mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-23 06:16:47 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c66d319d9c | ||
|
|
ae27165ffe | ||
|
|
32f1ca6f8b | ||
|
|
9ce2806710 | ||
|
|
3d4593d4d5 | ||
|
|
df5ae54ec7 | ||
|
|
fbee1b424d | ||
|
|
555017b525 | ||
|
|
1e170ee005 | ||
|
|
43501809b1 | ||
|
|
c0c67a101a | ||
|
|
1eb714e097 | ||
|
|
54a8e12856 | ||
|
|
6203f05ef9 | ||
|
|
703ad04067 | ||
|
|
778e96330d | ||
|
|
e3eb89fb12 | ||
|
|
166621bcb3 | ||
|
|
879a5a4cbe | ||
|
|
9faabfe995 | ||
|
|
6f23fa61ac | ||
|
|
30b6cf7821 | ||
|
|
6258011210 | ||
|
|
7557a46382 | ||
|
|
a0a91f358c | ||
|
|
0128286966 | ||
|
|
acd5e86e04 | ||
|
|
ab94b0a636 | ||
|
|
de6d696667 | ||
|
|
63946c4cfb | ||
|
|
475b603d15 | ||
|
|
096956cda9 | ||
|
|
3d3116d48b | ||
|
|
616360d751 | ||
|
|
7a5c30d297 | ||
|
|
9c5ab36a8b | ||
|
|
466656b167 | ||
|
|
5d6567cb02 | ||
|
|
c44c123ef5 | ||
|
|
4ecbf56e2b | ||
|
|
ed9a2c4b3f | ||
|
|
90751b9250 | ||
|
|
7d8011669d | ||
|
|
eb81062d85 | ||
|
|
8fbacc966e | ||
|
|
75801a12e3 | ||
|
|
9f1ce170e6 | ||
|
|
327c8826f4 | ||
|
|
fb0383d2bd | ||
|
|
28725d0d74 | ||
|
|
dac99b9374 | ||
|
|
1573477caf | ||
|
|
70a7513781 | ||
|
|
0277035496 | ||
|
|
33f462fdf6 | ||
|
|
639b9f346f | ||
|
|
447fee6f43 | ||
|
|
c9212a9a09 | ||
|
|
ea21fab379 | ||
|
|
4d090b64bd | ||
|
|
7e1e44e87a | ||
|
|
0a2a9dcd94 | ||
|
|
c9b4b66af2 | ||
|
|
7b6678b2a1 | ||
|
|
e79f62c5fa | ||
|
|
60046cc790 | ||
|
|
3fca25181a | ||
|
|
cbca31555d | ||
|
|
d5aa700b4b | ||
|
|
1db8319bce | ||
|
|
aa390f2a91 | ||
|
|
bd9e66d333 | ||
|
|
c34e318f8c | ||
|
|
4fc858b676 | ||
|
|
ac8b582b3d | ||
|
|
6f748d3d4f | ||
|
|
2854a524f0 | ||
|
|
985c34bfd9 | ||
|
|
63f97d8ec6 | ||
|
|
d2ac85e2c7 | ||
|
|
1b42f6232f | ||
|
|
4de141ab1d | ||
|
|
8ab2ec6f86 | ||
|
|
2fad8d4cff | ||
|
|
d94b0fe3c8 | ||
|
|
98956ef88f | ||
|
|
ac21d96bd8 | ||
|
|
c794aa02b8 | ||
|
|
dd564ab321 | ||
|
|
c0046e845e | ||
|
|
640767b748 | ||
|
|
d4eaede435 | ||
|
|
52bf4e613f | ||
|
|
9533a8dbdf | ||
|
|
774f78cd3e | ||
|
|
aca1dcf848 | ||
|
|
d24cd015b6 | ||
|
|
4d41525a91 | ||
|
|
b170a85fef | ||
|
|
90c6bc3a61 | ||
|
|
a4f6217a2f | ||
|
|
faff19af7b | ||
|
|
bc86bd4efa | ||
|
|
b4b18f3f30 | ||
|
|
1bcacf06d4 | ||
|
|
27178cedda | ||
|
|
6151d796a2 | ||
|
|
6ace9659e0 | ||
|
|
14942b4b43 | ||
|
|
9ede67ea63 | ||
|
|
cc74d2a6b0 | ||
|
|
ea779ac7dd | ||
|
|
693e9e5ad0 | ||
|
|
a1bc8ca6ca | ||
|
|
4e753a2c15 | ||
|
|
89314d4772 | ||
|
|
41f7ecacfc | ||
|
|
dd8da912f5 | ||
|
|
65ad911a2a | ||
|
|
37331d1c1b | ||
|
|
db2c842d15 | ||
|
|
c0e22a6533 | ||
|
|
bb87c368b8 | ||
|
|
76665b9404 | ||
|
|
a265ba2162 | ||
|
|
461a0fa2fb | ||
|
|
e51bbcb85a | ||
|
|
58ec62c895 | ||
|
|
843e1f9c44 | ||
|
|
45382144c3 | ||
|
|
e2f537628f | ||
|
|
91baa938e2 | ||
|
|
7fcaeacd65 | ||
|
|
2478d6f5d3 | ||
|
|
fbc1f6fb81 | ||
|
|
57aee7ca26 | ||
|
|
2fcfe9f2c3 | ||
|
|
2df2619029 | ||
|
|
9260d0d245 | ||
|
|
15becdaee4 | ||
|
|
80c9db3c88 | ||
|
|
c5d03d3a25 | ||
|
|
9e1570dc80 | ||
|
|
68da84e84a | ||
|
|
18ba73382e | ||
|
|
dabbfdb80a | ||
|
|
4eea8720a0 | ||
|
|
41239078a9 | ||
|
|
e375078dda | ||
|
|
da6b4c447f | ||
|
|
b72c0a0089 | ||
|
|
fbaf8f91bb | ||
|
|
329e943e4e | ||
|
|
31bd3e6056 | ||
|
|
15b94050ce | ||
|
|
c610699227 | ||
|
|
f0d2e20342 | ||
|
|
26a80005d6 | ||
|
|
5cf033a6ad | ||
|
|
e41ee7632d | ||
|
|
66a86433e7 | ||
|
|
2354a90e9f | ||
|
|
b7aaf51fbd | ||
|
|
5a885165b2 | ||
|
|
a748604418 | ||
|
|
e1a4e27173 | ||
|
|
2b06a293b6 | ||
|
|
472f98affe | ||
|
|
8114523be2 | ||
|
|
33ee1da817 | ||
|
|
301040a67a | ||
|
|
54b96ea7bd | ||
|
|
d0dfe2e7e7 | ||
|
|
fd8ceac170 | ||
|
|
a05d8c2823 | ||
|
|
626f418ab0 | ||
|
|
5792220dcb | ||
|
|
29d5d44f03 | ||
|
|
b2762f63a2 | ||
|
|
7d97f8a964 | ||
|
|
d3e63088d8 | ||
|
|
dddaa0ebcf | ||
|
|
ccbb1e5f5a | ||
|
|
3f1cd14f6c | ||
|
|
70abb2ce5c | ||
|
|
3f80bead1b | ||
|
|
93bb4283b8 | ||
|
|
5b5b31286b | ||
|
|
c5bde6560c | ||
|
|
cb4eb6236c | ||
|
|
d5e9e13555 | ||
|
|
3595b6d186 | ||
|
|
210010a390 | ||
|
|
99b3cc4464 | ||
|
|
9b6b081e38 | ||
|
|
b54ee3b1cd | ||
|
|
9fc4e1eddd | ||
|
|
73cca6ec39 | ||
|
|
58c2e12507 | ||
|
|
6dd80611a1 | ||
|
|
c2132039d2 | ||
|
|
d8d07eb129 | ||
|
|
f9768cd579 | ||
|
|
b6a15b2f4d | ||
|
|
5eca5d9948 | ||
|
|
f4a4ee00d0 | ||
|
|
cd94019733 | ||
|
|
d7fb47268f | ||
|
|
b4b5ac9944 | ||
|
|
df0b81d94d | ||
|
|
067d09720c | ||
|
|
870c35eece | ||
|
|
a82c178fd9 | ||
|
|
809bd18e66 | ||
|
|
4f0ffa2258 | ||
|
|
f45b17973c | ||
|
|
0bbea355c2 | ||
|
|
2be3507422 | ||
|
|
d6c946f390 | ||
|
|
96b6eb6b30 | ||
|
|
9cef973d9b | ||
|
|
88722a2831 | ||
|
|
d6b5c67313 | ||
|
|
4fed9d6532 | ||
|
|
28e0616543 | ||
|
|
6173e6b78a | ||
|
|
b5018cd994 | ||
|
|
f19a7c617d | ||
|
|
53d8cdd9f8 | ||
|
|
4bac5c06ba | ||
|
|
91a755d0e8 | ||
|
|
8cae7a4d44 | ||
|
|
11d1c45e45 | ||
|
|
5454a15b94 | ||
|
|
3ad0ec77ce | ||
|
|
3966e852ac | ||
|
|
83bfa9345f | ||
|
|
7d1d3847d8 | ||
|
|
a91c4f66ce | ||
|
|
ca2486ea61 | ||
|
|
24a2487c18 | ||
|
|
d68153dea3 | ||
|
|
89329fc0cc | ||
|
|
cba5a22714 | ||
|
|
1ce50993f0 | ||
|
|
2c0c934ad5 | ||
|
|
b6db8b63ec | ||
|
|
f1ab9e63fa | ||
|
|
12c574d5c9 | ||
|
|
af6f0c800f | ||
|
|
48f65cef40 | ||
|
|
b5a1d116fa | ||
|
|
b9339d3c60 | ||
|
|
0838dd24a4 | ||
|
|
9537fd7f0b | ||
|
|
95876feb46 | ||
|
|
19d817503d | ||
|
|
b6b364a09d | ||
|
|
f704d4d3ff | ||
|
|
450b9ab85c | ||
|
|
a1774bd3bd | ||
|
|
5aa69516bb | ||
|
|
c594dcec52 | ||
|
|
8126384726 | ||
|
|
96e6a9b02f | ||
|
|
d44ff4fd91 | ||
|
|
9a4ee873e1 | ||
|
|
597ed1681a | ||
|
|
bcd49b94dd | ||
|
|
422754f36f | ||
|
|
bfad382fd1 | ||
|
|
8941a594ee | ||
|
|
6bd8ab46d5 | ||
|
|
57f2ad6d15 | ||
|
|
33efeca0da | ||
|
|
be1888ed5f | ||
|
|
6ede18d41c | ||
|
|
d63e994ea5 | ||
|
|
700887d657 | ||
|
|
42674be38b | ||
|
|
fde7cd8f10 | ||
|
|
7ce713356e | ||
|
|
6511fc610b | ||
|
|
8dd4f77f3f | ||
|
|
004bfad348 | ||
|
|
ff90a5735d | ||
|
|
e6c0629626 | ||
|
|
01efffedfc | ||
|
|
74c219f171 | ||
|
|
bf10c5762a | ||
|
|
ca9abaf0c5 | ||
|
|
cfab250671 | ||
|
|
b1c0f7306d | ||
|
|
a156d8b8ce | ||
|
|
a7b7781fe9 | ||
|
|
21fe6afe8d | ||
|
|
48da46986b | ||
|
|
8d6239301f | ||
|
|
2e6807493f | ||
|
|
94cef20e49 | ||
|
|
c787a36af2 | ||
|
|
da0c4c7565 | ||
|
|
9c28f085d8 | ||
|
|
e9af0c7485 | ||
|
|
be54bfdc21 | ||
|
|
c6a6f4bc79 | ||
|
|
88ae1b7b3c | ||
|
|
f5d3b78653 | ||
|
|
68f1316eba | ||
|
|
e70e04d6e8 | ||
|
|
a3eb6868ea | ||
|
|
186759c95e | ||
|
|
8667b9a35d | ||
|
|
00defb0265 | ||
|
|
822a085d97 | ||
|
|
f23aec7f14 | ||
|
|
fb457128bf | ||
|
|
d126a414bd | ||
|
|
844fe3b9bc | ||
|
|
271855377f | ||
|
|
84020b16e3 | ||
|
|
c6035ab06e | ||
|
|
d94a40ecd9 | ||
|
|
c3be17ccae | ||
|
|
10dc978778 | ||
|
|
7f8f0eb65a | ||
|
|
c7107dc973 | ||
|
|
74eb544962 | ||
|
|
0696e3d558 | ||
|
|
714ca3542d | ||
|
|
7e27217dac | ||
|
|
4a7e14786c | ||
|
|
1ddb736f4c | ||
|
|
9ef49379f4 | ||
|
|
96213fe0ac | ||
|
|
d482da4803 | ||
|
|
4502da608d | ||
|
|
0976fd393b | ||
|
|
5882c6a481 | ||
|
|
52ea13819a | ||
|
|
048d044fdc | ||
|
|
9dda15a186 | ||
|
|
b094bbdcf4 | ||
|
|
eb708c1540 | ||
|
|
47a3b1f744 | ||
|
|
76b5d7e9e1 | ||
|
|
0071c9b0aa | ||
|
|
0ab42597d9 | ||
|
|
95ccc1e904 | ||
|
|
ea44866b2f | ||
|
|
6d4c6b56f6 | ||
|
|
f03ec88c2a | ||
|
|
e630ecdb0d | ||
|
|
eb27dc8db3 | ||
|
|
5cf7355c91 | ||
|
|
84bf0cee59 | ||
|
|
a18662ed13 | ||
|
|
3275d1f252 | ||
|
|
b14a0b885a | ||
|
|
e95a902b3d | ||
|
|
6733f7625b | ||
|
|
f7f61a8696 | ||
|
|
e1a6bb10de | ||
|
|
07bee5ca72 | ||
|
|
fa97ba0d9a | ||
|
|
bc95b02854 | ||
|
|
1893e7c8e5 | ||
|
|
0c04e2976b | ||
|
|
ac4fbb3e41 | ||
|
|
c98c24b9ff | ||
|
|
284c6fd85d | ||
|
|
3c8551ce90 | ||
|
|
65159a2733 | ||
|
|
007d702223 | ||
|
|
362b2aa604 | ||
|
|
de252965ac | ||
|
|
7349a6beaf | ||
|
|
828ca0ef9d | ||
|
|
f5049c2f14 | ||
|
|
f77c7f3d18 | ||
|
|
f75fb3cd95 | ||
|
|
8b9c26598a | ||
|
|
53600d3361 | ||
|
|
0dc5e5e29d | ||
|
|
eae9153b40 | ||
|
|
3d646aa92c | ||
|
|
b7c2bd4f72 | ||
|
|
b0a489fb7f | ||
|
|
01b9d5e023 | ||
|
|
6fa9415482 | ||
|
|
c159ff3134 | ||
|
|
efa5338e3b | ||
|
|
6dcf880482 | ||
|
|
b5fbb82ba1 | ||
|
|
ba8465abd2 | ||
|
|
0964dd99c5 | ||
|
|
a6a78f5776 | ||
|
|
23f73390a4 | ||
|
|
d55a890fdd | ||
|
|
84de8f2b93 | ||
|
|
08dac488c1 | ||
|
|
f2cff31b6e | ||
|
|
7c3f5c9fae | ||
|
|
aa16e82102 | ||
|
|
ddd3566d50 | ||
|
|
ec82af0c74 | ||
|
|
78bb3d6f09 | ||
|
|
54dab22042 | ||
|
|
9756cb6382 | ||
|
|
9fa0f95003 | ||
|
|
a624021a2e | ||
|
|
928df5caf7 | ||
|
|
5796524f06 | ||
|
|
b761a105b3 | ||
|
|
364ffc9024 | ||
|
|
712080f7e0 | ||
|
|
b906f4c0a1 | ||
|
|
d48bb4d744 | ||
|
|
d67ad166cd | ||
|
|
4e286ea86b | ||
|
|
a9be4e009f | ||
|
|
2f05d4b227 | ||
|
|
0b68639f7d | ||
|
|
5f09e01a44 | ||
|
|
6a98764b3b | ||
|
|
853c1f4387 | ||
|
|
b99c5aa394 | ||
|
|
349be0f169 | ||
|
|
4f28f6a770 | ||
|
|
fcf64c0c38 | ||
|
|
da8d59757e | ||
|
|
a02cfe0f1b | ||
|
|
f3255121a2 | ||
|
|
608555ce7e | ||
|
|
ec8b6e126e | ||
|
|
a697157257 | ||
|
|
ec070ee65b | ||
|
|
02f5ccd5d9 | ||
|
|
361d4f2147 | ||
|
|
c09a148cd9 | ||
|
|
b274dada85 | ||
|
|
c6a937e2e7 | ||
|
|
5840368f2d | ||
|
|
dee52dd2d0 | ||
|
|
a0e3b3386d | ||
|
|
6535b48c1c | ||
|
|
4d3611c5f1 | ||
|
|
77c4c88a4c | ||
|
|
4291866b9f | ||
|
|
8aef782411 | ||
|
|
0aa033ddf3 | ||
|
|
edba542c7a | ||
|
|
0e5289b022 | ||
|
|
6be3be0f16 | ||
|
|
03d188fc52 | ||
|
|
6e1e658922 | ||
|
|
a87575a76e | ||
|
|
336624c7b9 | ||
|
|
71660fbaa5 | ||
|
|
dd79885f6d | ||
|
|
51ffeb7c06 | ||
|
|
912749342c | ||
|
|
4bb91c4f98 | ||
|
|
400580179f | ||
|
|
c9d6b5431d | ||
|
|
51db00fb44 | ||
|
|
e20acfc9f9 | ||
|
|
a3fe753826 | ||
|
|
03aebd7525 | ||
|
|
fd5c0cfa28 | ||
|
|
357a0ff23e | ||
|
|
1a22f37d92 | ||
|
|
a5890b914f | ||
|
|
b397b10104 | ||
|
|
5de8e0555c | ||
|
|
91b01cd67e | ||
|
|
9c6b17c887 | ||
|
|
000d187c94 | ||
|
|
989e9d4d94 | ||
|
|
40ef704cc3 | ||
|
|
7c9fe0c173 | ||
|
|
dddbeb957a | ||
|
|
fd0cb30a4d | ||
|
|
125c631091 | ||
|
|
443dc7853f | ||
|
|
a5400d7212 | ||
|
|
da09d4c6e6 | ||
|
|
ace6b0a767 | ||
|
|
7d494fd3d5 | ||
|
|
cd1524e6ca | ||
|
|
a0526cdd32 | ||
|
|
4dd5f97a96 | ||
|
|
1ca6fe5519 | ||
|
|
6b2c604124 | ||
|
|
e42775ea7f | ||
|
|
a8c4729cf5 | ||
|
|
c200c0c20e | ||
|
|
4b174fd996 | ||
|
|
dbf5509f4f | ||
|
|
ec4f8c80d5 | ||
|
|
c8319bcc02 | ||
|
|
7bf480be9a | ||
|
|
2d3e85d941 | ||
|
|
ab6c8cb4b8 | ||
|
|
33c7c47f73 | ||
|
|
64d7b1cee5 | ||
|
|
0cebef872a | ||
|
|
65f835f3eb | ||
|
|
8309c1f673 | ||
|
|
e85347bf8b | ||
|
|
86a4512848 | ||
|
|
82831ea9a5 | ||
|
|
98c145c3b6 | ||
|
|
a50fe36ef8 | ||
|
|
7cbd710f7b | ||
|
|
39ef2b7605 | ||
|
|
da4901bb17 | ||
|
|
f28f5e01e5 | ||
|
|
e00aedd99b | ||
|
|
9d1a81ce2c | ||
|
|
cfed3933fa | ||
|
|
659624c71f | ||
|
|
6e0b77a8da | ||
|
|
54bb59ae99 | ||
|
|
cac941b272 | ||
|
|
0be48388c2 | ||
|
|
d8970752b6 | ||
|
|
08f0f5a1f7 | ||
|
|
f8162be8c3 | ||
|
|
f50074de50 | ||
|
|
9866fd01bd | ||
|
|
d1ad10c90f | ||
|
|
0045d7d1bf | ||
|
|
4a74ae1795 | ||
|
|
4d0b840c26 | ||
|
|
0c7335a77d | ||
|
|
7e8a538c20 | ||
|
|
aca5afa95c | ||
|
|
7793a49854 | ||
|
|
6bfbcbdcf7 | ||
|
|
bf72f39fe9 | ||
|
|
fa23dafdae | ||
|
|
9572ddd7e8 | ||
|
|
1ff36dc892 | ||
|
|
bf9a8f5021 | ||
|
|
0c4bea473c | ||
|
|
649428962e | ||
|
|
cc5ddc0b6b | ||
|
|
b624b6002e | ||
|
|
af35736e04 | ||
|
|
58b5b583a7 | ||
|
|
9e385e6947 | ||
|
|
560c003e03 | ||
|
|
1d045eea0d | ||
|
|
7a0e73ef3d | ||
|
|
5d20dd63ec | ||
|
|
ab9a853d52 | ||
|
|
82c0a2ebac | ||
|
|
75e78e86d3 | ||
|
|
a75326e2e0 | ||
|
|
b3e430c751 | ||
|
|
faa3a62259 | ||
|
|
438605fad5 | ||
|
|
9505b586bf | ||
|
|
40e7bc2450 | ||
|
|
a9aaca1ffa | ||
|
|
ce61d12f60 | ||
|
|
874bab10e4 | ||
|
|
21194c909a | ||
|
|
96a50d635d | ||
|
|
8c9e0bafa9 | ||
|
|
b3bb79992a | ||
|
|
4e92501864 | ||
|
|
d83fb10774 | ||
|
|
5a6cca33a0 | ||
|
|
b2f6953259 | ||
|
|
b1f1f74920 | ||
|
|
2adea8de48 | ||
|
|
859318becd | ||
|
|
55fb219503 | ||
|
|
b01316ce12 | ||
|
|
1921e19635 | ||
|
|
990df42407 | ||
|
|
924b4e0062 | ||
|
|
0e43dfb285 | ||
|
|
46621d3c83 | ||
|
|
fa95f7ff3b | ||
|
|
e45546e6f3 | ||
|
|
d79d48ffeb | ||
|
|
467ecf5b33 | ||
|
|
9f3e64e11a | ||
|
|
56954356db | ||
|
|
6466d02eda | ||
|
|
7a149a6943 | ||
|
|
acf3a4ec16 | ||
|
|
5c4b87675f | ||
|
|
83d3a60d5c | ||
|
|
3e4eb17b15 | ||
|
|
1075b28f26 | ||
|
|
943527c526 | ||
|
|
d350620315 | ||
|
|
6fc556cefc | ||
|
|
73283768a5 | ||
|
|
ce7d64f427 | ||
|
|
84b70be7ee | ||
|
|
3924c51097 | ||
|
|
4bb1bd4315 | ||
|
|
0164ad78be | ||
|
|
36e1eab3f4 | ||
|
|
177fa4062b | ||
|
|
821c68696d | ||
|
|
a3217db7b2 | ||
|
|
42dab181cd | ||
|
|
98d71de50f | ||
|
|
c596e1cda1 | ||
|
|
706f2ffc89 | ||
|
|
a7054a91e5 | ||
|
|
ad44b411fb | ||
|
|
f7fa2f1f4d | ||
|
|
2fcab15704 | ||
|
|
cfbad49d33 | ||
|
|
9dbcb32808 | ||
|
|
1b69bb5d2f | ||
|
|
2326672b3a | ||
|
|
393a76d57a | ||
|
|
4b3b41cd79 | ||
|
|
eab5793dda | ||
|
|
6cf2ddf541 | ||
|
|
ad6bbe539f | ||
|
|
f12864f69e | ||
|
|
b61c89c104 | ||
|
|
0def3c9983 | ||
|
|
9e5dc17c1d | ||
|
|
36d36d99f3 | ||
|
|
de985ac3fd | ||
|
|
245905aeda | ||
|
|
ac6caaf29e | ||
|
|
3734b5e7f1 | ||
|
|
789efb9832 | ||
|
|
c7bc35ad75 | ||
|
|
5071ce8575 | ||
|
|
64ff74df37 | ||
|
|
181066311b | ||
|
|
20ad433f8c | ||
|
|
494b5ff1ee | ||
|
|
cbd501b865 | ||
|
|
41384a0e41 | ||
|
|
3854e12024 | ||
|
|
ff55af1e9e | ||
|
|
bdf643ddb1 | ||
|
|
d46465845c | ||
|
|
dd75595082 | ||
|
|
a73cfbc2b5 | ||
|
|
21c844363a | ||
|
|
3109906514 | ||
|
|
606eb2b3cd | ||
|
|
e99059e001 | ||
|
|
cefbb635c1 | ||
|
|
b2b8b89cd8 | ||
|
|
92760f2c5f | ||
|
|
176be94be9 | ||
|
|
9fda809fa6 | ||
|
|
3c8d598eed | ||
|
|
f2068e83d4 | ||
|
|
5976e7078c | ||
|
|
da9a84ed84 | ||
|
|
03b635604a | ||
|
|
167f94bdbf | ||
|
|
4507351d48 | ||
|
|
0253f92e7e | ||
|
|
432d4efc9b | ||
|
|
749c3eb5a7 | ||
|
|
e933b56507 | ||
|
|
0c5ce9dfec | ||
|
|
acde444439 | ||
|
|
298a352cbd | ||
|
|
356552faad | ||
|
|
5e1e79b3c4 | ||
|
|
2996d2eb19 | ||
|
|
16023cbbd6 | ||
|
|
77927972e5 | ||
|
|
d762a320dc | ||
|
|
a9e54e7553 | ||
|
|
8b8a3d83e0 | ||
|
|
3fbbd4080a | ||
|
|
e79a371f76 | ||
|
|
c507379f09 | ||
|
|
47031767fa | ||
|
|
af5e68448c | ||
|
|
c1c88f87c6 | ||
|
|
a9b5c9c037 | ||
|
|
03b428b6cb | ||
|
|
271a835305 | ||
|
|
a3c3019a04 | ||
|
|
f063bf833f | ||
|
|
2002c03cef | ||
|
|
b8be5e80cd | ||
|
|
c29e11ed36 | ||
|
|
e35ed6e91c | ||
|
|
794ce68a6c | ||
|
|
31aa85ce7d | ||
|
|
15c2b0317d | ||
|
|
820d8b9edc | ||
|
|
a3a0f5f432 | ||
|
|
a98b5023a8 | ||
|
|
645c8913f1 | ||
|
|
066284d5c2 | ||
|
|
2802601c44 | ||
|
|
962a77c6b8 | ||
|
|
ca801574e3 | ||
|
|
606c1d38bb | ||
|
|
147ee59940 | ||
|
|
2e3fc89831 | ||
|
|
82bccd335d | ||
|
|
bfc05e2d71 | ||
|
|
c8135595be | ||
|
|
d5658d4180 | ||
|
|
8356e6a51f | ||
|
|
fbf55b9df4 | ||
|
|
176e6d09ca | ||
|
|
b72d1c297d | ||
|
|
f5b9c26735 | ||
|
|
d8141252e9 | ||
|
|
ed86dee65d | ||
|
|
f535cd3077 | ||
|
|
537757a7b9 | ||
|
|
4fb354776e | ||
|
|
1583b1e84a | ||
|
|
45ff04ecb6 | ||
|
|
ef08e43cf2 | ||
|
|
e17f7f5146 | ||
|
|
8654412844 | ||
|
|
140533db50 | ||
|
|
00cacae2a3 | ||
|
|
7e0b0d7328 | ||
|
|
1be77d68ce | ||
|
|
c5a5a11b7f | ||
|
|
becc7cb56a | ||
|
|
629a02cccf | ||
|
|
f28b97ebfd | ||
|
|
c5234e95cd | ||
|
|
b825f8d2b2 | ||
|
|
eb08253ed0 | ||
|
|
7b79fd98e5 | ||
|
|
6d5fcf5853 | ||
|
|
bc284ee6d8 | ||
|
|
260b4166c1 | ||
|
|
b59cc5ff6d | ||
|
|
5c89fb71ae | ||
|
|
3baa8c0445 | ||
|
|
ce589da58a | ||
|
|
0bb9359c05 | ||
|
|
54140dadcf | ||
|
|
60c22aefeb | ||
|
|
69a2331791 | ||
|
|
29cfd8ccfe | ||
|
|
bf67f386de | ||
|
|
a2f07011c1 | ||
|
|
0bd6cf7b6f | ||
|
|
cd8e491028 | ||
|
|
e773ccfe49 | ||
|
|
83de770387 | ||
|
|
b3a8098506 | ||
|
|
05407f488f | ||
|
|
85d53ebbf4 | ||
|
|
e4139f4819 | ||
|
|
45c935af45 | ||
|
|
cfbfd9ec1d | ||
|
|
ae209a144f | ||
|
|
64837efac5 | ||
|
|
8d73df2b04 | ||
|
|
59117c2e42 | ||
|
|
e23dd57c9d | ||
|
|
0e20be774e | ||
|
|
c3ae00ae49 | ||
|
|
a7328ecce1 | ||
|
|
15a952a143 | ||
|
|
3154f07817 | ||
|
|
4e700bffb8 | ||
|
|
7b2d4c9ef6 | ||
|
|
da828a218f | ||
|
|
13ef84bc35 | ||
|
|
c7b36322f6 | ||
|
|
8cc89a3a1f | ||
|
|
b8c5aff0cb | ||
|
|
fb0c387b12 | ||
|
|
1628045b55 | ||
|
|
608e5a4dbb | ||
|
|
30787fd49e | ||
|
|
1e231c3338 | ||
|
|
370549a19a | ||
|
|
39c39f0162 | ||
|
|
bcaa122fb9 | ||
|
|
96403de903 | ||
|
|
ab5cad18de | ||
|
|
b1c548a981 | ||
|
|
039769dbaf | ||
|
|
a76d6dc352 | ||
|
|
7eab75ded1 | ||
|
|
ef9c7c4a30 | ||
|
|
4c54e070ed | ||
|
|
80c609853a | ||
|
|
eeabc7234c | ||
|
|
79b740284a | ||
|
|
ab7b353ace | ||
|
|
3b82a15521 | ||
|
|
97d972ebb3 | ||
|
|
5f5081827d | ||
|
|
6b7b4e700a | ||
|
|
baac893d22 | ||
|
|
d680e594ed | ||
|
|
42adc49e57 | ||
|
|
4a2168b352 | ||
|
|
44d4660fe8 | ||
|
|
45d4117c02 | ||
|
|
ae837a6347 | ||
|
|
426fc18d10 | ||
|
|
2531ed89cd | ||
|
|
566d5c9a93 | ||
|
|
a033c331b6 | ||
|
|
066b534307 | ||
|
|
64cabd8074 | ||
|
|
a0db52c69f | ||
|
|
7bbedd1b55 | ||
|
|
0340256b4c | ||
|
|
c4bd8b1463 | ||
|
|
a2d465804f | ||
|
|
3c5d32637c | ||
|
|
c93cb71162 | ||
|
|
c3960f8e6a | ||
|
|
96d04bb5a0 | ||
|
|
1f1bfd0eab | ||
|
|
8cdf51f913 | ||
|
|
1f3eedcfd7 | ||
|
|
541f269c20 | ||
|
|
68a7ddefd3 | ||
|
|
3961c68928 | ||
|
|
832b795826 | ||
|
|
7a6be47603 | ||
|
|
81536481cc | ||
|
|
6e703c5744 | ||
|
|
82e8e51736 | ||
|
|
905529081d | ||
|
|
4159c98c58 | ||
|
|
e40efec4bd | ||
|
|
e418625457 | ||
|
|
4b82d26f5e | ||
|
|
63a02d1c0a | ||
|
|
bf42772995 | ||
|
|
b75221e9bf | ||
|
|
1e9a54d134 | ||
|
|
ff0b59ff6b | ||
|
|
b3a5a0e5ab | ||
|
|
e002b1c1c4 | ||
|
|
7009dc8d9b | ||
|
|
e28b7f06c5 | ||
|
|
b6e1d63cb0 | ||
|
|
5a279dbdc8 | ||
|
|
3ad3a2ab57 | ||
|
|
5361efe8ed | ||
|
|
2f2657b765 | ||
|
|
19a7f3faeb | ||
|
|
f480943649 | ||
|
|
f3019ff5a0 | ||
|
|
33ee5c26b0 | ||
|
|
1e9184f0f9 | ||
|
|
19251f7a79 | ||
|
|
b79da2c4d6 | ||
|
|
e68ba4c73a | ||
|
|
39ffe91230 | ||
|
|
150fc6f3ee | ||
|
|
a7411eb00d | ||
|
|
660fd7c1d4 | ||
|
|
53772db66d | ||
|
|
93dd08bdf5 | ||
|
|
176d707e0a | ||
|
|
34dade1b65 | ||
|
|
4e815f8565 | ||
|
|
e69a3ed934 | ||
|
|
77d63aba74 | ||
|
|
de8c725890 | ||
|
|
d4b2958e50 | ||
|
|
8669b372e0 | ||
|
|
61991e6367 | ||
|
|
bdcb813727 | ||
|
|
e6f1510a40 | ||
|
|
224af78463 | ||
|
|
983bf5cbab | ||
|
|
96bcf6eac4 | ||
|
|
0872ad34cf | ||
|
|
5aee3b866a | ||
|
|
3ce86f5664 | ||
|
|
23e5394fb4 | ||
|
|
be7ac7a2ca | ||
|
|
a616cfd0c2 | ||
|
|
e85b669307 | ||
|
|
bc6dfeb4a9 | ||
|
|
bf96986c38 | ||
|
|
26cfbb2b7b | ||
|
|
35fc2a609d | ||
|
|
f05b13c630 | ||
|
|
4d8954be4c | ||
|
|
1d0a9871c2 | ||
|
|
2292751fc3 | ||
|
|
a6524e47e2 | ||
|
|
02b9aa9163 | ||
|
|
754adce4a4 | ||
|
|
f3fdf70b56 | ||
|
|
38db6fde0c | ||
|
|
4f804577f9 | ||
|
|
44a182d92c | ||
|
|
91d65d0e4e | ||
|
|
a88f030b52 | ||
|
|
4537de8120 | ||
|
|
100bdedac3 | ||
|
|
914ad85e63 | ||
|
|
b3c2ad0a65 | ||
|
|
2e12635494 | ||
|
|
4325b787c0 | ||
|
|
4e3c702cc7 | ||
|
|
213cb1b08a | ||
|
|
b7569f4d70 | ||
|
|
e328cf9fed | ||
|
|
78af3dbdc0 | ||
|
|
372674b4c0 | ||
|
|
8d0f7e1594 | ||
|
|
558fea33fb | ||
|
|
de5930f7d8 | ||
|
|
e09a14aa44 | ||
|
|
d45c7c58df | ||
|
|
b5e0f46229 | ||
|
|
12229e4826 | ||
|
|
8f88525819 | ||
|
|
a225fe304d | ||
|
|
0f9eb13245 | ||
|
|
06437b7fba | ||
|
|
ba910c0fac | ||
|
|
28278d3c09 | ||
|
|
2bf7653ab9 | ||
|
|
cb39b3b65c | ||
|
|
3e3757bde7 | ||
|
|
8b4befd4fc | ||
|
|
972e9c866b | ||
|
|
f758010f01 | ||
|
|
8057faccc1 | ||
|
|
3f952a2fd2 | ||
|
|
eb71c70c99 | ||
|
|
2a44cf70b1 | ||
|
|
431b16639d | ||
|
|
014e68b62f | ||
|
|
31291f5d8a | ||
|
|
a52b34cb64 | ||
|
|
3ca55bf327 | ||
|
|
9bb2cee686 | ||
|
|
4f3bdd9f38 | ||
|
|
efe41c2435 | ||
|
|
f855cb19b8 | ||
|
|
861ed55879 | ||
|
|
35e0dcdd3d | ||
|
|
a72a8607e6 | ||
|
|
904747acf5 | ||
|
|
4d40a336c0 | ||
|
|
32e9c8049a | ||
|
|
bb24624979 | ||
|
|
506bc87e82 | ||
|
|
986885bd70 | ||
|
|
73c4893ef7 | ||
|
|
62c9f39297 | ||
|
|
8b5f62a5e5 | ||
|
|
aec5841c7f | ||
|
|
c997c090a1 | ||
|
|
0ab60cd3c3 | ||
|
|
ae23a8f6bf | ||
|
|
46e868d313 | ||
|
|
8dfa322b8b | ||
|
|
2f2f08b02f | ||
|
|
102fd24dd2 | ||
|
|
66cf3ec8fa | ||
|
|
57b0d9691e | ||
|
|
7c6f496765 | ||
|
|
67e72ce77e | ||
|
|
c97692d715 | ||
|
|
66f83f3b08 | ||
|
|
3765bdd3ac | ||
|
|
39bcdfb7b4 | ||
|
|
57cd770650 | ||
|
|
3194b0c53a | ||
|
|
9e8005f7b7 | ||
|
|
41ce198a1f | ||
|
|
05e30ed43b | ||
|
|
09cd582cc5 | ||
|
|
235781ce08 | ||
|
|
70aeb980d8 | ||
|
|
d0d6189874 | ||
|
|
8205d0fcc9 | ||
|
|
60d068a33e | ||
|
|
e1a4b457c2 | ||
|
|
86e18226eb | ||
|
|
7fa2975c24 | ||
|
|
d39190243b | ||
|
|
0550287658 | ||
|
|
82947a9343 | ||
|
|
b7fb806611 | ||
|
|
6a236061de | ||
|
|
898639d7bf | ||
|
|
6322400b83 | ||
|
|
9b7341889d | ||
|
|
0653f859bc | ||
|
|
48ff66cbce | ||
|
|
1b2a6f8bed | ||
|
|
c6cf665c4a | ||
|
|
19c84ff9a2 | ||
|
|
15398a8f58 | ||
|
|
9d2e22576e | ||
|
|
3ffb3c7011 | ||
|
|
cac4c8d5ce | ||
|
|
f40d006c26 | ||
|
|
e6c36597eb | ||
|
|
141808b787 | ||
|
|
003f103408 | ||
|
|
ce66498c88 | ||
|
|
bf30a0bc07 | ||
|
|
f8e6d782e1 | ||
|
|
7a8135c703 | ||
|
|
311e1ce9ee | ||
|
|
9bce21ddb7 | ||
|
|
c4e438d4ba | ||
|
|
a2da2d59df | ||
|
|
56a4236576 | ||
|
|
2443c655f2 | ||
|
|
ae1d5227de | ||
|
|
5769bbe15e | ||
|
|
6dbf7333c8 | ||
|
|
4352ce6753 | ||
|
|
29a50a52ca | ||
|
|
d25690cc8e | ||
|
|
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 | ||
|
|
d6701803d1 | ||
|
|
9e624ac833 | ||
|
|
0175c727ee | ||
|
|
90250baf0f | ||
|
|
cc22ae833a | ||
|
|
6c4b5cf2c2 | ||
|
|
88a2ca2168 | ||
|
|
41242735ed | ||
|
|
ab11943496 | ||
|
|
d9f0065f93 | ||
|
|
53dfdacce8 | ||
|
|
4e44515078 | ||
|
|
2b11f78d63 | ||
|
|
a4de0af79d | ||
|
|
145ac49233 | ||
|
|
6479319fea | ||
|
|
f224ed3a90 | ||
|
|
5f292e546d | ||
|
|
65020bc6de | ||
|
|
6adb50e860 | ||
|
|
1ea417dc30 | ||
|
|
a00924089d | ||
|
|
66716f5101 | ||
|
|
219df169a3 | ||
|
|
b712c3f5ca |
@@ -5,11 +5,16 @@ parse.cc.output
|
||||
syn-rules.cc
|
||||
syn-rules.cc.output
|
||||
lexor.cc
|
||||
iverilog-vpi
|
||||
ivl
|
||||
ivl.exp
|
||||
dep
|
||||
configure
|
||||
Makefile
|
||||
check
|
||||
check.cc
|
||||
config.status
|
||||
config.log
|
||||
config.cache
|
||||
config.h
|
||||
dosify
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: Attrib.cc,v 1.1 2000/12/04 17:37:03 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.cc,v 1.5 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Attrib.h"
|
||||
# include <assert.h>
|
||||
|
||||
@@ -34,14 +36,15 @@ Attrib::~Attrib()
|
||||
delete[] list_;
|
||||
}
|
||||
|
||||
void Attrib::set_attributes(const map<string,string>&attr)
|
||||
#if 0
|
||||
void Attrib::copy_attributes(const map<string,verinum>&attr)
|
||||
{
|
||||
assert(list_ == 0);
|
||||
|
||||
nlist_ = attr.size();
|
||||
list_ = new cell_[nlist_];
|
||||
|
||||
map<string,string>::const_iterator idx;
|
||||
map<string,verinum>::const_iterator idx;
|
||||
unsigned jdx;
|
||||
for (idx = attr.begin(), jdx = 0 ; idx != attr.end() ; idx ++, jdx++) {
|
||||
struct cell_*tmp = list_ + jdx;
|
||||
@@ -49,8 +52,9 @@ void Attrib::set_attributes(const map<string,string>&attr)
|
||||
tmp->val = (*idx).second;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
string Attrib::attribute(const string&key) const
|
||||
const verinum& Attrib::attribute(const string&key) const
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) {
|
||||
|
||||
@@ -58,10 +62,11 @@ string Attrib::attribute(const string&key) const
|
||||
return list_[idx].val;
|
||||
}
|
||||
|
||||
return "";
|
||||
static const verinum null;
|
||||
return null;
|
||||
}
|
||||
|
||||
void Attrib::attribute(const string&key, const string&value)
|
||||
void Attrib::attribute(const string&key, const verinum&value)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
@@ -90,7 +95,7 @@ bool Attrib::has_compat_attributes(const Attrib&that) const
|
||||
|
||||
for (idx = 0 ; idx < that.nlist_ ; idx += 1) {
|
||||
|
||||
string tmp = attribute(that.list_[idx].key);
|
||||
verinum tmp = attribute(that.list_[idx].key);
|
||||
if (tmp != that.list_[idx].val)
|
||||
return false;
|
||||
}
|
||||
@@ -98,18 +103,18 @@ bool Attrib::has_compat_attributes(const Attrib&that) const
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned Attrib::size() const
|
||||
unsigned Attrib::attr_cnt() const
|
||||
{
|
||||
return nlist_;
|
||||
}
|
||||
|
||||
string Attrib::key(unsigned idx) const
|
||||
const char* Attrib::attr_key(unsigned idx) const
|
||||
{
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].key;
|
||||
return list_[idx].key.c_str();
|
||||
}
|
||||
|
||||
string Attrib::value(unsigned idx) const
|
||||
const verinum& Attrib::attr_value(unsigned idx) const
|
||||
{
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].val;
|
||||
@@ -118,6 +123,28 @@ string Attrib::value(unsigned idx) const
|
||||
|
||||
/*
|
||||
* $Log: Attrib.cc,v $
|
||||
* Revision 1.5 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.4 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.3 2002/05/23 03:08:50 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/12/04 17:37:03 steve
|
||||
* Add Attrib class for holding NetObj attributes.
|
||||
*
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: Attrib.h,v 1.1 2000/12/04 17:37:03 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.h,v 1.4 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include <map>
|
||||
# include "verinum.h"
|
||||
|
||||
/*
|
||||
* This class keeps a map of key/value pairs. The map can be set from
|
||||
@@ -35,21 +35,21 @@ class Attrib {
|
||||
Attrib();
|
||||
~Attrib();
|
||||
|
||||
void set_attributes(const map<string,string>&attr);
|
||||
string attribute(const string&key) const;
|
||||
void attribute(const string&key, const string&value);
|
||||
const verinum&attribute(const string&key) const;
|
||||
void attribute(const string&key, const verinum&value);
|
||||
bool has_compat_attributes(const Attrib&that) const;
|
||||
|
||||
|
||||
/* Provide a means of iterating over the entries in the map. */
|
||||
unsigned size() const;
|
||||
string key(unsigned idx) const;
|
||||
string value(unsigned idx) const;
|
||||
unsigned attr_cnt() const;
|
||||
const char* attr_key(unsigned idx) const;
|
||||
const verinum& attr_value(unsigned idx) const;
|
||||
|
||||
|
||||
private:
|
||||
struct cell_ {
|
||||
string key;
|
||||
string val;
|
||||
string key;
|
||||
verinum val;
|
||||
};
|
||||
|
||||
unsigned nlist_;
|
||||
@@ -62,6 +62,24 @@ class Attrib {
|
||||
|
||||
/*
|
||||
* $Log: Attrib.h,v $
|
||||
* Revision 1.4 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.2 2002/05/23 03:08:50 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.1 2000/12/04 17:37:03 steve
|
||||
* Add Attrib class for holding NetObj attributes.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: HName.cc,v 1.4 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "HName.h"
|
||||
# include <iostream>
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
hname_t::hname_t()
|
||||
{
|
||||
item_ = 0;
|
||||
count_ = 0;
|
||||
}
|
||||
|
||||
hname_t::hname_t(const char*text)
|
||||
{
|
||||
item_ = strdup(text);
|
||||
count_ = 1;
|
||||
}
|
||||
|
||||
hname_t::hname_t(const hname_t&that)
|
||||
{
|
||||
count_ = that.count_;
|
||||
switch (count_) {
|
||||
case 0:
|
||||
item_ = 0;
|
||||
break;
|
||||
case 1:
|
||||
item_ = strdup(that.item_);
|
||||
break;
|
||||
default:
|
||||
array_ = new char*[count_];
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
array_[idx] = strdup(that.array_[idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hname_t::~hname_t()
|
||||
{
|
||||
switch (count_) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
free(item_);
|
||||
break;
|
||||
default:
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
free(array_[idx]);
|
||||
delete[]array_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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.4 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/01/05 04:36:06 steve
|
||||
* include malloc.h only when available.
|
||||
*
|
||||
* Revision 1.2 2001/12/18 04:52:45 steve
|
||||
* Include config.h for namespace declaration.
|
||||
*
|
||||
* Revision 1.1 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
#ifndef __HName_H
|
||||
#define __HName_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: HName.h,v 1.3 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 2
|
||||
using namespace std;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This class represents a Verilog hierarchical name. A hierarchical
|
||||
* name is an ordered list of simple names.
|
||||
*/
|
||||
|
||||
class hname_t {
|
||||
|
||||
public:
|
||||
hname_t ();
|
||||
explicit hname_t (const char*text);
|
||||
hname_t (const hname_t&that);
|
||||
~hname_t();
|
||||
|
||||
// This method adds a name to the end of the hierarchical
|
||||
// path. This becomes a new base name.
|
||||
void append(const char*text);
|
||||
|
||||
// This method adds a name to the *front* of the hierarchical
|
||||
// path. The base name remains the same, unless this is the
|
||||
// only component.
|
||||
void prepend(const char*text);
|
||||
|
||||
// This method removes the tail name from the hierarchy, and
|
||||
// returns a pointer to that tail name. That tail name now
|
||||
// must be removed by the caller.
|
||||
char* remove_tail_name();
|
||||
|
||||
// Return the given component in the hierarchical name. If the
|
||||
// idx is too large, return 0.
|
||||
const char*peek_name(unsigned idx) const;
|
||||
const char*peek_tail_name() const;
|
||||
|
||||
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.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/06/14 03:25:51 steve
|
||||
* Compiler portability.
|
||||
*
|
||||
* Revision 1.1 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+11
-2
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: LineInfo.cc,v 1.1 2000/11/30 17:31:42 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: LineInfo.cc,v 1.3 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include <cstdio>
|
||||
|
||||
@@ -42,6 +44,13 @@ void LineInfo::set_line(const LineInfo&that)
|
||||
|
||||
/*
|
||||
* $Log: LineInfo.cc,v $
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/11/30 17:31:42 steve
|
||||
* Change LineInfo to store const C strings.
|
||||
*
|
||||
|
||||
+5
-2
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: LineInfo.h,v 1.5 2000/11/30 17:31:42 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: LineInfo.h,v 1.6 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
@@ -52,6 +52,9 @@ class LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: LineInfo.h,v $
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.5 2000/11/30 17:31:42 steve
|
||||
* Change LineInfo to store const C strings.
|
||||
*
|
||||
|
||||
+155
-40
@@ -16,25 +16,33 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.89 2001/01/09 03:11:27 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.134 2002/09/16 00:30:33 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.3
|
||||
# This version string is only used in the version message printed
|
||||
# by the compiler. It reflects the assigned version number for the
|
||||
# product as a whole. Most components also print the CVS Name: token
|
||||
# in order to get a more automatic version stamp as well.
|
||||
VERSION = 0.6
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
|
||||
SUBDIRS = @subdirs@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = $(prefix)/include
|
||||
mandir = @mandir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
rdynamic=@rdynamic@
|
||||
strip_dynamic=@strip_dynamic@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
@@ -43,9 +51,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
STRIP = @STRIP@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
# The TARGETS variable lists the target modules that can be build and
|
||||
@@ -56,80 +67,117 @@ ifeq ('@HAVE_IPAL@','yes')
|
||||
TARGETS += tgt-pal
|
||||
endif
|
||||
|
||||
|
||||
all: ivl@EXEEXT@
|
||||
cd vvm ; $(MAKE) all
|
||||
all: ivl@EXEEXT@ libvpi.a
|
||||
for dir in $(SUBDIRS) ; do (cd $$dir ; $(MAKE) all); done
|
||||
cd vpi ; $(MAKE) all
|
||||
cd ivlpp ; $(MAKE) all
|
||||
cd driver ; $(MAKE) all
|
||||
cd driver ; $(MAKE) VERSION=$(VERSION) all
|
||||
cd tgt-verilog ; $(MAKE) all
|
||||
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
|
||||
|
||||
else
|
||||
all: iverilog-vpi
|
||||
endif
|
||||
|
||||
# This rule rules the compiler in the trivial hello.vl program to make
|
||||
# sure the basics were compiled properly.
|
||||
check: all
|
||||
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)
|
||||
./check | grep 'Hello, World'
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
|
||||
driver/iverilog -Ccheck.conf -ocheck.vvp -tvvp-check -B./ivlpp $(srcdir)/examples/hello.vl
|
||||
vvp/vvp -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
|
||||
clean:
|
||||
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a
|
||||
cd vvm ; $(MAKE) clean
|
||||
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a libvpi.a iverilog-vpi
|
||||
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
|
||||
rm -f vvm/Makefile
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) distclean); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) distclean); done
|
||||
rm -f vpi/Makefile
|
||||
rm -f ivlpp/Makefile
|
||||
rm -f driver/Makefile
|
||||
rm -f config.status config.cache config.log
|
||||
rm -f Makefile
|
||||
rm -f tgt-pal/Makefile tgt-stub/Makefile tgt-verilog/Makefile
|
||||
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-vvm.o t-xnf.o
|
||||
FF = nodangle.o synth.o syn-rules.o xnfio.o
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-xnf.o
|
||||
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o xnfio.o
|
||||
|
||||
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
|
||||
O = main.o async.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
|
||||
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
|
||||
elab_sig.o emit.o eval.o \
|
||||
elab_sig.o emit.o eval.o eval_attrib.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 \
|
||||
net_design.o net_event.o net_force.o net_link.o net_modulo.o net_proc.o \
|
||||
net_scope.o net_udp.o pad_to_width.o \
|
||||
load_module.o netlist.o netmisc.o net_assign.o \
|
||||
net_design.o net_event.o net_expr.o net_force.o net_func.o \
|
||||
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
|
||||
net_proc.o net_scope.o net_udp.o pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_dump.o \
|
||||
set_width.o \
|
||||
verinum.o verireal.o target.o targets.o util.o \
|
||||
Attrib.o LineInfo.o Module.o PDelays.o PEvent.o \
|
||||
set_width.o sync.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 \
|
||||
PTask.o PFunction.o PWire.o Statement.o StringHeap.o \
|
||||
$(FF) $(TT)
|
||||
|
||||
Makefile: Makefile.in config.status
|
||||
Makefile: Makefile.in config.h.in config.status
|
||||
./config.status
|
||||
|
||||
|
||||
ifeq (@CYGWIN@,yes)
|
||||
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)
|
||||
endif
|
||||
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
|
||||
else
|
||||
iverilog-vpi: iverilog-vpi.sh
|
||||
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
||||
-e 's;@INCLUDEDIR@;@includedir@;' -e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||
chmod +x $@
|
||||
endif
|
||||
|
||||
%.o: %.cc
|
||||
@[ -d dep ] || mkdir dep
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
$(CXX) @ident_support@ $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
|
||||
@@ -138,31 +186,57 @@ 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
|
||||
$(YACC) --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
|
||||
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
|
||||
|
||||
lexor.cc: $(srcdir)/lexor.lex
|
||||
flex -PVL -s -olexor.cc $(srcdir)/lexor.lex
|
||||
$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex
|
||||
|
||||
lexor_keyword.o: lexor_keyword.cc
|
||||
|
||||
lexor_keyword.cc: lexor_keyword.gperf
|
||||
gperf -o -i 7 -C -k 1-3,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
|
||||
|
||||
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
|
||||
man -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
|
||||
|
||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h
|
||||
cd vvm ; $(MAKE) install
|
||||
iverilog-vpi.pdf: iverilog-vpi.ps
|
||||
ps2pdf iverilog-vpi.ps iverilog-vpi.pdf
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf
|
||||
INSTALL_DOCDIR =
|
||||
all: iverilog-vpi.pdf
|
||||
else
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
endif
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/QUICK_START.txt
|
||||
else
|
||||
WIN32_INSTALL = $(bindir)/iverilog-vpi
|
||||
endif
|
||||
|
||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(libdir)/libvpi.a $(WIN32_INSTALL) $(INSTALL_DOC)
|
||||
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
|
||||
|
||||
$(bindir)/iverilog-vpi: ./iverilog-vpi
|
||||
$(INSTALL_PROGRAM) ./iverilog-vpi $(bindir)/iverilog-vpi
|
||||
|
||||
$(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 +244,60 @@ $(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
|
||||
|
||||
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/acc_user.h $(includedir)/acc_user.h
|
||||
|
||||
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
|
||||
$(INSTALL_DATA) $(srcdir)/veriuser.h $(includedir)/veriuser.h
|
||||
|
||||
$(mandir)/man1/iverilog-vpi.1: $(srcdir)/iverilog-vpi.man
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(mandir)/man1/iverilog-vpi.1
|
||||
|
||||
$(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
|
||||
$(INSTALL_DATA) iverilog-vpi.pdf $(prefix)/iverilog-vpi.pdf
|
||||
|
||||
# In windows installations, put a few examples and the quick_start
|
||||
# into the destination directory.
|
||||
ifeq (@WIN32@,yes)
|
||||
$(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
|
||||
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl \
|
||||
$(mandir) $(mandir)/man1
|
||||
|
||||
uninstall:
|
||||
rm -f $(libdir)/ivl/ivl@EXEEXT@
|
||||
rm -f $(libdir)/ivl/iverilog.conf
|
||||
rm -f $(libdir)/ivl/ivl
|
||||
-rmdir $(libdir)/ivl
|
||||
rm -f $(libdir)/libvpi.a
|
||||
rm -f $(bindir)/verilog
|
||||
rm -f $(bindir)/iverilog-vpi
|
||||
rm -f $(bindir)/gverilog@EXEEXT@
|
||||
rm -f $(includedir)/ivl_target.h
|
||||
rm -f $(includedir)/vpi_user.h
|
||||
rm -f $(includedir)/acc_user.h
|
||||
rm -f $(includedir)/veriuser.h
|
||||
rm -f $(mandir)/man1/iverilog-vpi.1
|
||||
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)
|
||||
|
||||
@@ -16,21 +16,25 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.cc,v 1.14 2000/11/15 20:31:05 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.cc,v 1.19 2002/08/12 01:34:58 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)
|
||||
: name_(strdup(name))
|
||||
{
|
||||
if (pp)
|
||||
ports_ = *pp;
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
{
|
||||
free(name_);
|
||||
}
|
||||
|
||||
void Module::add_gate(PGate*gate)
|
||||
@@ -50,7 +54,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);
|
||||
@@ -65,7 +69,7 @@ void Module::add_behavior(PProcess*b)
|
||||
|
||||
unsigned Module::port_count() const
|
||||
{
|
||||
return ports_.count();
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -75,11 +79,11 @@ unsigned Module::port_count() const
|
||||
*/
|
||||
const svector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
{
|
||||
assert(idx < ports_.count());
|
||||
assert(idx < ports.count());
|
||||
static svector<PEIdent*> zero;
|
||||
|
||||
if (ports_[idx])
|
||||
return ports_[idx]->expr;
|
||||
if (ports[idx])
|
||||
return ports[idx]->expr;
|
||||
else
|
||||
return zero;
|
||||
}
|
||||
@@ -87,17 +91,17 @@ const svector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
unsigned Module::find_port(const string&name) const
|
||||
{
|
||||
assert(name != "");
|
||||
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1)
|
||||
if (ports_[idx]->name == name)
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1)
|
||||
if (ports[idx]->name == name)
|
||||
return idx;
|
||||
|
||||
return ports_.count();
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
|
||||
PWire* Module::get_wire(const string&name) const
|
||||
PWire* Module::get_wire(const hname_t&name) const
|
||||
{
|
||||
map<string,PWire*>::const_iterator obj = wires_.find(name);
|
||||
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
|
||||
if (obj == wires_.end())
|
||||
return 0;
|
||||
else
|
||||
@@ -117,7 +121,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 +139,23 @@ const list<PProcess*>& Module::get_behaviors() const
|
||||
|
||||
/*
|
||||
* $Log: Module.cc,v $
|
||||
* Revision 1.19 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.18 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* Revision 1.17 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.16 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.15 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.14 2000/11/15 20:31:05 steve
|
||||
* Fix warning about temporaries.
|
||||
*
|
||||
|
||||
@@ -18,14 +18,16 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.h,v 1.21 2000/11/05 06:05:59 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.h,v 1.27 2002/08/19 02:39:16 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,20 +60,27 @@ class Module {
|
||||
};
|
||||
|
||||
public:
|
||||
explicit Module(const string&name, const svector<port_t*>*);
|
||||
explicit Module(const char*name);
|
||||
~Module();
|
||||
|
||||
|
||||
/* The module has parameters that are evaluated when the
|
||||
module is elaborated. During parsing, I put the parameters
|
||||
into this map. */
|
||||
map<string,PExpr*>parameters;
|
||||
map<string,PExpr*>localparams;
|
||||
struct param_expr_t {
|
||||
PExpr*expr;
|
||||
PExpr*msb;
|
||||
PExpr*lsb;
|
||||
bool signed_flag;
|
||||
};
|
||||
map<string,param_expr_t>parameters;
|
||||
map<string,param_expr_t>localparams;
|
||||
|
||||
/* The module also has defparam assignments which don't create
|
||||
new parameters within the module, but may be used to set
|
||||
values within this module (when instantiated) or in other
|
||||
instantiated modules. */
|
||||
map<string,PExpr*>defparms;
|
||||
map<hname_t,PExpr*>defparms;
|
||||
|
||||
/* Parameters may be overridden at instantiation time;
|
||||
the overrides do not contain explicit parameter names,
|
||||
@@ -81,6 +90,10 @@ class Module {
|
||||
a parameter-index to its name. */
|
||||
list<string> param_names;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
svector<port_t*> ports;
|
||||
|
||||
/* Keep a table of named events declared in the module. */
|
||||
map<string,PEvent*>events;
|
||||
|
||||
@@ -88,7 +101,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 +120,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 +135,9 @@ 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 +151,25 @@ class Module {
|
||||
|
||||
/*
|
||||
* $Log: Module.h,v $
|
||||
* Revision 1.27 2002/08/19 02:39:16 steve
|
||||
* Support parameters with defined ranges.
|
||||
*
|
||||
* Revision 1.26 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.25 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
|
||||
+82
-22
@@ -16,24 +16,31 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PDelays.cc,v 1.2 2000/02/23 02:56:53 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PDelays.cc,v 1.9 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
# include "verinum.h"
|
||||
|
||||
PDelays::PDelays()
|
||||
{
|
||||
delete_flag_ = true;
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
delay_[idx] = 0;
|
||||
}
|
||||
|
||||
PDelays::~PDelays()
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
delete delay_[idx];
|
||||
if (delete_flag_) {
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
delete delay_[idx];
|
||||
}
|
||||
}
|
||||
|
||||
void PDelays::set_delay(PExpr*del)
|
||||
@@ -41,41 +48,69 @@ void PDelays::set_delay(PExpr*del)
|
||||
assert(del);
|
||||
assert(delay_[0] == 0);
|
||||
delay_[0] = del;
|
||||
delete_flag_ = true;
|
||||
}
|
||||
|
||||
|
||||
void PDelays::set_delays(const svector<PExpr*>*del)
|
||||
void PDelays::set_delays(const svector<PExpr*>*del, bool df)
|
||||
{
|
||||
assert(del);
|
||||
assert(del->count() <= 3);
|
||||
for (unsigned idx = 0 ; idx < del->count() ; idx += 1)
|
||||
delay_[idx] = (*del)[idx];
|
||||
|
||||
delete_flag_ = df;
|
||||
}
|
||||
|
||||
void PDelays::eval_delays(Design*des, const string&path,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const
|
||||
static unsigned long calculate_val(Design*des, const NetScope*scope,
|
||||
const PExpr*expr)
|
||||
{
|
||||
verinum*dv;
|
||||
assert(expr);
|
||||
unsigned long val;
|
||||
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
|
||||
if (verireal*dr = expr->eval_rconst(des, scope)) {
|
||||
val = dr->as_long(shift);
|
||||
delete dr;
|
||||
|
||||
} else {
|
||||
verinum*dv = expr->eval_const(des, scope);
|
||||
if (dv == 0) {
|
||||
cerr << expr->get_line() << ": sorry: non-constant "
|
||||
<< "delays not supported here: " << *expr << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(dv);
|
||||
val = dv->as_ulong();
|
||||
val = des->scale_to_precision(val, scope);
|
||||
delete dv;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
|
||||
|
||||
if (delay_[0]) {
|
||||
dv = delay_[0]->eval_const(des, path);
|
||||
assert(dv);
|
||||
rise_time = dv->as_ulong();
|
||||
delete dv;
|
||||
rise_time = calculate_val(des, scope, delay_[0]);
|
||||
|
||||
if (delay_[1]) {
|
||||
dv = delay_[1]->eval_const(des, path);
|
||||
assert(dv);
|
||||
fall_time = dv->as_ulong();
|
||||
delete dv;
|
||||
fall_time = calculate_val(des, scope, delay_[1]);
|
||||
|
||||
if (delay_[2]) {
|
||||
dv = delay_[2]->eval_const(des, path);
|
||||
assert(dv);
|
||||
decay_time = dv->as_ulong();
|
||||
delete dv;
|
||||
decay_time = calculate_val(des, scope, delay_[2]);
|
||||
|
||||
} else {
|
||||
if (rise_time < fall_time)
|
||||
decay_time = rise_time;
|
||||
@@ -96,6 +131,31 @@ void PDelays::eval_delays(Design*des, const string&path,
|
||||
|
||||
/*
|
||||
* $Log: PDelays.cc,v $
|
||||
* Revision 1.9 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.8 2001/12/29 20:19:31 steve
|
||||
* Do not delete delay expressions of UDP instances.
|
||||
*
|
||||
* Revision 1.7 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.6 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2001/01/20 02:15:50 steve
|
||||
* apologize for not supporting non-constant delays.
|
||||
*
|
||||
* Revision 1.3 2001/01/14 23:04:55 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
* Revision 1.2 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PDelays_H
|
||||
#define __PDelays_H
|
||||
/*
|
||||
* Copyright (c) 1999 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2002 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -18,15 +18,23 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PDelays.h,v 1.2 2000/02/23 02:56:53 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PDelays.h,v 1.7 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
# include <string>
|
||||
# include <iostream>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 2
|
||||
using namespace std;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class PExpr;
|
||||
class ostream;
|
||||
|
||||
/*
|
||||
* Various PForm objects can carry delays. These delays include rise,
|
||||
@@ -38,10 +46,13 @@ class PDelays {
|
||||
PDelays();
|
||||
~PDelays();
|
||||
|
||||
/* Set the delay expressions. If the delete_flag is true, then
|
||||
this object takes ownership of the expressions, and will
|
||||
delete it in the destructor. */
|
||||
void set_delay(PExpr*);
|
||||
void set_delays(const svector<PExpr*>*del);
|
||||
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
|
||||
|
||||
void eval_delays(Design*des, const string&path,
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const;
|
||||
@@ -50,6 +61,7 @@ class PDelays {
|
||||
|
||||
private:
|
||||
PExpr* delay_[3];
|
||||
bool delete_flag_;
|
||||
|
||||
private: // not implemented
|
||||
PDelays(const PDelays&);
|
||||
@@ -60,6 +72,21 @@ ostream& operator << (ostream&o, const PDelays&);
|
||||
|
||||
/*
|
||||
* $Log: PDelays.h,v $
|
||||
* Revision 1.7 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2002/06/14 03:25:51 steve
|
||||
* Compiler portability.
|
||||
*
|
||||
* Revision 1.5 2001/12/29 20:19:31 steve
|
||||
* Do not delete delay expressions of UDP instances.
|
||||
*
|
||||
* Revision 1.4 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.3 2001/01/16 02:44:17 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
* Revision 1.2 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PEvent.cc,v 1.1 2000/04/01 19:31:57 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.cc,v 1.3 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PEvent.h"
|
||||
|
||||
PEvent::PEvent(const string&n)
|
||||
@@ -38,6 +40,13 @@ string PEvent::name() const
|
||||
|
||||
/*
|
||||
* $Log: PEvent.cc,v $
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
|
||||
@@ -18,19 +18,20 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PEvent.h,v 1.3 2000/04/09 17:44:30 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.h,v 1.6 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include <string>
|
||||
class ostream;
|
||||
|
||||
class Design;
|
||||
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,16 @@ class PEvent : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PEvent.h,v $
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.5 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.4 2001/01/16 02:44:18 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
* Revision 1.3 2000/04/09 17:44:30 steve
|
||||
* Catch event declarations during scope elaborate.
|
||||
*
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.cc,v 1.22 2001/01/12 04:31:27 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.cc,v 1.31 2002/08/19 02:39:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "Module.h"
|
||||
# include <typeinfo>
|
||||
@@ -42,37 +46,34 @@ bool PExpr::is_constant(Module*) const
|
||||
return false;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_net(Design*des, const string&path, unsigned,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
Link::strength_t,
|
||||
Link::strength_t) const
|
||||
{
|
||||
cerr << get_line() << ": error: Unable to elaborate `"
|
||||
<< *this << "' as gates." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_lnet(Design*des, const string&path) const
|
||||
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) 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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -133,8 +134,13 @@ const verireal& PEFNumber::value() const
|
||||
return *value_;
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(const string&s)
|
||||
: text_(s), msb_(0), lsb_(0), idx_(0)
|
||||
bool PEFNumber::is_constant(Module*) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(const hname_t&s)
|
||||
: path_(s), msb_(0), lsb_(0), idx_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -142,9 +148,9 @@ PEIdent::~PEIdent()
|
||||
{
|
||||
}
|
||||
|
||||
string PEIdent::name() const
|
||||
const hname_t& PEIdent::path() const
|
||||
{
|
||||
return text_;
|
||||
return path_;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -153,14 +159,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,Module::param_expr_t>::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,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->localparams.find(path_.peek_name(0));
|
||||
if (cur != mod->localparams.end()) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -195,13 +204,14 @@ bool PENumber::is_constant(Module*) const
|
||||
return true;
|
||||
}
|
||||
|
||||
PEString::PEString(const string&s)
|
||||
PEString::PEString(char*s)
|
||||
: text_(s)
|
||||
{
|
||||
}
|
||||
|
||||
PEString::~PEString()
|
||||
{
|
||||
delete[]text_;
|
||||
}
|
||||
|
||||
string PEString::value() const
|
||||
@@ -246,6 +256,38 @@ bool PEUnary::is_constant(Module*m) const
|
||||
|
||||
/*
|
||||
* $Log: PExpr.cc,v $
|
||||
* Revision 1.31 2002/08/19 02:39:16 steve
|
||||
* Support parameters with defined ranges.
|
||||
*
|
||||
* Revision 1.30 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.29 2001/12/30 21:32:03 steve
|
||||
* Support elaborate_net for PEString objects.
|
||||
*
|
||||
* Revision 1.28 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.27 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Revision 1.26 2001/11/07 04:26:46 steve
|
||||
* elaborate_lnet uses scope instead of string path.
|
||||
*
|
||||
* Revision 1.25 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* Revision 1.24 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.23 2001/01/14 23:04:55 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
* Revision 1.22 2001/01/12 04:31:27 steve
|
||||
* Handle error idents in constants not in any scope (PR#97)
|
||||
*
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.h,v 1.47 2000/12/16 19:03:30 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.h,v 1.62 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
@@ -51,8 +51,11 @@ class PExpr : public LineInfo {
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
// Procedural elaboration of the expression.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
|
||||
// Procedural elaboration of the expression. Set thie
|
||||
// bare_memory_ok flag if the result is allowed to be a
|
||||
// NetEMemory without an index.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
bool sys_task_arg =false) const;
|
||||
|
||||
// Elaborate expressions that are the r-value of parameter
|
||||
// assignments. This elaboration follows the restrictions of
|
||||
@@ -62,7 +65,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 +80,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 +89,12 @@ 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
|
||||
// constants.
|
||||
virtual verireal* eval_rconst(const Design*, const NetScope*) const;
|
||||
|
||||
// This method returns true if that expression is the same as
|
||||
// this expression. This method is used for comparing
|
||||
@@ -118,15 +126,16 @@ 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,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
virtual bool is_constant(Module*) const;
|
||||
@@ -177,7 +186,17 @@ 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;
|
||||
|
||||
/* A PEFNumber is a constant, so this returns true. */
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
@@ -188,7 +207,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;
|
||||
@@ -197,13 +216,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,
|
||||
@@ -211,7 +230,8 @@ class PEIdent : public PExpr {
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
|
||||
// Elaborate the PEIdent as a port to a module. This method
|
||||
@@ -219,12 +239,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.
|
||||
@@ -235,11 +256,24 @@ class PEIdent : public PExpr {
|
||||
// expression.
|
||||
PExpr*idx_;
|
||||
|
||||
NetNet* elaborate_net_ram_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_ram_(Design*des, NetScope*scope,
|
||||
NetMemory*mem, unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
|
||||
NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope,
|
||||
NetNet*sig,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
|
||||
private:
|
||||
NetAssign_* elaborate_mem_lval_(Design*des, NetScope*scope,
|
||||
NetMemory*mem) const;
|
||||
|
||||
};
|
||||
|
||||
class PENumber : public PExpr {
|
||||
@@ -251,16 +285,20 @@ class PENumber : public PExpr {
|
||||
const verinum& value() const;
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
virtual verireal*eval_rconst(const Design*, const NetScope*) const;
|
||||
|
||||
virtual bool is_the_same(const PExpr*that) const;
|
||||
virtual bool is_constant(Module*) const;
|
||||
@@ -269,21 +307,37 @@ class PENumber : public PExpr {
|
||||
verinum*const value_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This represents a string constant in an expression.
|
||||
*
|
||||
* The s parameter to the PEString constructor is a C string that this
|
||||
* class instance will take for its own. The caller should not delete
|
||||
* the string, the destructor will do it.
|
||||
*/
|
||||
class PEString : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEString(const string&s);
|
||||
explicit PEString(char*s);
|
||||
~PEString();
|
||||
|
||||
string value() const;
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
verinum* PEString::eval_const(const Design*, const NetScope*) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
private:
|
||||
const string text_;
|
||||
char*text_;
|
||||
};
|
||||
|
||||
class PEUnary : public PExpr {
|
||||
@@ -293,16 +347,17 @@ class PEUnary : public PExpr {
|
||||
~PEUnary();
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEUnary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
@@ -314,22 +369,24 @@ class PEUnary : public PExpr {
|
||||
class PEBinary : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEBinary(char op, PExpr*l, PExpr*r)
|
||||
: op_(op), left_(l), right_(r) { }
|
||||
explicit PEBinary(char op, PExpr*l, PExpr*r);
|
||||
~PEBinary();
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEBinary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetEBinary*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
virtual verireal*eval_rconst(const Design*des, const NetScope*sc) const;
|
||||
|
||||
private:
|
||||
char op_;
|
||||
@@ -338,42 +395,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,
|
||||
@@ -393,16 +450,17 @@ class PETernary : public PExpr {
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetETernary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetETernary*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
@@ -412,213 +470,82 @@ class PETernary : public PExpr {
|
||||
|
||||
/*
|
||||
* This class represents a parsed call to a function, including calls
|
||||
* to system functions.
|
||||
* to system functions. The parameters in the parms list are the
|
||||
* expressions that are passed as input to the ports of the function.
|
||||
*/
|
||||
class PECallFunction : public PExpr {
|
||||
public:
|
||||
explicit PECallFunction(const char*n, const svector<PExpr *> &parms);
|
||||
explicit PECallFunction(const char*n);
|
||||
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
|
||||
explicit PECallFunction(const hname_t&n);
|
||||
~PECallFunction();
|
||||
|
||||
virtual void dump(ostream &) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
bool sys_task_arg =false) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
hname_t path_;
|
||||
svector<PExpr *> parms_;
|
||||
|
||||
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
||||
|
||||
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* Revision 1.47 2000/12/16 19:03:30 steve
|
||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||
* Revision 1.62 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.46 2000/12/10 22:01:35 steve
|
||||
* Support decimal constants in behavioral delays.
|
||||
* Revision 1.61 2002/06/04 05:38:43 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.45 2000/12/06 06:31:09 steve
|
||||
* Check lvalue of procedural continuous assign (PR#29)
|
||||
* Revision 1.60 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Revision 1.44 2000/09/17 21:26:15 steve
|
||||
* Add support for modulus (Eric Aardoom)
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.43 2000/09/09 15:21:26 steve
|
||||
* move lval elaboration to PExpr virtual methods.
|
||||
* Revision 1.59 2002/04/23 03:53:59 steve
|
||||
* Add support for non-constant bit select.
|
||||
*
|
||||
* Revision 1.42 2000/09/07 22:38:13 steve
|
||||
* Support unary + and - in constants.
|
||||
* Revision 1.58 2002/04/14 03:55:25 steve
|
||||
* Precalculate unary - if possible.
|
||||
*
|
||||
* Revision 1.41 2000/06/30 15:50:20 steve
|
||||
* Allow unary operators in constant expressions.
|
||||
* Revision 1.57 2002/04/13 02:33:17 steve
|
||||
* Detect missing indices to memories (PR#421)
|
||||
*
|
||||
* Revision 1.40 2000/06/13 05:22:16 steve
|
||||
* Support concatenation in parameter expressions.
|
||||
* Revision 1.56 2002/03/09 04:02:26 steve
|
||||
* Constant expressions are not l-values for task ports.
|
||||
*
|
||||
* Revision 1.39 2000/06/01 02:31:39 steve
|
||||
* Parameters can be strings.
|
||||
* Revision 1.55 2002/03/09 02:10:22 steve
|
||||
* Add the NetUserFunc netlist node.
|
||||
*
|
||||
* 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.54 2001/12/30 21:32:03 steve
|
||||
* Support elaborate_net for PEString objects.
|
||||
*
|
||||
* Revision 1.37 2000/05/07 04:37:56 steve
|
||||
* Carry strength values from Verilog source to the
|
||||
* pform and netlist for gates.
|
||||
* Revision 1.53 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* 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.52 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* 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.
|
||||
* Revision 1.51 2001/11/07 04:26:46 steve
|
||||
* elaborate_lnet uses scope instead of string path.
|
||||
*
|
||||
* Revision 1.50 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*/
|
||||
#endif
|
||||
|
||||
+11
-2
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PFunction.cc,v 1.4 2001/01/13 22:20:08 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PFunction.cc,v 1.6 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
#include "PTask.h"
|
||||
|
||||
PFunction::PFunction()
|
||||
@@ -52,6 +54,13 @@ void PFunction::set_output(PWire*o)
|
||||
|
||||
/*
|
||||
* $Log: PFunction.cc,v $
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.cc,v 1.9 2000/05/06 15:41:56 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.cc,v 1.14 2002/08/12 01:34:58 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,29 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
const char* PGModule::get_type()
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PGate.cc,v $
|
||||
* Revision 1.14 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.13 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.12 2001/10/21 00:42:47 steve
|
||||
* Module types in pform are char* instead of string.
|
||||
*
|
||||
* Revision 1.11 2001/10/19 01:55:32 steve
|
||||
* Method to get the type_ member
|
||||
*
|
||||
* Revision 1.10 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.9 2000/05/06 15:41:56 steve
|
||||
* Carry assignment strength to pform.
|
||||
*
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.h,v 1.18 2000/05/06 15:41:56 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.h,v 1.24 2002/08/12 01:34:58 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;
|
||||
@@ -79,10 +79,10 @@ class PGate : public LineInfo {
|
||||
void strength0(strength_t);
|
||||
void strength1(strength_t);
|
||||
|
||||
map<string,string> attributes;
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*des, 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,37 @@ 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.24 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.23 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.22 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.21 2001/10/21 00:42:47 steve
|
||||
* Module types in pform are char* instead of string.
|
||||
*
|
||||
* Revision 1.20 2001/10/19 01:55:32 steve
|
||||
* Method to get the type_ member
|
||||
*
|
||||
* Revision 1.19 2001/04/22 23:09:45 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.18 2000/05/06 15:41:56 steve
|
||||
* Carry assignment strength to pform.
|
||||
*
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PTask.cc,v 1.4 2001/01/13 22:20:08 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PTask.cc,v 1.7 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PTask.h"
|
||||
|
||||
PTask::PTask()
|
||||
@@ -40,13 +42,22 @@ void PTask::set_ports(svector<PWire*>*p)
|
||||
void PTask::set_statement(Statement*s)
|
||||
{
|
||||
assert(statement_ == 0);
|
||||
assert(s != 0);
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: PTask.cc,v $
|
||||
* Revision 1.7 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/04/19 03:04:47 steve
|
||||
* Spurious assert of empty statemnt.
|
||||
*
|
||||
* Revision 1.4 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PTask.h,v 1.10 2001/01/13 22:20:08 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PTask.h,v 1.12 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
@@ -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,12 @@ class PFunction : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PTask.h,v $
|
||||
* Revision 1.12 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.11 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.10 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PUdp.h,v 1.4 2000/02/23 02:56:53 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.h,v 1.7 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <map>
|
||||
@@ -27,6 +27,8 @@
|
||||
# include <string>
|
||||
# include "verinum.h"
|
||||
|
||||
class PExpr;
|
||||
|
||||
svector<string>::svector<string>(unsigned size)
|
||||
: nitems_(size), items_(new string[size])
|
||||
{
|
||||
@@ -68,12 +70,12 @@ class PUdp {
|
||||
|
||||
verinum::V initial;
|
||||
|
||||
map<string,string> attributes;
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
void dump(ostream&out) const;
|
||||
|
||||
private:
|
||||
const string name_;
|
||||
private:
|
||||
|
||||
private: // Not implemented
|
||||
PUdp(const PUdp&);
|
||||
@@ -82,6 +84,20 @@ class PUdp {
|
||||
|
||||
/*
|
||||
* $Log: PUdp.h,v $
|
||||
* Revision 1.7 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.5 2001/04/22 23:09:45 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.4 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
||||
@@ -16,16 +16,34 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PWire.cc,v 1.5 2001/01/06 02:29:35 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PWire.cc,v 1.10 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
PWire::PWire(const string&n, NetNet::Type t, NetNet::PortType pt)
|
||||
: name_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
|
||||
PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
|
||||
: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false),
|
||||
lidx_(0), ridx_(0)
|
||||
{
|
||||
if (t == NetNet::INTEGER) {
|
||||
type_ = NetNet::REG;
|
||||
signed_ = true;
|
||||
isint_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt)
|
||||
: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false),
|
||||
lidx_(0), ridx_(0)
|
||||
{
|
||||
if (t == NetNet::INTEGER) {
|
||||
type_ = NetNet::REG;
|
||||
signed_ = true;
|
||||
isint_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
NetNet::Type PWire::get_wire_type() const
|
||||
@@ -33,6 +51,11 @@ NetNet::Type PWire::get_wire_type() const
|
||||
return type_;
|
||||
}
|
||||
|
||||
const hname_t& PWire::path() const
|
||||
{
|
||||
return hname_;
|
||||
}
|
||||
|
||||
bool PWire::set_wire_type(NetNet::Type t)
|
||||
{
|
||||
assert(t != NetNet::IMPLICIT);
|
||||
@@ -45,6 +68,10 @@ bool PWire::set_wire_type(NetNet::Type t)
|
||||
if (t == NetNet::REG) { type_ = t; return true; }
|
||||
return false;
|
||||
case NetNet::REG:
|
||||
if (t == NetNet::INTEGER) {
|
||||
isint_ = true;
|
||||
return true;
|
||||
}
|
||||
if (t == NetNet::REG) return true;
|
||||
return false;
|
||||
default:
|
||||
@@ -91,6 +118,11 @@ bool PWire::get_signed() const
|
||||
return signed_;
|
||||
}
|
||||
|
||||
bool PWire::get_isint() const
|
||||
{
|
||||
return isint_;
|
||||
}
|
||||
|
||||
void PWire::set_range(PExpr*m, PExpr*l)
|
||||
{
|
||||
msb_ = svector<PExpr*>(msb_,m);
|
||||
@@ -108,6 +140,23 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||
|
||||
/*
|
||||
* $Log: PWire.cc,v $
|
||||
* Revision 1.10 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.9 2002/06/21 04:59:35 steve
|
||||
* Carry integerness throughout the compilation.
|
||||
*
|
||||
* Revision 1.8 2002/01/26 05:28:28 steve
|
||||
* Detect scalar/vector declarion mismatch.
|
||||
*
|
||||
* Revision 1.7 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.6 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/01/06 02:29:35 steve
|
||||
* Support arrays of integers.
|
||||
*
|
||||
|
||||
@@ -18,15 +18,21 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PWire.h,v 1.9 2000/12/11 00:31:43 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PWire.h,v 1.14 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
# include "LineInfo.h"
|
||||
# include <map>
|
||||
# include <map>
|
||||
# include "svector.h"
|
||||
|
||||
#ifdef HAVE_IOSFWD
|
||||
# include <iosfwd>
|
||||
#else
|
||||
class ostream;
|
||||
#endif
|
||||
|
||||
class PExpr;
|
||||
class Design;
|
||||
|
||||
@@ -34,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);
|
||||
@@ -51,12 +64,13 @@ class PWire : public LineInfo {
|
||||
|
||||
void set_signed(bool flag);
|
||||
bool get_signed() const;
|
||||
bool get_isint() const;
|
||||
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||
|
||||
map<string,string> attributes;
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
// Write myself to the specified stream.
|
||||
void dump(ostream&out) const;
|
||||
@@ -64,10 +78,11 @@ class PWire : public LineInfo {
|
||||
void elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
hname_t hname_;
|
||||
NetNet::Type type_;
|
||||
NetNet::PortType port_type_;
|
||||
bool signed_;
|
||||
bool isint_; // original type of integer
|
||||
|
||||
// These members hold expressions for the bit width of the
|
||||
// wire. If they do not exist, the wire is 1 bit wide.
|
||||
@@ -86,6 +101,27 @@ class PWire : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PWire.h,v $
|
||||
* Revision 1.14 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.13 2002/06/21 04:59:35 steve
|
||||
* Carry integerness throughout the compilation.
|
||||
*
|
||||
* Revision 1.12 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.11 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.10 2001/01/16 02:44:18 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
* Revision 1.9 2000/12/11 00:31:43 steve
|
||||
* Add support for signed reg variables,
|
||||
* simulate in t-vvm signed comparisons.
|
||||
|
||||
@@ -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.
|
||||
+188
-126
@@ -12,12 +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,
|
||||
tools. These back-end tools currently include a simulator engine
|
||||
called VVP, an XNF (Xilinx Netlist Format) generator and an EDIF fpga
|
||||
netlist generator. In the future, backends are expected for EDIF/LPM,
|
||||
structural Verilog, VHDL, etc.
|
||||
|
||||
For instructions on how to run Icarus Verilog,
|
||||
see the ``iverilog'' man page.
|
||||
|
||||
|
||||
2.0 Building/Installing Icarus Verilog From Source
|
||||
|
||||
If you are starting from source, the build process is designed to be
|
||||
@@ -26,15 +29,17 @@ system and C/C++ compilation should be able to build the source
|
||||
distribution with little effort. Some actual programming skills are
|
||||
not required, but helpful in case of problems.
|
||||
|
||||
If you are building for Windows, see the mingw.txt file.
|
||||
|
||||
2.1 Compile Time Prerequisites
|
||||
|
||||
You need the following software to compile Icarus Verilog from source
|
||||
on a UNIX-like system:
|
||||
|
||||
- GNU Make
|
||||
The Makefiles use some GNU extensions to, so a basic POSIX
|
||||
The Makefiles use some GNU extensions, so a basic POSIX
|
||||
make will not work. Linux systems typically come with a
|
||||
satisfactory make. BSD based systems (i.e. NetBSD, FreeBSD)
|
||||
satisfactory make. BSD based systems (i.e., NetBSD, FreeBSD)
|
||||
typically have GNU make as the gmake program.
|
||||
|
||||
- ISO C++ Compiler
|
||||
@@ -43,7 +48,7 @@ on a UNIX-like system:
|
||||
recent gcc compilers with the associated libstdc++ are known
|
||||
to work. MSVC++ 5 and 6 are known to definitely *not* work.
|
||||
|
||||
- bison
|
||||
- bison and flex
|
||||
|
||||
- gperf 2.7
|
||||
The lexical analyzer doesn't recognize keywords directly,
|
||||
@@ -63,15 +68,48 @@ 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
|
||||
libraries are installed or not.
|
||||
|
||||
--prefix=<root>
|
||||
The default is /usr/local, which causes the tool suite to
|
||||
be compiled for install in /usr/local/bin,
|
||||
/usr/local/share/ivl, etc.
|
||||
|
||||
I recommend that if you are configuring for precompiled
|
||||
binaries, use --prefix=/usr. On Solaris systems, it is
|
||||
common to use --prefix=/opt. You can configure for a non-root
|
||||
install with --prefix=$HOME.
|
||||
|
||||
2.3 (Optional) Testing
|
||||
|
||||
To run a simple test before installation, execute
|
||||
|
||||
make check
|
||||
|
||||
The commands printed by this run might help you in running Icarus
|
||||
Verilog on your own Verilog sources before the package is installed
|
||||
by root.
|
||||
|
||||
2.4 Installation
|
||||
|
||||
Now install the files in an appropriate place. (The makefiles by
|
||||
default install in /usr/local unless you specify a different prefix
|
||||
with the --prefix=<path> flag to the configure command.) Do this as
|
||||
root.
|
||||
with the --prefix=<path> flag to the configure command.) You may need
|
||||
to do this as root to gain access to installation directories.
|
||||
|
||||
make install
|
||||
|
||||
2.5 Uninstallation
|
||||
|
||||
The generated Makefiles also include the uninstall target. This should
|
||||
remove all the files that ``make install'' creates.
|
||||
|
||||
3.0 How Icarus Verilog Works
|
||||
|
||||
This tool includes a parser which reads in Verilog (plus extensions)
|
||||
@@ -91,7 +129,7 @@ only sees a single input file. See ivlpp/ivlpp.txt for details.
|
||||
|
||||
3.2 Parse
|
||||
|
||||
The verilog compiler starts by parsing the verilog source file. The
|
||||
The Verilog compiler starts by parsing the Verilog source file. The
|
||||
output of the parse in a list of Module objects in PFORM. The pform
|
||||
(see pform.h) is mostly a direct reflection of the compilation
|
||||
step. There may be dangling references, and it is not yet clear which
|
||||
@@ -114,10 +152,10 @@ The elaborate() function performs the elaboration.
|
||||
|
||||
One can see a human readable version of the final, elaborated and
|
||||
optimized netlist by using the ``-N <path>'' flag to the compiler. If
|
||||
elaboration succeeds, the final netlist (i.e. after optimizations but
|
||||
elaboration succeeds, the final netlist (i.e., after optimizations but
|
||||
before code generation) will be dumped into the file named <path>.
|
||||
|
||||
Elaboration is actually performed it two steps: scopes and parameters
|
||||
Elaboration is actually performed in two steps: scopes and parameters
|
||||
first, followed by the structural and behavioral elaboration.
|
||||
|
||||
3.3.1 Scope Elaboration
|
||||
@@ -146,19 +184,19 @@ simply passing through the pform.
|
||||
|
||||
This is actually a collection of processing steps that perform
|
||||
optimizations that do not depend on the target technology. Examples of
|
||||
some useful transformations would be,
|
||||
some useful transformations are
|
||||
|
||||
- eliminate null effect circuitry,
|
||||
- eliminate null effect circuitry
|
||||
- combinational reduction
|
||||
- Constant propagation
|
||||
- constant propagation
|
||||
|
||||
The actual functions performed are specified on the ivl command line by
|
||||
the -F flags (See below).
|
||||
the -F flags (see below).
|
||||
|
||||
3.5 Code Generation
|
||||
|
||||
This step takes the design netlist and uses it to drive the code
|
||||
generator. (See target.h.) This may require transforming the
|
||||
generator (see target.h). This may require transforming the
|
||||
design to suit the technology.
|
||||
|
||||
The emit() method of the Design class performs this step. It runs
|
||||
@@ -170,7 +208,10 @@ command line.
|
||||
|
||||
3.6 ATTRIBUTES
|
||||
|
||||
The parser accepts as an extension to Verilog the $attribute module
|
||||
NOTE: The $attribute syntax will soon be deprecated in favor of the
|
||||
Verilog-2001 attribute syntax, which is cleaner and standardized.
|
||||
|
||||
The parser accepts, as an extension to Verilog, the $attribute module
|
||||
item. The syntax of the $attribute item is:
|
||||
|
||||
$attribute (<identifier>, <key>, <value>);
|
||||
@@ -198,6 +239,11 @@ between processing steps. Processing steps that are aware of others
|
||||
may place attributes on netlist objects to communicate information to
|
||||
later steps.
|
||||
|
||||
Icarus Verilog also accepts the Verilog 2001 syntax for
|
||||
attributes. They have the same general meaning as with the $attribute
|
||||
syntax, but they are attached to objects by position instead of by
|
||||
name. Also, the key is a Verilog identifier instead of a string.
|
||||
|
||||
4.0 Running iverilog
|
||||
|
||||
The preferred way to invoke the compiler is with the iverilog(1)
|
||||
@@ -205,82 +251,8 @@ command. This program invokes the preprocessor (ivlpp) and the
|
||||
compiler (ivl) with the proper command line options to get the job
|
||||
done in a friendly way. See the iverilog(1) man page for usage details.
|
||||
|
||||
4.1 Running IVL Directly (not recommended)
|
||||
|
||||
The ivl command is the compiler driver, that invokes the parser,
|
||||
optimization functions and the code generator, but not the preprocessor.
|
||||
|
||||
Usage: ivl <options>... file
|
||||
ivl -h
|
||||
|
||||
-F <name>
|
||||
Use this flag to request an optimization function be applied
|
||||
to the netlist before it is sent to the target output
|
||||
stage. Any number of -F options may be given, to specify a
|
||||
variety of processing steps. The steps will be applied in
|
||||
order, with the output of one uses as the input to the next.
|
||||
|
||||
The function is specified by name. Use the "ivl -h" command to
|
||||
get a list of configured function names.
|
||||
|
||||
-f <assign>
|
||||
Use this flag to set a parameter value. The format of the
|
||||
assignment is <key>=<value> where key is any string up to the
|
||||
first '=', and <value> is the rest of the option. If the '='
|
||||
is omitted, then the key is assigned the empty string.
|
||||
|
||||
The useful keys are defined by the functions and the target in
|
||||
use. These assignments are specifically useful for passing
|
||||
target specific information to the target back-end, or
|
||||
options/parameters to optimization functions, if any are defined.
|
||||
|
||||
-m <module>
|
||||
Cause a named VPI module to be included in the module
|
||||
list. This parameter appends the named module to the end of
|
||||
the VPI_MODULE_LIST. This is an ordered list of modules to be
|
||||
loaded into the simulation at runtime.
|
||||
|
||||
This list can also be set with -fVPI_MODULE_LIST=<list> which
|
||||
sets the list completely. Then, -m after this will append
|
||||
module names to the list sp specified. The default list
|
||||
includes "system".
|
||||
|
||||
-N <file>
|
||||
Dump the elaborated netlist to the named file. The netlist is
|
||||
the folly elaborated netlist, after all the function modules
|
||||
are applied and right before the output generator is
|
||||
called. This is an aid for debugging the compiler, and the
|
||||
output generator in particular.
|
||||
|
||||
-o <file>
|
||||
Normally, the generated result is sent to standard
|
||||
output. Use the -o flag to specify an output file for the
|
||||
generated result.
|
||||
|
||||
-P <file>
|
||||
Write the PForm of the parsed input to the specified file.
|
||||
The pform is the compiler's understanding of the input after
|
||||
parsing and before elaboration. This is an aid for debugging
|
||||
the compiler.
|
||||
|
||||
-s <module>
|
||||
Normally, ivl will elaborate the only module in the source
|
||||
file. If there are multiple modules, use this option to select
|
||||
the module to be used as the top-level module.
|
||||
|
||||
-T [min|typ|max]
|
||||
Normally, ivl will select typ values from min:type:max
|
||||
expressions and print a warning. This flag tells the compiler
|
||||
exactly which value to choose, and suppresses the warning.
|
||||
|
||||
-t <name>
|
||||
Select the output format for the compiled result. Use the
|
||||
"ivl -h" command to get a list of configured targets.
|
||||
|
||||
-v
|
||||
Print version and copyright information for ivl.
|
||||
|
||||
4.2 EXAMPLES
|
||||
4.1 EXAMPLES
|
||||
|
||||
Example: Compiling "hello.vl"
|
||||
|
||||
@@ -297,7 +269,7 @@ endmodule
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
Insure that "iverilog" is on your search path, and the vpi library
|
||||
Ensure that "iverilog" is on your search path, and the vpi library
|
||||
is available.
|
||||
|
||||
To compile the program:
|
||||
@@ -318,24 +290,15 @@ by the compiler. See the iverilog(1) man page.
|
||||
|
||||
Icarus Verilog is in development - as such it still only supports a
|
||||
(growing) subset of Verilog. Below is a description of some of the
|
||||
currently unsupported verilog features. This list is not exhaustive,
|
||||
currently unsupported Verilog features. This list is not exhaustive,
|
||||
and does not account for errors in the compiler. See the Icarus
|
||||
Verilog web page for the current state of support for Verilog.
|
||||
Verilog web page for the current state of support for Verilog, and in
|
||||
particular, browse the bug report database for reported unsupported
|
||||
constructs.
|
||||
|
||||
- block disable not supported, i.e.:
|
||||
|
||||
begin : foo
|
||||
[...]
|
||||
disable foo; // sorry
|
||||
[...]
|
||||
end
|
||||
|
||||
- Functions in structural contexts are not supported.
|
||||
|
||||
assign foo = user_function(a,b); // sorry
|
||||
always @(a or b) foo = user_function(a,b); // OK
|
||||
|
||||
- real data types not supported. This includes real and realtime.
|
||||
- real data types not supported. This includes real and
|
||||
realtime. However, floating point constants in delay expressions
|
||||
are supported so that `timescale works properly.
|
||||
|
||||
- System functions are supported, but the compiler presumes that
|
||||
they return 32 bits. This is the typical case.
|
||||
@@ -344,14 +307,102 @@ Verilog web page for the current state of support for Verilog.
|
||||
|
||||
- trireg is not supported. tri0 and tri1 are supported.
|
||||
|
||||
- tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1
|
||||
and rtranif0 are not supported.
|
||||
|
||||
- Module instance arrays are not supported, although gate instance
|
||||
arrays do work.
|
||||
|
||||
- Net delays, of the form "wire #N foo;" do not work. Delays in
|
||||
every other context do work properly, including the V2001 form
|
||||
"wire #5 foo = bar;"
|
||||
|
||||
- Event controls inside non-blocking assignments are not supported.
|
||||
i.e.: a <= @(posedge clk) b;
|
||||
|
||||
- Lists of named events of the form @(event_1 or event_2) are not
|
||||
supported. Named events are otherwise supported, and lists of
|
||||
other kinds of events are also supported.
|
||||
|
||||
- Macro arguments are not supported. `define macros are supported,
|
||||
but they cannot take arguments.
|
||||
|
||||
5.1 Nonstandard Constructs or Behaviors
|
||||
|
||||
Icarus Verilog includes some features that are not part of the
|
||||
IEEE1364 standard, but have well defined meaning, and also sometimes
|
||||
gives nonstandard (but extended) meanings to some features of the
|
||||
language that are defined.
|
||||
|
||||
$sizeof(<expr>)
|
||||
$bits(<expr>)
|
||||
The $bits system function returns the size in bits of the
|
||||
expression that is its argument. The result of this
|
||||
function is undefined if the argument doesn't have a
|
||||
self-determined size.
|
||||
|
||||
The $sizeof function is deprecated in favor of $bits, which is
|
||||
the same thing, but included in the SystemVerilog definition.
|
||||
|
||||
Builtin system functions
|
||||
|
||||
Certain of the system functions have well defined meanings, so
|
||||
can theoretically be evaluated at compile time, instead of
|
||||
using runtime VPI code. Doing so means that VPI cannot
|
||||
override the definitions of functions handled in this
|
||||
manner. On the other hand, this makes them synthesizeable, and
|
||||
also allows for more aggressive constant propagation. The
|
||||
functions handled in this manner are:
|
||||
|
||||
$bits
|
||||
$signed
|
||||
$sizeof
|
||||
$unsigned
|
||||
|
||||
Implementations of these system functions in VPI modules will
|
||||
be ignored.
|
||||
|
||||
Preprocessing Library Modules
|
||||
|
||||
Icarus Verilog does preprocess modules that are loaded from
|
||||
libraries via the -y mechanism. However, the only macros
|
||||
defined during compilation of that file are those that it
|
||||
defines itself (or includes) or that are defined on the
|
||||
command line or command file.
|
||||
|
||||
Specifically, macros defined in the non-library source files
|
||||
are not remembered when the library module is loaded. This is
|
||||
intentional. If it were otherwise, then compilation results
|
||||
might vary depending on the order that libraries are loaded,
|
||||
and that is too unpredictable.
|
||||
|
||||
It is said that some commercial compilers do allow macro
|
||||
definitions to span library modules. That's just plain weird.
|
||||
|
||||
Width in %t Time Formats
|
||||
|
||||
Standard Verilog does not allow width fields in the %t formats
|
||||
of display strings. For example, this is illegal:
|
||||
|
||||
$display("Time is %0t", %time);
|
||||
|
||||
Standard Verilog instead relies on the $timeformat to
|
||||
completely specify the format.
|
||||
|
||||
Icarus Verilog allows the programmer to specify the field
|
||||
with. The "%t" format in Icarus Verilog works exactly as it
|
||||
does in standard Verilog. However, if the programmer chooses
|
||||
to specify a minimum width (i.e., "%5t"), then for that display
|
||||
Icarus Verilog will override the $timeformat minimum width and
|
||||
use the explicit minimum width.
|
||||
|
||||
6.0 CREDITS
|
||||
|
||||
Except where otherwise noted, Icarus Verilog, ivl and ivlpp are
|
||||
Copyright Stephen Williams. The proper notices are in the head of each
|
||||
file. However, I have received aid in the form of fixes, Verilog
|
||||
guidance, and especially testing from many people, including (in
|
||||
alphabetical order):
|
||||
file. However, I have early on received aid in the form of fixes,
|
||||
Verilog guidance, and especially testing from many people, including
|
||||
(in alphabetical order):
|
||||
|
||||
Eric Aardoom <[email protected]>
|
||||
Stephan I. Boettcher <[email protected]>
|
||||
@@ -359,15 +410,19 @@ alphabetical order):
|
||||
Larry Doolittle <[email protected]>
|
||||
Guy Hutchison <[email protected]>
|
||||
Ales Hvezda <[email protected]>
|
||||
Yasuhisa Kato <ykato@mac.com>
|
||||
Venkat Iyer <venkat@comit.com>
|
||||
Yasuhisa Kato <[email protected]>
|
||||
James Lee <[email protected]>
|
||||
Peter Monta <[email protected]>
|
||||
Daniel H. Nelsen <[email protected]>
|
||||
Stefan Petersen <[email protected]>
|
||||
Michael Ruff <[email protected]>
|
||||
Mike Runyan <[email protected]>
|
||||
Jason Schonberg <[email protected]>
|
||||
Stuart Sutherland <[email protected]>
|
||||
Stephen Tell <[email protected]>
|
||||
Stefan Theide <[email protected]>
|
||||
Tom Verbeure
|
||||
Steve Wilson <[email protected]>
|
||||
|
||||
and others. Testers in particular include a larger community of people
|
||||
@@ -380,11 +435,11 @@ for collecting and organizing the test suite code for all those testers.
|
||||
This is a list of people who have created ports and precompiled
|
||||
packages for various operating systems. These folks have graciously
|
||||
taken on the task of building Icarus Verilog on their systems and
|
||||
bundled it into neat packages.(*) If you want to be added to the list (or
|
||||
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]>
|
||||
@@ -393,10 +448,13 @@ removed from the list) send e-mail to me.
|
||||
Hamish Moffatt <[email protected]>
|
||||
|
||||
Macintosh -- MacO/S
|
||||
Yasuhisa Kato <ykato@mac.com>
|
||||
Yasuhisa Kato <kato@y.email.ne.jp>
|
||||
|
||||
Mac O/S X
|
||||
Timothy J. Wood <[email protected]>
|
||||
|
||||
NetBSD/*
|
||||
Dan <[email protected]>
|
||||
Dan McMahill <[email protected]>
|
||||
|
||||
Solaris/SPARC packages (.pkg)
|
||||
Dan McMahill <[email protected]>
|
||||
@@ -404,15 +462,19 @@ removed from the list) send e-mail to me.
|
||||
Cygwin32/*
|
||||
Venkat Iyer <[email protected]>
|
||||
|
||||
(*) These are not the only systems where Icarus Verilog has been run,
|
||||
Mingw32
|
||||
Venkat Iyer <[email protected]>
|
||||
|
||||
(+) These are not the only systems where Icarus Verilog has been run,
|
||||
just the systems where precompiled binaries are publicly available.
|
||||
|
||||
|
||||
6.2 TEST SUITE MANAGER
|
||||
|
||||
Steve Wilson <stevew@home.com> or <[email protected]> has taken on
|
||||
the large task of managing the test suite. He has maintained the
|
||||
regression test scripts, the driver list, received submissions from
|
||||
myself and others, and has written a great many tests on his own. Any
|
||||
compiler writer, for any language, will tell you that the test suite
|
||||
is at least as important as the compiler code itself.
|
||||
Steve Wilson <stevew@ka6s.com> has taken on the large task of managing
|
||||
the test suite. He has maintained the regression test scripts, the
|
||||
driver list, received submissions from myself and others, and has
|
||||
written a great many tests on his own. Any compiler writer, for any
|
||||
language, will tell you that the test suite is at least as important
|
||||
as the compiler code itself.
|
||||
|
||||
|
||||
+60
-102
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Statement.cc,v 1.22 2000/07/26 05:08:07 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.cc,v 1.28 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Statement.h"
|
||||
# include "PExpr.h"
|
||||
|
||||
@@ -30,17 +32,19 @@ Statement::~Statement()
|
||||
PAssign_::PAssign_(PExpr*lval, PExpr*ex)
|
||||
: event_(0), lval_(lval), rval_(ex)
|
||||
{
|
||||
delay_ = 0;
|
||||
}
|
||||
|
||||
PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex)
|
||||
: event_(0), lval_(lval), rval_(ex)
|
||||
{
|
||||
if (de) delay_.set_delay(de);
|
||||
delay_ = de;
|
||||
}
|
||||
|
||||
PAssign_::PAssign_(PExpr*lval, PEventStatement*ev, PExpr*ex)
|
||||
: event_(ev), lval_(lval), rval_(ex)
|
||||
{
|
||||
delay_ = 0;
|
||||
}
|
||||
|
||||
PAssign_::~PAssign_()
|
||||
@@ -103,11 +107,20 @@ PBlock::~PBlock()
|
||||
delete list_[idx];
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(const string&n, const svector<PExpr*>&p)
|
||||
: name_(n), parms_(p)
|
||||
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
|
||||
: path_(n), parms_(p)
|
||||
{
|
||||
}
|
||||
|
||||
PCallTask::~PCallTask()
|
||||
{
|
||||
}
|
||||
|
||||
const hname_t& PCallTask::path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
|
||||
: type_(t), expr_(ex), items_(l)
|
||||
{
|
||||
@@ -165,7 +178,7 @@ PDelayStatement::~PDelayStatement()
|
||||
{
|
||||
}
|
||||
|
||||
PDisable::PDisable(const string&sc)
|
||||
PDisable::PDisable(const hname_t&sc)
|
||||
: scope_(sc)
|
||||
{
|
||||
}
|
||||
@@ -177,6 +190,7 @@ PDisable::~PDisable()
|
||||
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
||||
: expr_(ee), statement_(0)
|
||||
{
|
||||
assert(expr_.count() > 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -186,6 +200,11 @@ PEventStatement::PEventStatement(PEEvent*ee)
|
||||
expr_[0] = ee;
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(void)
|
||||
: statement_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PEventStatement::~PEventStatement()
|
||||
{
|
||||
// delete the events and the statement?
|
||||
@@ -217,6 +236,17 @@ PForever::~PForever()
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||
PExpr*n2, PExpr*e2, Statement*st)
|
||||
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
|
||||
statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PForStatement::~PForStatement()
|
||||
{
|
||||
}
|
||||
|
||||
PProcess::~PProcess()
|
||||
{
|
||||
delete statement_;
|
||||
@@ -243,7 +273,7 @@ PRepeat::~PRepeat()
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PTrigger::PTrigger(const string&e)
|
||||
PTrigger::PTrigger(const hname_t&e)
|
||||
: event_(e)
|
||||
{
|
||||
}
|
||||
@@ -252,6 +282,11 @@ PTrigger::~PTrigger()
|
||||
{
|
||||
}
|
||||
|
||||
PWhile::PWhile(PExpr*e1, Statement*st)
|
||||
: cond_(e1), statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PWhile::~PWhile()
|
||||
{
|
||||
delete cond_;
|
||||
@@ -260,105 +295,28 @@ PWhile::~PWhile()
|
||||
|
||||
/*
|
||||
* $Log: Statement.cc,v $
|
||||
* Revision 1.22 2000/07/26 05:08:07 steve
|
||||
* Parse disable statements to pform.
|
||||
* Revision 1.28 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.21 2000/05/11 23:37:26 steve
|
||||
* Add support for procedural continuous assignment.
|
||||
* Revision 1.27 2002/04/21 22:31:02 steve
|
||||
* Redo handling of assignment internal delays.
|
||||
* Leave it possible for them to be calculated
|
||||
* at run time.
|
||||
*
|
||||
* Revision 1.20 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
* Revision 1.26 2002/04/21 04:59:07 steve
|
||||
* Add support for conbinational events by finding
|
||||
* the inputs to expressions and some statements.
|
||||
* Get case and assignment statements working.
|
||||
*
|
||||
* Revision 1.19 2000/04/12 04:23:57 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the 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.
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
|
||||
+75
-142
@@ -18,14 +18,15 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Statement.h,v 1.29 2000/09/09 15:21:26 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.h,v 1.36 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include "svector.h"
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
# include "HName.h"
|
||||
# include "LineInfo.h"
|
||||
class PExpr;
|
||||
class Statement;
|
||||
@@ -55,6 +56,8 @@ class PProcess : public LineInfo {
|
||||
Type type() const { return type_; }
|
||||
Statement*statement() { return statement_; }
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -74,7 +77,7 @@ class Statement : public LineInfo {
|
||||
virtual ~Statement() =0;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
@@ -96,7 +99,7 @@ class PAssign_ : public Statement {
|
||||
protected:
|
||||
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
|
||||
|
||||
PDelays delay_;
|
||||
PExpr* delay_;
|
||||
PEventStatement*event_;
|
||||
|
||||
private:
|
||||
@@ -113,11 +116,9 @@ class PAssign : public PAssign_ {
|
||||
~PAssign();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
|
||||
Design*des, const string&path) const;
|
||||
};
|
||||
|
||||
class PAssignNB : public PAssign_ {
|
||||
@@ -128,11 +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_;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -308,6 +308,7 @@ class PDisable : public Statement {
|
||||
*
|
||||
* @name <statement>;
|
||||
* @(expr) <statement>;
|
||||
* @* <statement>;
|
||||
*/
|
||||
class PEventStatement : public Statement {
|
||||
|
||||
@@ -315,18 +316,20 @@ class PEventStatement : public Statement {
|
||||
|
||||
explicit PEventStatement(const svector<PEEvent*>&ee);
|
||||
explicit PEventStatement(PEEvent*ee);
|
||||
// Make an @* statement.
|
||||
explicit PEventStatement(void);
|
||||
|
||||
~PEventStatement();
|
||||
|
||||
void set_statement(Statement*st);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
// This method is used to elaborate, but attach a previously
|
||||
// elaborated statement to the event.
|
||||
NetProc* elaborate_st(Design*des, const string&path, NetProc*st) const;
|
||||
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
|
||||
|
||||
private:
|
||||
svector<PEEvent*>expr_;
|
||||
@@ -339,7 +342,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 +355,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 +367,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 +397,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 +412,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 +426,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 +453,38 @@ class PWhile : public Statement {
|
||||
|
||||
/*
|
||||
* $Log: Statement.h,v $
|
||||
* Revision 1.36 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.35 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.34 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.33 2002/04/21 22:31:02 steve
|
||||
* Redo handling of assignment internal delays.
|
||||
* Leave it possible for them to be calculated
|
||||
* at run time.
|
||||
*
|
||||
* Revision 1.32 2002/04/21 04:59:07 steve
|
||||
* Add support for conbinational events by finding
|
||||
* the inputs to expressions and some statements.
|
||||
* Get case and assignment statements working.
|
||||
*
|
||||
* Revision 1.31 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.30 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.29 2000/09/09 15:21:26 steve
|
||||
* move lval elaboration to PExpr virtual methods.
|
||||
*
|
||||
@@ -480,104 +512,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
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
* ---
|
||||
* You should also have recieved a copy of the Picture Elements
|
||||
* Binary Software License offer along with the source. This offer
|
||||
* allows you to obtain the right to redistribute the software in
|
||||
* binary (compiled) form. If you have not received it, contact
|
||||
* Picture Elements, Inc., 777 Panoramic Way, Berkeley, CA 94704.
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: StringHeap.cc,v 1.2 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "StringHeap.h"
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
StringHeap::StringHeap()
|
||||
{
|
||||
cell_base_ = 0;
|
||||
cell_ptr_ = HEAPCELL;
|
||||
}
|
||||
|
||||
StringHeap::~StringHeap()
|
||||
{
|
||||
// This is a planned memory leak. The string heap is indended
|
||||
// to hold permanently-allocated strings.
|
||||
}
|
||||
|
||||
const char* StringHeap::add(const char*text)
|
||||
{
|
||||
unsigned len = strlen(text);
|
||||
assert((len+1) <= HEAPCELL);
|
||||
|
||||
unsigned rem = HEAPCELL - cell_ptr_;
|
||||
if (rem < (len+1)) {
|
||||
cell_base_ = (char*)malloc(HEAPCELL);
|
||||
cell_ptr_ = 0;
|
||||
}
|
||||
|
||||
char*res = cell_base_ + cell_ptr_;
|
||||
memcpy(res, text, len);
|
||||
cell_ptr_ += len;
|
||||
cell_base_[cell_ptr_++] = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: StringHeap.cc,v $
|
||||
* Revision 1.2 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/08/04 19:13:16 steve
|
||||
* dll uses StringHeap for named items.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef __StringHeap_H
|
||||
#define __StringHeap_H
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: StringHeap.h,v 1.2 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
class StringHeap {
|
||||
|
||||
public:
|
||||
StringHeap();
|
||||
~StringHeap();
|
||||
|
||||
const char*add(const char*);
|
||||
|
||||
private:
|
||||
enum { HEAPCELL = 0x10000 };
|
||||
|
||||
char*cell_base_;
|
||||
unsigned cell_ptr_;
|
||||
|
||||
private: // not implemented
|
||||
StringHeap(const StringHeap&);
|
||||
StringHeap& operator= (const StringHeap&);
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: StringHeap.h,v $
|
||||
* Revision 1.2 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/08/04 19:13:16 steve
|
||||
* dll uses StringHeap for named items.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
#ifndef __acc_user_H
|
||||
#define __acc_user_H
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: acc_user.h,v 1.6 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This header file contains the definitions and declarations needed
|
||||
* by an Icarus Verilog user using acc_ routines.
|
||||
*
|
||||
* NOTE: Icarus Verilog does not support acc_ routines. This is just a
|
||||
* stub. The functions that are implemented here are actually
|
||||
* implemented using VPI routines.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define EXTERN_C_START extern "C" {
|
||||
# define EXTERN_C_END }
|
||||
#else
|
||||
# define EXTERN_C_START
|
||||
# define EXTERN_C_END
|
||||
# define bool int
|
||||
#endif
|
||||
|
||||
EXTERN_C_START
|
||||
|
||||
/*
|
||||
* This is a declaration of the "handle" type that is compatible with
|
||||
* the vpiHandle from vpi_user.h.
|
||||
*/
|
||||
typedef struct __vpiHandle *handle;
|
||||
|
||||
/* OBJECT TYPES */
|
||||
#define accScope 21
|
||||
#define accScalar 300
|
||||
#define accVector 302
|
||||
|
||||
/* type VALUES FOR t_setval_delay STRUCTURE */
|
||||
#define accNoDelay 0
|
||||
#define accInertialDelay 1
|
||||
#define accTransportDelay 2
|
||||
#define accPureTransportDelay 3
|
||||
#define accForceFlag 4
|
||||
#define accReleaseFlag 5
|
||||
|
||||
/* type VALUES FOR t_setval_value STRUCTURE */
|
||||
#define accBinStrVal 1
|
||||
#define accOctStrVal 2
|
||||
#define accDecStrVal 3
|
||||
#define accHexStrVal 4
|
||||
#define accScalarVal 5
|
||||
#define accIntVal 6
|
||||
#define accRealVal 7
|
||||
#define accStringVal 8
|
||||
#define accVectorVal 9
|
||||
|
||||
/* type VALUES FOR t_acc_time STRUCTURE */
|
||||
#define accTime 1
|
||||
#define accSimTime 2
|
||||
#define accRealTime 3
|
||||
|
||||
|
||||
typedef struct t_acc_time {
|
||||
int type;
|
||||
int low, high;
|
||||
double real;
|
||||
} s_acc_time, *p_acc_time;
|
||||
|
||||
typedef struct t_setval_delay {
|
||||
s_acc_time time;
|
||||
int model;
|
||||
} s_setval_delay, *p_setval_delay;
|
||||
|
||||
typedef struct t_acc_vecval {
|
||||
int aval;
|
||||
int bval;
|
||||
} s_acc_vecval, *p_acc_vecval;
|
||||
|
||||
typedef struct t_setval_value {
|
||||
int format;
|
||||
union {
|
||||
char*str;
|
||||
int scalar;
|
||||
int integer;
|
||||
double real;
|
||||
p_acc_vecval vector;
|
||||
} value;
|
||||
} s_setval_value, *p_setval_value, s_acc_value, *p_acc_value;
|
||||
|
||||
extern int acc_error_flag;
|
||||
|
||||
extern int acc_initialize(void);
|
||||
|
||||
extern void acc_close(void);
|
||||
|
||||
extern int acc_fetch_argc(void);
|
||||
extern char**acc_fetch_argv(void);
|
||||
|
||||
extern char* acc_fetch_fullname(handle obj);
|
||||
|
||||
extern int acc_fetch_tfarg_int(int n);
|
||||
extern char* acc_fetch_tfarg_str(int n);
|
||||
|
||||
extern handle acc_handle_tfarg(int n);
|
||||
|
||||
extern handle acc_next_topmod(handle prev_topmod);
|
||||
|
||||
extern int acc_object_of_type(handle object, int type);
|
||||
|
||||
extern char*acc_product_version(void);
|
||||
|
||||
extern int acc_set_value(handle obj, p_setval_value value,
|
||||
p_setval_delay delay);
|
||||
|
||||
extern char* acc_version(void);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
/*
|
||||
* $Log: acc_user.h,v $
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.5 2002/06/11 15:19:12 steve
|
||||
* Add acc_fetch_argc/argv/version (mruff)
|
||||
*
|
||||
* Revision 1.4 2002/06/07 02:58:58 steve
|
||||
* Add a bunch of acc/tf functions. (mruff)
|
||||
*
|
||||
* Revision 1.3 2002/06/02 19:03:29 steve
|
||||
* Add acc_handle_tfarg and acc_next_topmode
|
||||
*
|
||||
* Revision 1.2 2002/05/30 02:06:05 steve
|
||||
* Implement acc_product_version.
|
||||
*
|
||||
* Revision 1.1 2002/05/23 03:46:42 steve
|
||||
* Add the acc_user.h header file.
|
||||
*
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: async.cc,v 1.4 2002/08/18 22:07:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
# include <assert.h>
|
||||
|
||||
bool NetAssign::is_asynchronous()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCondit::is_asynchronous()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetEvWait::is_asynchronous()
|
||||
{
|
||||
/* The "sense" set contains the set of Nexa that are in the
|
||||
sensitivity list. We also presume here that the list is
|
||||
only LEVEL sensitive. */
|
||||
NexusSet*sense = new NexusSet;
|
||||
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
|
||||
NexusSet*tmp = event(idx)->nex_async_();
|
||||
if (tmp == 0) {
|
||||
delete sense;
|
||||
return false;
|
||||
}
|
||||
|
||||
sense->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
NexusSet*inputs = statement_->nex_input();
|
||||
|
||||
if (! sense->contains(*inputs)) {
|
||||
delete sense;
|
||||
delete inputs;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete sense;
|
||||
delete inputs;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetProc::is_asynchronous()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetProcTop::is_asynchronous()
|
||||
{
|
||||
if (type_ == NetProcTop::KINITIAL)
|
||||
return false;
|
||||
|
||||
return statement_->is_asynchronous();
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: async.cc,v $
|
||||
* Revision 1.4 2002/08/18 22:07:16 steve
|
||||
* Detect temporaries in sequential block synthesis.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/07/04 00:24:16 steve
|
||||
* initial statements are not asynchronous.
|
||||
*
|
||||
* Revision 1.1 2002/06/30 02:21:31 steve
|
||||
* Add structure for asynchronous logic synthesis.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
ATTRIBUTES TO CONTROL SYNTHESIS
|
||||
|
||||
The following is a summary of Verilog attributes that Icarus Verilog
|
||||
understands within Verilog source files to control synthesis
|
||||
behavior. This section documents generic synthesis attributes. For
|
||||
target specific attributes, see target specific documentation.
|
||||
|
||||
These attributes only effect the behavior of the synthesizer. For
|
||||
example, the ivl_combinational will not generate an error message
|
||||
if the Verilog is being compiled for simulation. (It may generate a
|
||||
warning.)
|
||||
|
||||
|
||||
* Attributes for "always" and "initial" statements
|
||||
|
||||
(* ivl_combinational *)
|
||||
|
||||
This attribute tells the compiler that the statement models
|
||||
combinational logic. If the compiler finds that it cannot make
|
||||
combinational logic out of a marked always statement, it will
|
||||
report an error.
|
||||
|
||||
This attribute can be used to prevent accidentally inferring
|
||||
latches or flip-flops where the user intended combinational
|
||||
logic.
|
||||
|
||||
(* ivl_synthesis_on *)
|
||||
|
||||
This attribute tells the compiler that the marked always statement
|
||||
is synthesizeable. The compiler will attempt to synthesize the
|
||||
code in the marked "always" statement. If it cannot in any way
|
||||
synthesize it, then it will report an error.
|
||||
|
||||
(* ivl_synthesis_off *)
|
||||
|
||||
If this value is attached to an "always" statement, then the
|
||||
compiler will *not* synthesize the "always" statment. This can be
|
||||
used, for example, to mark embedded test bench code.
|
||||
|
||||
|
||||
* Attributes for signals (wire/reg/integer/tri/etc.)
|
||||
|
||||
[ none defined yet ]
|
||||
|
||||
|
||||
* Other Attributes
|
||||
|
||||
[ none defined yet ]
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
#!/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 libveriuser
|
||||
do
|
||||
echo "Autoconf in $dir..."
|
||||
( cd ./$dir ; autoconf )
|
||||
done
|
||||
|
||||
echo "Precompiling lexor_keyword.gperf"
|
||||
gperf -o -i 7 -C -k 1-3,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
|
||||
@@ -4,3 +4,6 @@
|
||||
|
||||
[-tvvm-check]
|
||||
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o.cc -- -
|
||||
|
||||
[-tvvp-check]
|
||||
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=./tgt-vvp/vvp.tgt -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o -- -
|
||||
|
||||
+47
-13
@@ -18,10 +18,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: compiler.h,v 1.5 2000/10/31 17:49:02 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: compiler.h,v 1.13 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
|
||||
/*
|
||||
* This defines constants and defaults for the compiler in general.
|
||||
*/
|
||||
@@ -65,24 +67,56 @@
|
||||
|
||||
/* Implicit definitions of wires. */
|
||||
extern bool warn_implicit;
|
||||
extern bool error_implicit;
|
||||
|
||||
/* inherit timescales accross files. */
|
||||
extern bool warn_timescale;
|
||||
|
||||
/* This is true if verbose output is requested. */
|
||||
extern bool verbose_flag;
|
||||
|
||||
/* This is an ordered list of library suffixxes to search. */
|
||||
extern list<const char*>library_suff;
|
||||
extern int build_library_index(const char*path, bool key_case_sensitive);
|
||||
|
||||
/* This is the generation of Verilog that the compiler is asked to
|
||||
support. */
|
||||
enum generation_t {
|
||||
GN_VER1995 = 1,
|
||||
GN_VER2001 = 2,
|
||||
GN_SYSVER30 = 3,
|
||||
GN_DEFAULT = 3
|
||||
};
|
||||
|
||||
extern generation_t generation_flag;
|
||||
|
||||
/* This is the string to use to invoke the preprocessor. */
|
||||
extern char*ivlpp_string;
|
||||
|
||||
/*
|
||||
* $Log: compiler.h,v $
|
||||
* Revision 1.5 2000/10/31 17:49:02 steve
|
||||
* Support time variables.
|
||||
* Revision 1.13 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.4 2000/08/20 04:13:56 steve
|
||||
* Add ivl_target support for logic gates, and
|
||||
* make the interface more accessible.
|
||||
* Revision 1.12 2002/05/28 20:40:37 steve
|
||||
* ivl indexes the search path for libraries, and
|
||||
* supports case insensitive module-to-file lookup.
|
||||
*
|
||||
* Revision 1.3 2000/03/17 21:50:25 steve
|
||||
* Switch to control warnings.
|
||||
* Revision 1.11 2002/05/28 00:50:39 steve
|
||||
* Add the ivl -C flag for bulk configuration
|
||||
* from the driver, and use that to run library
|
||||
* modules through the preprocessor.
|
||||
*
|
||||
* Revision 1.2 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
* Revision 1.10 2002/05/24 01:13:00 steve
|
||||
* Support language generation flag -g.
|
||||
*
|
||||
* Revision 1.1 1999/06/06 20:42:48 steve
|
||||
* Make compiler width a compile time constant.
|
||||
* Revision 1.9 2002/04/22 00:53:39 steve
|
||||
* Do not allow implicit wires in sensitivity lists.
|
||||
*
|
||||
* Revision 1.8 2002/04/15 00:04:22 steve
|
||||
* Timescale warnings.
|
||||
*
|
||||
* Revision 1.7 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
*/
|
||||
#endif
|
||||
|
||||
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.
|
||||
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
#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.5 2002/08/11 23:39:33 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.5 2002/08/11 23:39:33 steve
|
||||
* Remove VVM option.
|
||||
*
|
||||
* Revision 1.4 2002/02/16 03:18:53 steve
|
||||
* Make vvm optional, normally off.
|
||||
*
|
||||
* Revision 1.3 2001/10/18 16:16:23 steve
|
||||
* Include HAVE_SYS_WAIT in config.h (PR#306)
|
||||
*
|
||||
* Revision 1.2 2001/09/15 18:27:04 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
* Revision 1.1 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
*/
|
||||
#endif // __config_H
|
||||
Vendored
+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/"`
|
||||
;;
|
||||
|
||||
+167
-54
@@ -1,14 +1,59 @@
|
||||
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_HEADERS(getopt.h)
|
||||
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_CHECK_PROGS(LEX,flex,none)
|
||||
if test "$LEX" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable flex found. ***"
|
||||
echo " Please install the 'flex' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(YACC,bison,none)
|
||||
if test "$YACC" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable bison found. ***"
|
||||
echo " Please install the 'bison' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
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,
|
||||
[ --with-ipal enable PAL target],
|
||||
if test "$with_ipal" = no; then
|
||||
echo Disabling ipal support
|
||||
HAVE_IPAL=
|
||||
fi
|
||||
)
|
||||
AC_SUBST(HAVE_IPAL)
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# --
|
||||
# Look for a dl library to use. First look for the standard dlopen
|
||||
@@ -23,58 +68,13 @@ AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
|
||||
fi
|
||||
AC_SUBST(DLLIB)
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_LANG_C
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
# $host
|
||||
|
||||
|
||||
#######################
|
||||
## test for underscores. The vpi module loader in vvm needs to know this
|
||||
## in order to know the name of the start symbol for the .vpi module.
|
||||
#######################
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_SUBST(CYGWIN)
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
AC_MSG_CHECKING("for leading and/or trailing underscores")
|
||||
cat << EOF > underscore.c
|
||||
void underscore(void){}
|
||||
EOF
|
||||
$CC -shared -c underscore.c > /dev/null 2>&1
|
||||
|
||||
CC_LEADING_UNDERSCORE=no
|
||||
CC_TRAILING_UNDERSCORE=no
|
||||
|
||||
output=`nm underscore.o|grep _underscore 2>&1`
|
||||
if test ! -z "$output" -a -z "$CYGWIN" ; then
|
||||
CC_LEADING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_LU)
|
||||
fi
|
||||
|
||||
|
||||
|
||||
output=`nm underscore.o|grep underscore_ 2>&1`
|
||||
if test ! -z "$output"; then
|
||||
CC_TRAILING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_TU)
|
||||
fi
|
||||
|
||||
if test "$CC_LEADING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WLU)
|
||||
fi
|
||||
if test "$CC_TRAILING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WTU)
|
||||
fi
|
||||
|
||||
rm underscore.c underscore.o
|
||||
|
||||
AC_MSG_RESULT("$CC_LEADING_UNDERSCORE $CC_TRAILING_UNDERSCORE")
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
|
||||
@@ -95,6 +95,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
|
||||
@@ -118,28 +138,121 @@ 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)
|
||||
|
||||
AC_MSG_RESULT($shared)
|
||||
|
||||
#######################
|
||||
## test for underscores. The vpi module loader needs to know this
|
||||
## in order to know the name of the start symbol for the .vpi module.
|
||||
#######################
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_MINGW32
|
||||
|
||||
|
||||
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
WIN32=no
|
||||
AC_MSG_CHECKING("Checking for windows")
|
||||
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
|
||||
then
|
||||
WIN32=yes
|
||||
fi
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
|
||||
AC_MSG_CHECKING("for leading and/or trailing underscores")
|
||||
cat << EOF > underscore.c
|
||||
void underscore(void){}
|
||||
EOF
|
||||
|
||||
$CC $shared -c underscore.c > /dev/null 2>&1
|
||||
|
||||
CC_LEADING_UNDERSCORE=no
|
||||
CC_TRAILING_UNDERSCORE=no
|
||||
|
||||
output=`nm underscore.o|grep _underscore 2>&1`
|
||||
if test ! -z "$output" -o $WIN32 = "yes"; then
|
||||
CC_LEADING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_LU)
|
||||
fi
|
||||
|
||||
output=`nm underscore.o|grep underscore_ 2>&1`
|
||||
if test ! -z "$output"; then
|
||||
CC_TRAILING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_TU)
|
||||
fi
|
||||
|
||||
if test "$CC_LEADING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WLU)
|
||||
fi
|
||||
if test "$CC_TRAILING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WTU)
|
||||
fi
|
||||
|
||||
rm underscore.c underscore.o
|
||||
|
||||
AC_MSG_RESULT("$CC_LEADING_UNDERSCORE $CC_TRAILING_UNDERSCORE")
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
AC_MSG_CHECKING("for ident support in C compiler")
|
||||
ident_support='-DHAVE_CVS_IDENT=1'
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
ident_support=
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
ident_support=
|
||||
;;
|
||||
|
||||
*-*-machten*)
|
||||
ident_support=
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(ident_support)
|
||||
AC_MSG_RESULT($ident_support)
|
||||
|
||||
|
||||
AC_CONFIG_SUBDIRS(vvp tgt-vvp tgt-fpga libveriuser)
|
||||
|
||||
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cprop.cc,v 1.23 2000/12/30 03:11:15 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cprop.cc,v 1.39 2002/08/20 04:12:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "functor.h"
|
||||
@@ -38,16 +40,23 @@ 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.
|
||||
if (obj->attribute("LPM_Direction") != "ADD")
|
||||
if (obj->attribute("LPM_Direction") != verinum("ADD"))
|
||||
return;
|
||||
|
||||
// If the low bit on the A side is 0, then eliminate it from
|
||||
@@ -55,11 +64,11 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
||||
// result. Don't reduce the adder smaller then a 1-bit
|
||||
// adder. These will be eliminated later.
|
||||
while ((obj->width() > 1)
|
||||
&& link_drivers_constant(obj->pin_DataA(0))
|
||||
&& (driven_value(obj->pin_DataA(0)) == verinum::V0)) {
|
||||
&& obj->pin_DataA(0).nexus()->drivers_constant()
|
||||
&& (obj->pin_DataA(0).nexus()->driven_value() == verinum::V0)) {
|
||||
|
||||
NetAddSub*tmp = 0;
|
||||
tmp = new NetAddSub(obj->name(), obj->width()-1);
|
||||
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
|
||||
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
|
||||
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
|
||||
//connect(tmp->pin_Clock(), obj->pin_Clock());
|
||||
@@ -80,11 +89,11 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
||||
|
||||
// Now do the same thing on the B side.
|
||||
while ((obj->width() > 1)
|
||||
&& link_drivers_constant(obj->pin_DataB(0))
|
||||
&& (driven_value(obj->pin_DataB(0)) == verinum::V0)) {
|
||||
&& obj->pin_DataB(0).nexus()->drivers_constant()
|
||||
&& (obj->pin_DataB(0).nexus()->driven_value() == verinum::V0)) {
|
||||
|
||||
NetAddSub*tmp = 0;
|
||||
tmp = new NetAddSub(obj->name(), obj->width()-1);
|
||||
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
|
||||
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
|
||||
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
|
||||
//connect(tmp->pin_Clock(), obj->pin_Clock());
|
||||
@@ -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 (! obj->pin_DataA(idx).nexus()->drivers_constant())
|
||||
continue;
|
||||
if (! obj->pin_DataB(idx).nexus()->drivers_constant())
|
||||
continue;
|
||||
if (obj->pin_DataA(idx).nexus()->driven_value() ==
|
||||
obj->pin_DataB(idx).nexus()->driven_value())
|
||||
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 (! obj->pin_DataA(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
if (! obj->pin_DataB(idx).nexus()->drivers_constant()) {
|
||||
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::XNOR);
|
||||
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:
|
||||
@@ -194,12 +310,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
on the output of an AND gate. */
|
||||
|
||||
while (idx < top) {
|
||||
if (! link_drivers_constant(obj->pin(idx))) {
|
||||
if (! obj->pin(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) == verinum::V1) {
|
||||
if (obj->pin(idx).nexus()->driven_value()==verinum::V1) {
|
||||
obj->pin(idx).unlink();
|
||||
top -= 1;
|
||||
if (idx < top) {
|
||||
@@ -210,7 +326,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) != verinum::V0) {
|
||||
if (obj->pin(idx).nexus()->driven_value() != verinum::V0) {
|
||||
idx += 1;
|
||||
xs += 1;
|
||||
continue;
|
||||
@@ -223,15 +339,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::AND:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -248,15 +368,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::AND:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -271,7 +395,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,18 +412,23 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::AND:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -311,12 +440,16 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
}
|
||||
|
||||
/* Finally, this cleans up the gate by creating a
|
||||
new [N]OR gate that has the right number of
|
||||
new [N]AND gate that has the right number of
|
||||
inputs, connected in the right place. */
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -341,12 +474,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
on the output of an OR gate. */
|
||||
|
||||
while (idx < top) {
|
||||
if (! link_drivers_constant(obj->pin(idx))) {
|
||||
if (! obj->pin(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) == verinum::V0) {
|
||||
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
|
||||
obj->pin(idx).unlink();
|
||||
top -= 1;
|
||||
if (idx < top) {
|
||||
@@ -357,7 +490,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) != verinum::V1) {
|
||||
if (obj->pin(idx).nexus()->driven_value() != verinum::V1) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -369,15 +502,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::OR:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
case NetLogic::NOR:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -394,15 +531,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::OR:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
case NetLogic::NOR:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -419,18 +560,22 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::OR:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
break;
|
||||
case NetLogic::NOR:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -445,9 +590,13 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
new [N]OR gate that has the right number of
|
||||
inputs, connected in the right place. */
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -467,14 +616,17 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
unsigned idx = 1;
|
||||
|
||||
/* Eliminate all the 0 inputs. They have no effect
|
||||
on the output of an XOR gate. */
|
||||
on the output of an XOR gate. The eliminate works
|
||||
by unlinking the current input and relinking the
|
||||
last input to this position. It's like bubbling
|
||||
all the 0 inputs to the end. */
|
||||
while (idx < top) {
|
||||
if (! link_drivers_constant(obj->pin(idx))) {
|
||||
if (! obj->pin(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) == verinum::V0) {
|
||||
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
|
||||
obj->pin(idx).unlink();
|
||||
top -= 1;
|
||||
if (idx < top) {
|
||||
@@ -499,12 +651,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
unsigned one = 0, ones = 0;
|
||||
idx = 1;
|
||||
while (idx < top) {
|
||||
if (! link_drivers_constant(obj->pin(idx))) {
|
||||
if (! obj->pin(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) == verinum::V1) {
|
||||
if (obj->pin(idx).nexus()->driven_value() == verinum::V1) {
|
||||
if (one == 0) {
|
||||
one = idx;
|
||||
ones += 1;
|
||||
@@ -512,6 +664,8 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Here we found two constant V1
|
||||
inputs. Unlink both. */
|
||||
obj->pin(idx).unlink();
|
||||
top -= 1;
|
||||
if (idx < top) {
|
||||
@@ -526,8 +680,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
obj->pin(top).unlink();
|
||||
}
|
||||
|
||||
/* Reset ones counter and one index,
|
||||
start looking for the next pair. */
|
||||
assert(ones == 1);
|
||||
ones = 0;
|
||||
one = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -535,12 +692,16 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
}
|
||||
|
||||
/* If all the inputs were eliminated, then replace
|
||||
the gate with a constant 0 and I am done. */
|
||||
the gate with a constant value and I am done. */
|
||||
if (top == 1) {
|
||||
verinum::V out = obj->type()==NetLogic::XNOR
|
||||
? verinum::V1
|
||||
: verinum::V0;
|
||||
NetConst*tmp = new NetConst(obj->name(), out);
|
||||
NetConst*tmp = new NetConst(scope, obj->name(), out);
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
@@ -558,9 +719,9 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
|
||||
if ((top == 3) && (ones == 1)) {
|
||||
unsigned save;
|
||||
if (! link_drivers_constant(obj->pin(1)))
|
||||
if (! obj->pin(1).nexus()->drivers_constant())
|
||||
save = 1;
|
||||
else if (driven_value(obj->pin(1)) != verinum::V1)
|
||||
else if (obj->pin(1).nexus()->driven_value() != verinum::V1)
|
||||
save = 1;
|
||||
else
|
||||
save = 2;
|
||||
@@ -568,14 +729,18 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
|
||||
if (obj->type() == NetLogic::XOR)
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
else
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -593,14 +758,18 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
|
||||
if (obj->type() == NetLogic::XOR)
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
else
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -615,7 +784,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);
|
||||
@@ -653,12 +822,12 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
connected to the select input. */
|
||||
bool flag = true;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (! link_drivers_constant(obj->pin_Data(idx, 0))) {
|
||||
if (! obj->pin_Data(idx, 0).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin_Data(idx, 0)) != verinum::Vz) {
|
||||
if (obj->pin_Data(idx, 0).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
@@ -685,12 +854,12 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
NetMux with an array of BUFIF0 devices. */
|
||||
flag = true;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (! link_drivers_constant(obj->pin_Data(idx, 1))) {
|
||||
if (! obj->pin_Data(idx, 1).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin_Data(idx, 1)) != verinum::Vz) {
|
||||
if (obj->pin_Data(idx, 1).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
@@ -771,7 +940,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
return;
|
||||
|
||||
// Look for signals that have NetESignal nodes attached to
|
||||
// them. If I find any, this this constant is used by a
|
||||
// them. If I find any, then this constant is used by a
|
||||
// behavioral expression somewhere.
|
||||
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
|
||||
Nexus*nex = obj->pin(idx).nexus();
|
||||
@@ -783,13 +952,27 @@ 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->peek_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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Done. Delete me.
|
||||
delete obj;
|
||||
}
|
||||
@@ -811,6 +994,65 @@ void cprop(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: cprop.cc,v $
|
||||
* Revision 1.39 2002/08/20 04:12:22 steve
|
||||
* Copy gate delays when doing gate delay substitutions.
|
||||
*
|
||||
* Revision 1.38 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.37 2002/06/25 01:33:22 steve
|
||||
* Cache calculated driven value.
|
||||
*
|
||||
* Revision 1.36 2002/06/24 01:49:38 steve
|
||||
* Make link_drive_constant cache its results in
|
||||
* the Nexus, to improve cprop performance.
|
||||
*
|
||||
* Revision 1.35 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.34 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.33 2002/04/14 02:51:37 steve
|
||||
* Fix bug removing pairs of ones in XOR.
|
||||
*
|
||||
* Revision 1.32 2002/02/03 00:06:28 steve
|
||||
* Comments about xor evaluation.
|
||||
*
|
||||
* Revision 1.31 2001/12/31 01:56:08 steve
|
||||
* Get sense of 1-bit == operator right.
|
||||
*
|
||||
* 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:
|
||||
|
||||
+234
-124
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: design_dump.cc,v 1.109 2001/01/13 22:20:08 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: design_dump.cc,v 1.135 2002/10/23 01:47:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
/*
|
||||
* This file contains all the dump methods of the netlist classes.
|
||||
*/
|
||||
@@ -75,7 +77,23 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
o << " (local)";
|
||||
if (signed_)
|
||||
o << " signed";
|
||||
o << " (eref=" << get_eref() << ")";
|
||||
switch (port_type_) {
|
||||
case NetNet::NOT_A_PORT:
|
||||
break;
|
||||
case NetNet::PIMPLICIT:
|
||||
o << " implicit-port?";
|
||||
break;
|
||||
case NetNet::PINPUT:
|
||||
o << " input";
|
||||
break;
|
||||
case NetNet::POUTPUT:
|
||||
o << " output";
|
||||
break;
|
||||
case NetNet::PINOUT:
|
||||
o << " inout";
|
||||
break;
|
||||
}
|
||||
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
|
||||
if (scope())
|
||||
o << " scope=" << scope()->name();
|
||||
o << " #(" << rise_time() << "," << fall_time() << "," <<
|
||||
@@ -99,6 +117,13 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetSubnet::dump_net(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "** " << name() << " is a NetSubnet **"
|
||||
<< endl;
|
||||
NetNet::dump_net(o, ind);
|
||||
}
|
||||
|
||||
void NetMemory::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << name_ << "[" << width_ << "] " <<
|
||||
@@ -156,9 +181,9 @@ void NetObj::dump_node_pins(ostream&o, unsigned ind) const
|
||||
void NetObj::dump_obj_attr(ostream&o, unsigned ind) const
|
||||
{
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < attributes_.size() ; idx += 1) {
|
||||
o << setw(ind) << "" << attributes_.key(idx) << " = \"" <<
|
||||
attributes_.value(idx) << "\"" << endl;
|
||||
for (idx = 0 ; idx < attr_cnt() ; idx += 1) {
|
||||
o << setw(ind) << "" << attr_key(idx) << " = \"" <<
|
||||
attr_value(idx) << "\"" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,20 +238,12 @@ void NetMult::dump_node(ostream&o, unsigned ind) const
|
||||
|
||||
void NetMux::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Multiplexer (NetMux): " << name() << endl;
|
||||
o << setw(ind) << "" << "Multiplexer (NetMux): " << name()
|
||||
<< " scope=" << scope()->name() << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
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()
|
||||
@@ -254,7 +271,8 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
|
||||
void NetFF::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "LPM_FF: " << name()
|
||||
<< " scope=" << (scope()? scope()->name() : "") << endl;
|
||||
<< " scope=" << (scope()? scope()->name() : "")
|
||||
<< " aset_value=" << aset_value_ << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
@@ -297,6 +315,12 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
|
||||
case OR:
|
||||
o << "or";
|
||||
break;
|
||||
case PULLDOWN:
|
||||
o << "pulldown";
|
||||
break;
|
||||
case PULLUP:
|
||||
o << "pullup";
|
||||
break;
|
||||
case RNMOS:
|
||||
o << "rnmos";
|
||||
break;
|
||||
@@ -337,12 +361,21 @@ void NetRamDq::dump_node(ostream&o, unsigned ind) const
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetUserFunc::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << def_->name() << "(";
|
||||
o << ")" << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetTaskDef::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "task " << name_ << ";" << endl;
|
||||
|
||||
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 ";
|
||||
@@ -365,77 +398,12 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
|
||||
o << setw(ind) << "" << "endtask" << endl;
|
||||
}
|
||||
|
||||
void NetUDP::dump_sequ_(ostream&o, unsigned ind) const
|
||||
{
|
||||
string tmp = "";
|
||||
for (unsigned idx = 0 ; idx < ind ; idx += 1)
|
||||
tmp += " ";
|
||||
|
||||
o << tmp << "Sequential UDP" << " #(" << rise_time() <<
|
||||
"," << fall_time() << "," << decay_time() << ") " << name() <<
|
||||
endl;
|
||||
|
||||
for (FSM_::const_iterator ent = fsm_.begin()
|
||||
; ent != fsm_.end() ; ent++) {
|
||||
o << setw(ind+6) << "" << (*ent).first << " -->";
|
||||
|
||||
state_t_*st = (*ent).second;
|
||||
assert((*ent).first[0] == st->out);
|
||||
for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
|
||||
string tmp = (*ent).first;
|
||||
if (st->pins[idx].zer) {
|
||||
tmp[0] = st->pins[idx].zer->out;
|
||||
tmp[idx] = '0';
|
||||
o << " " << tmp;
|
||||
}
|
||||
|
||||
if (st->pins[idx].one) {
|
||||
tmp[0] = st->pins[idx].one->out;
|
||||
tmp[idx] = '1';
|
||||
o << " " << tmp;
|
||||
}
|
||||
|
||||
if (st->pins[idx].xxx) {
|
||||
tmp[0] = st->pins[idx].xxx->out;
|
||||
tmp[idx] = 'x';
|
||||
o << " " << tmp;
|
||||
}
|
||||
}
|
||||
|
||||
o << endl;
|
||||
}
|
||||
|
||||
o << setw(ind+6) << "" << "initial value == " << init_ << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetUDP::dump_comb_(ostream&o, unsigned ind) const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void NetUDP::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
if (is_sequential())
|
||||
dump_sequ_(o, ind);
|
||||
else
|
||||
dump_comb_(o, ind);
|
||||
}
|
||||
|
||||
void NetUDP_COMB::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Combinational primitive: ";
|
||||
o << setw(ind) << "" << "UDP (" << udp_name() << "): ";
|
||||
o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
|
||||
") " << name() << endl;
|
||||
|
||||
for (map<string,char>::const_iterator ent = cm_.begin()
|
||||
; ent != cm_.end() ; ent++) {
|
||||
o << setw(ind+6) << "" << (*ent).first << " --> " <<
|
||||
(*ent).second << endl;
|
||||
}
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
@@ -453,19 +421,45 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) {
|
||||
o << setw(ind+2) << "" << "(* " << attr_key(idx) << " = "
|
||||
<< attr_value(idx) << " *)" << endl;
|
||||
}
|
||||
|
||||
statement_->dump(o, ind+2);
|
||||
}
|
||||
|
||||
void NetAssign_::dump_lval(ostream&o) const
|
||||
{
|
||||
if (sig_) {
|
||||
o << sig_->name();
|
||||
if (bmux_) {
|
||||
o << "[" << *bmux_ << "]";
|
||||
|
||||
} else {
|
||||
o << "[" << (loff_+lwid_-1) << ":" << loff_ << "]";
|
||||
}
|
||||
} else if (mem_) {
|
||||
// Is there an obvious way to flag memories in the dump
|
||||
// as different from the _real_ bit mux case?
|
||||
// o << "**memory**";
|
||||
o << mem_->name() << "[";
|
||||
if (bmux_) o << *bmux_;
|
||||
else o << "**oops**";
|
||||
o << "]";
|
||||
} else {
|
||||
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 << "}";
|
||||
@@ -478,8 +472,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;
|
||||
}
|
||||
|
||||
@@ -489,36 +485,21 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
|
||||
dump_lval(o);
|
||||
|
||||
o << " <= ";
|
||||
#if 0
|
||||
if (l_val(0)->rise_time())
|
||||
o << "#" << l_val(0)->rise_time() << " ";
|
||||
#endif
|
||||
o << *rval() << ";" << endl;
|
||||
|
||||
}
|
||||
|
||||
void NetAssignMem::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "";
|
||||
o << "/* " << get_line() << " */" << endl;
|
||||
o << setw(ind) << "";
|
||||
o << memory()->name() << "[" << *index() << "] = ";
|
||||
rval()->dump(o);
|
||||
o << ";" << endl;
|
||||
}
|
||||
|
||||
void NetAssignMemNB::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "";
|
||||
o << "/* " << get_line() << " */" << endl;
|
||||
o << setw(ind) << "";
|
||||
o << memory()->name() << "[" << *index() << "] <= ";
|
||||
rval()->dump(o);
|
||||
o << ";" << endl;
|
||||
}
|
||||
|
||||
/* Dump a block statement */
|
||||
void NetBlock::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << type_ << endl;
|
||||
o << setw(ind) << "" << type_;
|
||||
if (subscope_)
|
||||
o << " : " << subscope_->name();
|
||||
o << endl;
|
||||
|
||||
if (last_) {
|
||||
const NetProc*cur = last_;
|
||||
@@ -678,8 +659,12 @@ void NetPDelay::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetRelease::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "release " << lval_->name() << "; "
|
||||
<< "/* " << get_line() << " */" << endl;
|
||||
if (lval_)
|
||||
o << setw(ind) << "" << "release " << lval_->name() << "; "
|
||||
<< "/* " << get_line() << " */" << endl;
|
||||
else
|
||||
o << setw(ind) << "" << "release (null); "
|
||||
<< "/* " << get_line() << " */" << endl;
|
||||
}
|
||||
|
||||
void NetRepeat::dump(ostream&o, unsigned ind) const
|
||||
@@ -715,23 +700,32 @@ void NetScope::dump(ostream&o) const
|
||||
|
||||
/* Dump the parameters for this scope. */
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator pp;
|
||||
map<string,param_expr_t>::const_iterator pp;
|
||||
for (pp = parameters_.begin()
|
||||
; pp != parameters_.end() ; pp ++) {
|
||||
o << " parameter " << (*pp).first << " = " <<
|
||||
*(*pp).second << ";" << endl;
|
||||
o << " parameter ";
|
||||
|
||||
if ((*pp).second.signed_flag)
|
||||
o << "signed ";
|
||||
|
||||
if ((*pp).second.msb)
|
||||
o << "[" << *(*pp).second.msb
|
||||
<< ":" << *(*pp).second.lsb << "] ";
|
||||
|
||||
o << (*pp).first << " = " <<
|
||||
*(*pp).second.expr << ";" << endl;
|
||||
}
|
||||
|
||||
for (pp = localparams_.begin()
|
||||
; pp != localparams_.end() ; pp ++) {
|
||||
o << " localparam " << (*pp).first << " = " <<
|
||||
*(*pp).second << ";" << endl;
|
||||
*(*pp).second.expr << ";" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump the saved defparam assignments here. */
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator pp;
|
||||
map<hname_t,NetExpr*>::const_iterator pp;
|
||||
for (pp = defparams.begin()
|
||||
; pp != defparams.end() ; pp ++ ) {
|
||||
o << " defparam " << (*pp).first << " = " <<
|
||||
@@ -817,7 +811,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
|
||||
@@ -873,8 +867,12 @@ void NetEBinary::dump(ostream&o) const
|
||||
|
||||
void NetEConcat::dump(ostream&o) const
|
||||
{
|
||||
if (repeat_ != 1)
|
||||
o << repeat_;
|
||||
if (repeat_calculated_) {
|
||||
if (repeat_value_ != 1)
|
||||
o << repeat_value_;
|
||||
} else if (repeat_) {
|
||||
o << "<" << *repeat_ << ">";
|
||||
}
|
||||
|
||||
if (parms_[0])
|
||||
o << "{" << *parms_[0];
|
||||
@@ -915,10 +913,12 @@ void NetESFunc::dump(ostream&o) const
|
||||
|
||||
void NetESignal::dump(ostream&o) const
|
||||
{
|
||||
o << name();
|
||||
if (has_sign())
|
||||
o << "+";
|
||||
o << name() << "[" << msi_<<":"<<lsi_ << "]";
|
||||
}
|
||||
|
||||
void NetESubSignal::dump(ostream&o) const
|
||||
void NetEBitSel::dump(ostream&o) const
|
||||
{
|
||||
sig_->dump(o);
|
||||
o << "[";
|
||||
@@ -935,7 +935,10 @@ void NetEMemory::dump(ostream&o) const
|
||||
|
||||
void NetEParam::dump(ostream&o) const
|
||||
{
|
||||
o << "<" << scope_->name() << "." << name_ << ">";
|
||||
if (scope_ != 0)
|
||||
o << "<" << scope_->name() << "." << name_ << ">";
|
||||
else
|
||||
o << "<" << name_ << ">";
|
||||
}
|
||||
|
||||
void NetETernary::dump(ostream&o) const
|
||||
@@ -976,7 +979,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;
|
||||
|
||||
@@ -999,6 +1004,111 @@ void Design::dump(ostream&o) const
|
||||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.135 2002/10/23 01:47:17 steve
|
||||
* Fix synth2 handling of aset/aclr signals where
|
||||
* flip-flops are split by begin-end blocks.
|
||||
*
|
||||
* Revision 1.134 2002/10/19 22:59:49 steve
|
||||
* Redo the parameter vector support to allow
|
||||
* parameter names in range expressions.
|
||||
*
|
||||
* Revision 1.133 2002/08/19 00:06:11 steve
|
||||
* Allow release to handle removal of target net.
|
||||
*
|
||||
* Revision 1.132 2002/08/13 05:35:00 steve
|
||||
* Do not elide named blocks.
|
||||
*
|
||||
* Revision 1.131 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.130 2002/08/04 18:28:14 steve
|
||||
* Do not use hierarchical names of memories to
|
||||
* generate vvp labels. -tdll target does not
|
||||
* used hierarchical name string to look up the
|
||||
* memory objects in the design.
|
||||
*
|
||||
* Revision 1.129 2002/06/19 04:20:03 steve
|
||||
* Remove NetTmp and add NetSubnet class.
|
||||
*
|
||||
* Revision 1.128 2002/06/14 21:38:41 steve
|
||||
* Fix expression width for repeat concatenations.
|
||||
*
|
||||
* Revision 1.127 2002/06/08 23:42:46 steve
|
||||
* Add NetRamDq synthsesis from memory l-values.
|
||||
*
|
||||
* Revision 1.126 2002/06/05 03:44:25 steve
|
||||
* Add support for memory words in l-value of
|
||||
* non-blocking assignments, and remove the special
|
||||
* NetAssignMem_ and NetAssignMemNB classes.
|
||||
*
|
||||
* Revision 1.125 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.124 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.123 2002/05/05 21:11:49 steve
|
||||
* Put off evaluation of concatenation repeat expresions
|
||||
* until after parameters are defined. This allows parms
|
||||
* to be used in repeat expresions.
|
||||
*
|
||||
* Add the builtin $signed system function.
|
||||
*
|
||||
* Revision 1.122 2002/03/09 02:10:22 steve
|
||||
* Add the NetUserFunc netlist node.
|
||||
*
|
||||
* Revision 1.121 2001/12/31 00:03:05 steve
|
||||
* Include s indicator in dump of signed numbers.
|
||||
*
|
||||
* Revision 1.120 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.119 2001/11/19 01:46:38 steve
|
||||
* Print typename is fallback expression node dump.
|
||||
*
|
||||
* Revision 1.118 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.117 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.116 2001/07/27 04:51:44 steve
|
||||
* Handle part select expressions as variants of
|
||||
* NetESignal/IVL_EX_SIGNAL objects, instead of
|
||||
* creating new and useless temporary signals.
|
||||
*
|
||||
* Revision 1.115 2001/07/27 02:41:55 steve
|
||||
* Fix binding of dangling function ports. do not elide them.
|
||||
*
|
||||
* Revision 1.114 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.113 2001/04/29 20:19:10 steve
|
||||
* Add pullup and pulldown devices.
|
||||
*
|
||||
* Revision 1.112 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.111 2001/02/17 05:13:36 steve
|
||||
* Check that the port really exists here.
|
||||
*
|
||||
* Revision 1.110 2001/01/18 03:16:35 steve
|
||||
* NetMux needs a scope. (PR#115)
|
||||
*
|
||||
* Revision 1.109 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: dosify.c,v 1.3 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is a simple program to make a dosified copy of the
|
||||
* original. That is, it converts unix style line ends to DOS
|
||||
* style. This is useful for installing text files.
|
||||
*
|
||||
* The exact substitution is to replace \n with \r\n. If the line
|
||||
* already ends with \r\n then it is not changed to \r\r\n.
|
||||
*/
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
FILE*ifile;
|
||||
FILE*ofile;
|
||||
int ch, pr;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <input> <output>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ifile = fopen(argv[1], "rb");
|
||||
if (ifile == 0) {
|
||||
fprintf(stderr, "Unable to open %s for input.\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
ofile = fopen(argv[2], "wb");
|
||||
if (ofile == 0) {
|
||||
fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
pr = 0;
|
||||
while ((ch = fgetc(ifile)) != EOF) {
|
||||
|
||||
if ((ch == '\n') && (pr != '\r'))
|
||||
fputc('\r', ofile);
|
||||
|
||||
fputc(ch, ofile);
|
||||
pr = ch;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: dosify.c,v $
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/08/11 23:47:04 steve
|
||||
* Add missing Log and Ident strings.
|
||||
*
|
||||
* Revision 1.1 2001/08/03 17:06:47 steve
|
||||
* Add install of examples for Windows.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
a.out
|
||||
Makefile
|
||||
parse.c
|
||||
parse.h
|
||||
parse.output
|
||||
lexor.c
|
||||
cfparse.c
|
||||
cfparse.h
|
||||
cfparse.output
|
||||
cflexor.c
|
||||
foo.*
|
||||
iverilog
|
||||
iverilog.ps
|
||||
iverilog.pdf
|
||||
tmp.pdf
|
||||
|
||||
+36
-10
@@ -18,12 +18,12 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.3 2001/01/09 03:11:27 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.15 2002/08/10 22:36:59 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
VERSION = 0.6
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -37,7 +37,6 @@ includedir = $(prefix)/include
|
||||
mandir = @mandir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
rdynamic=@rdynamic@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
@@ -46,35 +45,59 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I.
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
|
||||
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 substit.o cflexor.o cfparse.o
|
||||
|
||||
iverilog@EXEEXT@: $O
|
||||
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@
|
||||
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
|
||||
|
||||
lexor.c: lexor.lex
|
||||
flex -s -olexor.c $(srcdir)/lexor.lex
|
||||
|
||||
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@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
||||
|
||||
build_string.o: build_string.c globals.h
|
||||
lexor.o: lexor.c parse.h globals.h
|
||||
parse.o: parse.c globals.h
|
||||
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
|
||||
cfparse.o: cfparse.c globals.h cfparse_misc.h
|
||||
|
||||
iverilog.ps: $(srcdir)/iverilog.man
|
||||
man -t $(srcdir)/iverilog.man > iverilog.ps
|
||||
|
||||
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(mandir)/man1/iverilog.1
|
||||
iverilog.pdf: iverilog.ps
|
||||
ps2pdf iverilog.ps iverilog.pdf
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
INSTALL_DOC = $(prefix)/iverilog.pdf
|
||||
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 +105,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@
|
||||
|
||||
+56
-2
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: build_string.c,v 1.2 2000/10/28 03:45:47 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: build_string.c,v 1.11 2002/08/12 01:35:01 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "globals.h"
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
@@ -51,6 +53,8 @@ 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 == 'M') && depfile)
|
||||
|| ((*pattern == 'N') && npath)
|
||||
|| ((*pattern == 'T') && mtm)) {
|
||||
int rc = build_string(output, olen,
|
||||
@@ -68,6 +72,18 @@ int build_string(char*output, size_t olen, const char*pattern)
|
||||
olen -= strlen(base);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
strcpy(output, iconfig_path);
|
||||
output += strlen(iconfig_path);
|
||||
olen -= strlen(iconfig_path);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
strcpy(output, generation);
|
||||
output += strlen(generation);
|
||||
olen -= strlen(generation);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (f_list) {
|
||||
strcpy(output, f_list);
|
||||
@@ -84,6 +100,14 @@ int build_string(char*output, size_t olen, const char*pattern)
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
if (depfile) {
|
||||
strcpy(output, depfile);
|
||||
output += strlen(depfile);
|
||||
olen -= strlen(depfile);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
if (npath) {
|
||||
strcpy(output, npath);
|
||||
@@ -141,6 +165,36 @@ int build_string(char*output, size_t olen, const char*pattern)
|
||||
|
||||
/*
|
||||
* $Log: build_string.c,v $
|
||||
* Revision 1.11 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.10 2002/05/28 02:25:03 steve
|
||||
* Pass library paths through -Cfile instead of command line.
|
||||
*
|
||||
* Revision 1.9 2002/05/28 00:50:39 steve
|
||||
* Add the ivl -C flag for bulk configuration
|
||||
* from the driver, and use that to run library
|
||||
* modules through the preprocessor.
|
||||
*
|
||||
* Revision 1.8 2002/05/24 01:13:00 steve
|
||||
* Support language generation flag -g.
|
||||
*
|
||||
* Revision 1.7 2002/04/04 05:26:13 steve
|
||||
* Add dependency generation.
|
||||
*
|
||||
* 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,137 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cflexor.lex,v 1.6 2002/05/28 20:40:37 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "cfparse.h"
|
||||
# include "cfparse_misc.h"
|
||||
# include "globals.h"
|
||||
# include <string.h>
|
||||
|
||||
/*
|
||||
* Lexical location information is passed in the yylloc variable to th
|
||||
* parser. The file names, strings, are kept in a list so that I can
|
||||
* re-use them. The set_file_name function will return a pointer to
|
||||
* the name as it exists in the list (and delete the passed string.)
|
||||
* If the name is new, it will be added to the list.
|
||||
*/
|
||||
YYLTYPE yylloc;
|
||||
|
||||
static int comment_enter;
|
||||
|
||||
%}
|
||||
|
||||
%x CCOMMENT
|
||||
%x LCOMMENT
|
||||
%x PLUS_ARGS
|
||||
|
||||
%%
|
||||
|
||||
/* Accept C++ style comments. */
|
||||
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
|
||||
<LCOMMENT>. { yymore(); }
|
||||
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
|
||||
|
||||
/* Accept C style comments. */
|
||||
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
|
||||
<CCOMMENT>. { yymore(); }
|
||||
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
|
||||
<CCOMMENT>"*/" { BEGIN(comment_enter); }
|
||||
|
||||
/* Accept shell type comments. */
|
||||
^"#".* { ; }
|
||||
|
||||
/* Skip white space. */
|
||||
[ \t\f\r] { ; }
|
||||
/* Skip line ends, but also count the line. */
|
||||
\n { yylloc.first_line += 1; }
|
||||
|
||||
|
||||
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
|
||||
|
||||
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
|
||||
|
||||
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
|
||||
|
||||
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
|
||||
|
||||
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
|
||||
|
||||
|
||||
/* If it is not any known plus-flag, return the generic form. */
|
||||
"+"[^\n \t\b\f\r+]* {
|
||||
cflval.text = strdup(yytext);
|
||||
BEGIN(PLUS_ARGS);
|
||||
return TOK_PLUSWORD; }
|
||||
|
||||
/* Once in PLUS_ARGS mode, words are delimited by +
|
||||
characters. White space and line end terminate PLUS_ARGS mode,
|
||||
but + terminates only the word. */
|
||||
<PLUS_ARGS>[^\n \t\b\f\r+]* {
|
||||
cflval.text = strdup(yytext);
|
||||
return TOK_PLUSARG; }
|
||||
|
||||
/* Within plusargs, this is a delimiter. */
|
||||
<PLUS_ARGS>"+" { }
|
||||
|
||||
/* White space end plus_args mode. */
|
||||
<PLUS_ARGS>[ \t\b\f\r] { BEGIN(0); }
|
||||
|
||||
<PLUS_ARGS>\n {
|
||||
yylloc.first_line += 1;
|
||||
BEGIN(0); }
|
||||
|
||||
/* Notice the -a flag. */
|
||||
"-a" { return TOK_Da; }
|
||||
|
||||
/* Notice the -v flag. */
|
||||
"-v" { return TOK_Dv; }
|
||||
|
||||
/* Notice the -y flag. */
|
||||
"-y" { return TOK_Dy; }
|
||||
|
||||
/* This rule matches paths and strings that may be file names. This
|
||||
is a little bit tricky, as we don't want to mistake a comment for
|
||||
a string word. */
|
||||
"/"[^\*\/].* { cflval.text = strdup(yytext);
|
||||
return TOK_STRING; }
|
||||
|
||||
[^/\n \t\b\r+-].* { cflval.text = strdup(yytext);
|
||||
return TOK_STRING; }
|
||||
|
||||
/* Fallback match. */
|
||||
. { return yytext[0]; }
|
||||
|
||||
%%
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cfreset(FILE*fd, const char*path)
|
||||
{
|
||||
yyin = fd;
|
||||
yyrestart(fd);
|
||||
yylloc.first_line = 1;
|
||||
yylloc.text = (char*)path;
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
%{
|
||||
/*
|
||||
* 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.8 2002/06/23 20:10:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
# include "globals.h"
|
||||
# include "cfparse_misc.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_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
|
||||
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
||||
|
||||
%%
|
||||
|
||||
start
|
||||
:
|
||||
| item_list
|
||||
;
|
||||
|
||||
item_list
|
||||
: item_list item
|
||||
| item
|
||||
;
|
||||
|
||||
item
|
||||
/* Absent any other matching, a token string is taken to be the name
|
||||
of a source file. Add the file to the file list. */
|
||||
|
||||
: TOK_STRING
|
||||
{ char*tmp = substitutions($1);
|
||||
translate_file_name(tmp);
|
||||
process_file_name(tmp);
|
||||
free($1);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* The -a flag is completely ignored. */
|
||||
|
||||
| TOK_Da { }
|
||||
|
||||
/* The -v <libfile> flag is ignored, and the <libfile> is processed
|
||||
as an ordinary source file. */
|
||||
|
||||
| TOK_Dv TOK_STRING
|
||||
{ char*tmp = substitutions($2);
|
||||
translate_file_name(tmp);
|
||||
process_file_name(tmp);
|
||||
fprintf(stderr, "%s:%u: Ignoring -v in front of %s\n",
|
||||
@1.text, @1.first_line, $2);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* This rule matches "-y <path>" sequences. This does the same thing
|
||||
as -y on the command line, so add the path to the library
|
||||
directory list. */
|
||||
|
||||
| TOK_Dy TOK_STRING
|
||||
{ char*tmp = substitutions($2);
|
||||
process_library_switch(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_LIBDIR TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
process_library_switch(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_LIBDIR_NOCASE TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
process_library_nocase_switch(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_DEFINE TOK_PLUSARG
|
||||
{ process_define($2);
|
||||
free($2);
|
||||
}
|
||||
|
||||
/* The +incdir token introduces a list of +<path> arguments that are
|
||||
the include directories to search. */
|
||||
|
||||
| TOK_INCDIR inc_args
|
||||
|
||||
/* The +libext token introduces a list of +<ext> arguments that
|
||||
become individual -Y flags to ivl. */
|
||||
|
||||
| TOK_LIBEXT libext_args
|
||||
|
||||
/* The +<word> tokens that are not otherwise matched, are
|
||||
ignored. The skip_args rule arranges for all the argument words
|
||||
to be consumed. */
|
||||
|
||||
| TOK_PLUSWORD skip_args
|
||||
{ fprintf(stderr, "%s:%u: Ignoring %s\n",
|
||||
@1.text, @1.first_line, $1);
|
||||
free($1);
|
||||
}
|
||||
| TOK_PLUSWORD
|
||||
{ if (strcmp($1, "+toupper-filenames") == 0) {
|
||||
setcase_filename_flag = 1;
|
||||
} else if (strcmp($1, "+tolower-filenames") == 0) {
|
||||
setcase_filename_flag = 2;
|
||||
} else {
|
||||
fprintf(stderr, "%s:%u: Ignoring %s\n",
|
||||
@1.text, @1.first_line, $1);
|
||||
}
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
/* inc_args are +incdir+ arguments in order. */
|
||||
inc_args
|
||||
: inc_args inc_arg
|
||||
| inc_arg
|
||||
;
|
||||
|
||||
inc_arg : TOK_PLUSARG
|
||||
{ char*tmp = substitutions($1);
|
||||
process_include_dir(tmp);
|
||||
free($1);
|
||||
free(tmp);
|
||||
}
|
||||
;
|
||||
|
||||
/* inc_args are +incdir+ arguments in order. */
|
||||
libext_args
|
||||
: libext_args libext_arg
|
||||
| libext_arg
|
||||
;
|
||||
|
||||
libext_arg : TOK_PLUSARG
|
||||
{ process_library2_switch($1);
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
/* skip_args are arguments to a +word flag that is not otherwise
|
||||
parsed. This rule matches them and releases the strings, so that
|
||||
they can be safely ignored. */
|
||||
skip_args
|
||||
: skip_args skip_arg
|
||||
| skip_arg
|
||||
;
|
||||
|
||||
skip_arg : TOK_PLUSARG
|
||||
{ free($1);
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
int yyerror(const char*msg)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#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
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cfparse_misc.h,v 1.4 2002/08/12 01:35:01 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The vlltype supports the passing of detailed source file location
|
||||
* information between the lexical analyzer and the parser. Defining
|
||||
* YYLTYPE compels the lexor to use this type and not something other.
|
||||
*/
|
||||
struct cfltype {
|
||||
unsigned first_line;
|
||||
unsigned first_column;
|
||||
unsigned last_line;
|
||||
unsigned last_column;
|
||||
const char*text;
|
||||
};
|
||||
# define YYLTYPE struct cfltype
|
||||
extern YYLTYPE yylloc;
|
||||
|
||||
/*
|
||||
* $Log: cfparse_misc.h,v $
|
||||
* Revision 1.4 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/01/02 02:39:34 steve
|
||||
* Use my own cfltype to defend against bison 1.30.
|
||||
*
|
||||
* Revision 1.2 2001/11/12 18:47:32 steve
|
||||
* Support +incdir in command files, and ignore other
|
||||
* +args flags. Also ignore -a and -v flags.
|
||||
*
|
||||
* Revision 1.1 2001/11/12 01:26:36 steve
|
||||
* More sophisticated command file parser.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+81
-4
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: globals.h,v 1.3 2000/11/09 21:58:00 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: globals.h,v 1.16 2002/08/12 01:35:01 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stddef.h>
|
||||
@@ -27,6 +27,9 @@
|
||||
/* This is the base (i.e. -B<value>) of the Icarus Verilog files. */
|
||||
extern const char*base;
|
||||
|
||||
/* This is the path to the iconfig file sent to ivl. */
|
||||
extern char* iconfig_path;
|
||||
|
||||
/* This is a list of all the -f<key>=<value> options from the
|
||||
command line, concatenated together. */
|
||||
extern char*f_list;
|
||||
@@ -36,14 +39,17 @@ extern char*mod_list;
|
||||
/* This is the optional -Tmin|typ|max setting. */
|
||||
extern const char*mtm;
|
||||
|
||||
/* Ths is the optional -M<dependfile> value, if one was supplied. */
|
||||
extern const char*depfile;
|
||||
|
||||
/* Ths is the optional -N<path> value, if one was supplied. */
|
||||
extern const char*npath;
|
||||
|
||||
/* 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 +57,85 @@ extern int synth_flag;
|
||||
/* This is the name of the selected target. */
|
||||
extern const char*targ;
|
||||
|
||||
/* This is the language generation flag. */
|
||||
extern const char*generation;
|
||||
|
||||
/* Perform variable substitutions on the string. */
|
||||
extern char* substitutions(const char*str);
|
||||
|
||||
/* Add the name to the list of source files. */
|
||||
extern void process_file_name(const char*name);
|
||||
|
||||
/* Add the name to the list of library directories. */
|
||||
extern void process_library_switch(const char*name);
|
||||
extern void process_library_nocase_switch(const char*name);
|
||||
extern void process_library2_switch(const char*name);
|
||||
|
||||
/* Add a new include file search directory */
|
||||
extern void process_include_dir(const char*name);
|
||||
|
||||
/* Add a new -D define. */
|
||||
extern void process_define(const char*name);
|
||||
|
||||
/* -v */
|
||||
extern int verbose_flag;
|
||||
|
||||
extern char warning_flags[];
|
||||
|
||||
/* -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.16 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.15 2002/06/23 20:10:51 steve
|
||||
* Variable substitution in command files.
|
||||
*
|
||||
* Revision 1.14 2002/05/28 20:40:37 steve
|
||||
* ivl indexes the search path for libraries, and
|
||||
* supports case insensitive module-to-file lookup.
|
||||
*
|
||||
* Revision 1.13 2002/05/28 00:50:40 steve
|
||||
* Add the ivl -C flag for bulk configuration
|
||||
* from the driver, and use that to run library
|
||||
* modules through the preprocessor.
|
||||
*
|
||||
* Revision 1.12 2002/05/24 01:13:00 steve
|
||||
* Support language generation flag -g.
|
||||
*
|
||||
* Revision 1.11 2002/04/04 05:26:13 steve
|
||||
* Add dependency generation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
|
||||
+169
-32
@@ -1,17 +1,19 @@
|
||||
.TH iverilog 1 "$Date: 2001/01/05 05:16:03 $" Version "$Date: 2001/01/05 05:16:03 $"
|
||||
.TH iverilog 1 "$Date: 2002/06/23 20:10:51 $" Version "$Date: 2002/06/23 20:10:51 $"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-fflag=value] [-Iincludepath] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] sourcefile
|
||||
[-ESVv] [-Cpath] [-ccmdfile] [-g1|-g2|-g3.0] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
|
||||
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fIiverilog\fP is a compiler that translates Verilog source code into
|
||||
executable programs for simulation, or other netlist formats for
|
||||
further processing. The currenty supported targets are \fIvvm\fP (for
|
||||
executable simulation) and \fIxnf\fP for synthesis. Other target
|
||||
further processing. The currently supported targets are \fIvvp\fP for
|
||||
simulation, and \fIxnf\fP and \fIfpga\fP for synthesis. Other target
|
||||
types are added as code generators are implemented.
|
||||
|
||||
.SH OPTIONS
|
||||
@@ -20,7 +22,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 +31,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,24 +53,34 @@ Defines macro \fImacro\fP as \fIdefn\fP.
|
||||
Preprocess the Verilog source, but do not compile it. The output file
|
||||
is the Verilog input, but with file inclusions and macro references
|
||||
expanded and removed. This is useful, for example, to preprocess
|
||||
verilog source for use by other compilers.
|
||||
Verilog source for use by other compilers.
|
||||
.TP 8
|
||||
.B -f\fIflag=value\fP
|
||||
Assign a value to a target specific flag. The \fB-f\fP switch may be
|
||||
used as often as necessary to specify all the desired flags. The flags
|
||||
that are used depend on the target that is selected, and are described
|
||||
in target specific documentation. Flags that are not used are ignored.
|
||||
.B -g1\fI|\fP-g2\fI|\fP-g3.0
|
||||
Select the Verilog language \fIgeneration\fP to support in the
|
||||
compiler. This selects between \fIIEEE1364-1995\fP(1),
|
||||
\fIIEEE1364-2001\fP(2), or \fISystemVerilog 3.0\fP(3.0). Normally,
|
||||
Icarus Verilog defaults to the latest known generation of the
|
||||
language. This flag is most useful to restrict the language to a set
|
||||
supported by tools of specific generations, for compatibility with
|
||||
other tools.
|
||||
.TP 8
|
||||
.B -I\fIincludedir\fP
|
||||
Append directory \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.
|
||||
.TP 8
|
||||
.B -M\fIpath\fP
|
||||
Write into the file specified by path a list of files that contribute
|
||||
to the compilation of the design. This includes files that are
|
||||
included by include directives and files that are automatically loaded
|
||||
by library support. The output is one file name per line, with no
|
||||
leading or trailing space.
|
||||
.TP 8
|
||||
.B -m\fImodule\fP
|
||||
Add this module to the list of VPI modules to be loaded by the
|
||||
simulation. Many modules can be specified, and all will be loaded, in
|
||||
the order specified.
|
||||
the order specified. The system module is implicit and always included.
|
||||
.TP 8
|
||||
.B -N\fIpath\fP
|
||||
This is used for debugging the compiler proper. Dump the final netlist
|
||||
@@ -82,6 +92,12 @@ elaborated and optimized.
|
||||
Place output in the file \fIfilename\fP. If no output file name is
|
||||
specified, \fIiverilog\fP uses the default name \fBa.out\fP.
|
||||
.TP 8
|
||||
.B -p\fIflag=value\fP
|
||||
Assign a value to a target specific flag. The \fB-p\fP switch may be
|
||||
used as often as necessary to specify all the desired flags. The flags
|
||||
that are used depend on the target that is selected, and are described
|
||||
in target specific documentation. Flags that are not used are ignored.
|
||||
.TP 8
|
||||
.B -S
|
||||
Synthesize. Normally, if the target can accept behavioral
|
||||
descriptions the compiler will leave processes in behavioral
|
||||
@@ -91,9 +107,10 @@ netlist format, the \fB-S\fP switch is unnecessary and has no effect.
|
||||
.TP 8
|
||||
.B -s \fItopmodule\fP
|
||||
Specify the top level module to elaborate. Icarus Verilog will by default
|
||||
choose the only module that has no ports. However, this simplistic
|
||||
heuristic is often not sufficient, and sometimes not what is wanted
|
||||
anyhow.
|
||||
choose modules that are not instantiated in any other modules, but
|
||||
sometimes that is not sufficient, or instantiates too many modules. If
|
||||
the user specifies one or more root modules with \fB-s\fP flags, then
|
||||
they will be used as root modules instead.
|
||||
.TP 8
|
||||
.B -T\fImin|typ|max\fP
|
||||
Use this switch to select min, typ or max times from min:typ:max
|
||||
@@ -109,13 +126,36 @@ Use this switch to specify the target output format. See the
|
||||
.B -v
|
||||
Turn on verbose messages. This will print the command lines that are
|
||||
executed to perform the actual compilation, along with version
|
||||
information from the various components.
|
||||
information from the various components, as well as the version of the
|
||||
product as a whole.
|
||||
.TP 8
|
||||
.B -V
|
||||
Print the version of the compiler, and exit.
|
||||
.TP 8
|
||||
.B -W\fIclass\fP
|
||||
Turn on different classes of warnings. See the \fBWARNING TYPES\fP
|
||||
section below for desctriptions of the different warning groups. If
|
||||
section below for descriptions of the different warning groups. If
|
||||
multiple \fB-W\fP switches are used, the warning set is the union of
|
||||
all the requested classes.
|
||||
.TP 8
|
||||
.B -y\fIlibdir\fP
|
||||
Append the directory to the library module search path. When the
|
||||
compiler finds an undefined module, it looks in these directories for
|
||||
files with the right name.
|
||||
|
||||
.SH MODULE LIBRARIES
|
||||
|
||||
The Icarus Verilog compiler supports module libraries as directories
|
||||
that contain Verilog source files. During elaboration, the compiler
|
||||
notices the instantiation of undefined module types. If the user
|
||||
specifies library search directories, the compiler will search the
|
||||
directory for files with the name of the missing module type. If it
|
||||
finds such a file, it loads it as a Verilog source file, they tries
|
||||
again to elaborate the module.
|
||||
|
||||
Library module files should contain only a single module, but this is
|
||||
not a requirement. Library modules may reference other modules in the
|
||||
library or in the main design.
|
||||
|
||||
.SH TARGETS
|
||||
|
||||
@@ -128,20 +168,27 @@ desired target.
|
||||
The null target causes no code to be generated. It is useful for
|
||||
checking the syntax of the Verilog source.
|
||||
.TP 8
|
||||
.B vvm
|
||||
This is the default. The target is an executable program that uses the
|
||||
vvm simulation runtime. The compiler actually generates C++ code, then
|
||||
compiles and links that code to make the output executable.
|
||||
.B vvp
|
||||
This is the default. The vvp target generates code for the vvp
|
||||
runtime. The output is a complete program that simulates the design
|
||||
but must be run by the \fBvvp\fP command.
|
||||
.TP 8
|
||||
.B xnf
|
||||
This is the Xilinx Netlist Format used by many tools for placing
|
||||
devices in FPGAs or other programmable devices. The Icarus Verilog XNF
|
||||
code generator can generate complete designs or XNF macros that can be
|
||||
imported into larger designs by other tools.
|
||||
imported into larger designs by other tools. (This target is obsolete,
|
||||
use the \fBfpga\fP target instead.)
|
||||
.TP 8
|
||||
.B fpga
|
||||
This is a synthesis target that supports a variety of fpga devices,
|
||||
mostly by EDIF format output.
|
||||
|
||||
.SH "WARNING TYPES"
|
||||
These are the types of warnings that can be selected by the \fB-W\fP
|
||||
switch.
|
||||
switch. All the warning types (other then \fBall\fP) can also be
|
||||
prefixed with \fBno-\fP to turn off that warning. This is most useful
|
||||
after a \fB-Wall\fP argument to suppress isolated warning types.
|
||||
|
||||
.TP 8
|
||||
.B all
|
||||
@@ -150,24 +197,113 @@ 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.
|
||||
|
||||
.TP 8
|
||||
.B timescale
|
||||
This enables warnings for inconsistent use of the timescale
|
||||
directive. It detects if some modules have no timescale, or if modules
|
||||
inherit timescale from another file. Both probably mean that
|
||||
timescales are inconsistent, and simulation timing can be confusing
|
||||
and dependent on compilation order.
|
||||
|
||||
.SH "COMMAND FILES"
|
||||
The command file allows the user to place source file names and
|
||||
certain command line switches into a text file instead of on a long
|
||||
command line. Command files can include C or C++ style comments, as
|
||||
well as # comments, if the # starts the line.
|
||||
|
||||
.TP 8
|
||||
.I "file name"
|
||||
A simple file name or file path is taken to be the name of a Verilog
|
||||
source file. The path starts with the first non-white-space
|
||||
character. Variables are substitued in file names.
|
||||
|
||||
.TP 8
|
||||
.B -y\ \fIlibdir\fP
|
||||
A \fB-y\fP token prefixes a library directory in the command file,
|
||||
exactly like it does on the command line. The parameter to the \fB-y\fP
|
||||
flag may be on the same line or the next non-comment line.
|
||||
|
||||
Variables in the \fIlibdir\fP are substituted.
|
||||
|
||||
.TP 8
|
||||
.B +incdir+\fIincludedir\fP
|
||||
The \fB+incdir+\fP token in command files gives directories to search
|
||||
for include files in much the same way that \fB-I\fP flags work on the
|
||||
command line. The difference is that multiple \fI+includedir\fP
|
||||
directories are valid parameters to a single \fB+incdir+\fP token,
|
||||
although you may also have multiple \fB+incdir+\fP lines.
|
||||
|
||||
Variables in the \fIincludedir\fP are substituted.
|
||||
|
||||
.TP 8
|
||||
.B +libext+\fIext\fP
|
||||
The \fB+libext\fP token in command files fives file extensions to try
|
||||
when looking for a library file. This is useful in conjunction with
|
||||
\fB-y\fP flags to list suffixes to try in each directory before moving
|
||||
on to the next library directory.
|
||||
|
||||
.TP 8
|
||||
.B +libdir+\fIdir\fP
|
||||
This is another way to specify library directories. See the -y flag.
|
||||
|
||||
.TP 8
|
||||
.B +libdir-nocase+\fIdir\fP
|
||||
This is like the \fB+libdir\fP statement, but file names inside the
|
||||
directories declared here are case insensitive. The missing module
|
||||
name in a lookup need not match the file name case, as long as the
|
||||
letters are correct. For example, "foo" matches "Foo.v" but not
|
||||
"bar.v".
|
||||
|
||||
.TP 8
|
||||
.B +define+\fINAME\fP=\fIvalue\fP
|
||||
The \fB+define+\fP token is the same as the \fB-D\fP option on the
|
||||
command line. The value part of the token is optional.
|
||||
|
||||
.TP 8
|
||||
.B +toupper-filename\fP
|
||||
This token causes file names after this in the command file to be
|
||||
translated to uppercase. This helps with situations where a directory
|
||||
has passed through a DOS machine, and in the process the file names
|
||||
become munged.
|
||||
|
||||
.TP 8
|
||||
.B +tolower-filename\fP
|
||||
This is similar to the \fB+toupper-filename\fP hack described above.
|
||||
|
||||
.SH "VARIABLES IN COMMAND FILES"
|
||||
|
||||
In certain cases, iverilog supports variables in command files. These
|
||||
are strings of the form "$(\fIvarname\fP)", where \fIvarname\fP is the
|
||||
name of the environment variable to read. The entire string is
|
||||
replaced with the contents of that variable. Variables are only
|
||||
substitued in contexts that explicitly support them, including file
|
||||
and directory strings.
|
||||
|
||||
Variable values come from the operating system environment, and not
|
||||
from preprocessor defines elsewhere in the file or the command line.
|
||||
|
||||
.SH EXAMPLES
|
||||
These examples assume that you have a Verilog source file called hello.v in
|
||||
the current directory
|
||||
|
||||
To compile hello.v to an executable file called a.out:
|
||||
|
||||
verilog hello.v
|
||||
iverilog hello.v
|
||||
|
||||
To compile hello.v to an executable file called hello:
|
||||
|
||||
verilog -o hello hello.v
|
||||
iverilog -o hello hello.v
|
||||
|
||||
To compile and run explicitly using the vvp runtime:
|
||||
|
||||
iverilog -ohello.vvp -tvvp hello.v
|
||||
|
||||
To compile hello.v to a file in XNF-format called hello.xnf
|
||||
|
||||
verilog -txnf -ohello.xnf hello.v
|
||||
iverilog -txnf -ohello.xnf hello.v
|
||||
|
||||
|
||||
.SH "AUTHOR"
|
||||
@@ -175,11 +311,12 @@ To compile hello.v to a file in XNF-format called hello.xnf
|
||||
Steve Williams ([email protected])
|
||||
|
||||
.SH SEE ALSO
|
||||
vvp(1),
|
||||
.BR "<http://www.icarus.com/eda/verilog/>"
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2000 Stephen Williams
|
||||
Copyright \(co 2002 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
||||
+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"
|
||||
|
||||
|
||||
+496
-242
@@ -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,18 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: main.c,v 1.5 2000/11/30 02:50:54 steve Exp $"
|
||||
#endif
|
||||
#ident "$Id: main.c,v 1.47 2002/08/12 01:27:48 steve Exp $"
|
||||
|
||||
# include "config.h"
|
||||
|
||||
|
||||
const char HELP[] =
|
||||
"Usage: iverilog [-ESv] [-c <path>] [-Dmacro[=defn]]
|
||||
[-f 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 [-ESvV] [-B base] [-C path] [-c cmdfile] [-g1|-g2|-g3.0]\n"
|
||||
" [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
|
||||
" [-N file] [-o filename] [-p flag=value]\n"
|
||||
" [-s topmodule] [-t target] [-T min|typ|max]\n"
|
||||
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
|
||||
"See man page for details.";
|
||||
|
||||
#define MAXSIZE 4096
|
||||
|
||||
@@ -36,28 +38,55 @@ 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>
|
||||
#include <libiberty.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
|
||||
|
||||
#ifndef RDYNAMIC
|
||||
# define RDYNAMIC "-rdynamic"
|
||||
#endif
|
||||
|
||||
# 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*npath = 0;
|
||||
const char*targ = "vvm";
|
||||
const char*start = 0;
|
||||
const char*targ = "vvp";
|
||||
const char*depfile = 0;
|
||||
|
||||
const char*generation = "-g3.0";
|
||||
|
||||
char warning_flags[16] = "";
|
||||
|
||||
@@ -65,19 +94,68 @@ 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;
|
||||
|
||||
char*iconfig_path = 0;
|
||||
FILE*iconfig_file = 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];
|
||||
|
||||
static const char*my_tempfile(const char*str, FILE**fout)
|
||||
{
|
||||
FILE*file;
|
||||
int retry;
|
||||
|
||||
static char pathbuf[8192];
|
||||
|
||||
const char*tmpdir = getenv("TMP");
|
||||
if (tmpdir == 0)
|
||||
tmpdir = getenv("TMPDIR");
|
||||
if (tmpdir == 0)
|
||||
tmpdir = getenv("TEMP");
|
||||
#ifdef __MINGW32__
|
||||
if (tmpdir == 0)
|
||||
tmpdir = "C:\\TEMP";
|
||||
#else
|
||||
if (tmpdir == 0)
|
||||
tmpdir = "/tmp";
|
||||
#endif
|
||||
|
||||
assert(tmpdir);
|
||||
assert((strlen(tmpdir) + strlen(str)) < sizeof pathbuf - 10);
|
||||
|
||||
srand(getpid());
|
||||
retry = 100;
|
||||
file = NULL;
|
||||
while ((retry > 0) && (file == NULL)) {
|
||||
unsigned code = rand();
|
||||
sprintf(pathbuf, "%s%c%s%04x", tmpdir, sep, str, code);
|
||||
file = fopen(pathbuf, "w");
|
||||
retry -= 1;
|
||||
}
|
||||
|
||||
*fout = file;
|
||||
return pathbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the default target type. It looks up the bits that are
|
||||
* needed to run the command from the configuration file (which is
|
||||
@@ -99,6 +177,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 +195,14 @@ static int t_default(char*cmd, unsigned ncmd)
|
||||
|
||||
|
||||
rc = system(cmd);
|
||||
remove(source_path);
|
||||
remove(iconfig_path);
|
||||
if (rc != 0) {
|
||||
if (rc == 127) {
|
||||
fprintf(stderr, "Failed to execute: %s\n", cmd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (WIFEXITED(rc))
|
||||
return WEXITSTATUS(rc);
|
||||
|
||||
@@ -118,130 +213,6 @@ static int t_default(char*cmd, unsigned ncmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the vvm target. After preprocessing, run the
|
||||
* ivl translator to get C++, then run g++ to make an executable
|
||||
* program out of that.
|
||||
*/
|
||||
static int t_vvm(char*cmd, unsigned ncmd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
const char*pattern = lookup_pattern("<ivl>");
|
||||
if (pattern == 0) {
|
||||
fprintf(stderr, "No such target: %s\n", targ);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmp[0] = ' ';
|
||||
tmp[1] = '|';
|
||||
tmp[2] = ' ';
|
||||
rc = build_string(tmp+3, sizeof tmp - 3, pattern);
|
||||
cmd = realloc(cmd, ncmd+3+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
|
||||
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);
|
||||
} else {
|
||||
fprintf(stderr, "Command signaled: %s\n", cmd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(tmp, "%s -O " RDYNAMIC " -fno-exceptions -o %s -I%s "
|
||||
"-L%s %s.cc -lvvm -lvpip %s", CXX, opath, IVL_INC, IVL_LIB,
|
||||
opath, DLLIB);
|
||||
|
||||
if (verbose_flag)
|
||||
printf("compile: %s\n", tmp);
|
||||
|
||||
rc = system(tmp);
|
||||
if (rc != 0) {
|
||||
if (WIFEXITED(rc)) {
|
||||
fprintf(stderr, "errors compiling translated program.\n");
|
||||
return WEXITSTATUS(rc);
|
||||
} else {
|
||||
fprintf(stderr, "Command signaled: %s\n", tmp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(tmp, "%s.cc", opath);
|
||||
unlink(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static 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)
|
||||
{
|
||||
@@ -249,24 +220,175 @@ static void process_warning_switch(const char*name)
|
||||
strcpy(warning_flags, "-W");
|
||||
|
||||
if (strcmp(name,"all") == 0) {
|
||||
strcat(warning_flags, "i");
|
||||
strcat(warning_flags, "it");
|
||||
|
||||
} else if (strcmp(name,"implicit") == 0) {
|
||||
if (! strchr(warning_flags+2, 'i'))
|
||||
strcat(warning_flags, "i");
|
||||
} else if (strcmp(name,"timescale") == 0) {
|
||||
if (! strchr(warning_flags+2, 't'))
|
||||
strcat(warning_flags, "t");
|
||||
} else if (strcmp(name,"no-implicit") == 0) {
|
||||
char*cp = strchr(warning_flags+2, 'i');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-timescale") == 0) {
|
||||
char*cp = strchr(warning_flags+2, 't');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void process_library_switch(const char *name)
|
||||
{
|
||||
fprintf(iconfig_file, "-y:%s\n", name);
|
||||
}
|
||||
|
||||
void process_library_nocase_switch(const char *name)
|
||||
{
|
||||
fprintf(iconfig_file, "-yl:%s\n", name);
|
||||
}
|
||||
|
||||
void process_library2_switch(const char *name)
|
||||
{
|
||||
fprintf(iconfig_file, "-Y:%s\n", 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 process_generation(const char*name)
|
||||
{
|
||||
if (strcmp(name,"1") == 0)
|
||||
generation = "-g1";
|
||||
|
||||
else if (strcmp(name,"2") == 0)
|
||||
generation = "-g2";
|
||||
|
||||
else if (strcmp(name,"3.0") == 0)
|
||||
generation = "-g3.0";
|
||||
|
||||
else {
|
||||
fprintf(stderr, "Unknown/Unsupported Language generation "
|
||||
"%s\n", name);
|
||||
fprintf(stderr, "Supported generations are:\n");
|
||||
fprintf(stderr, " 1 -- IEEE1364-1995 (Verilog 1)\n"
|
||||
" 2 -- IEEE1364-2001 (Verilog 2001)\n"
|
||||
" 3.0 -- SystemVerilog 3.0\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char*config_path = 0;
|
||||
char*cmd;
|
||||
unsigned ncmd;
|
||||
int e_flag = 0;
|
||||
int opt, idx;
|
||||
int version_flag = 0;
|
||||
int opt, idx, rc;
|
||||
char*cp;
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o: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
|
||||
|
||||
/* Create a temporary file for communicating input parameters
|
||||
to the preprocessor. */
|
||||
source_path = strdup(my_tempfile("ivrlg", &source_file));
|
||||
if (NULL == source_file) {
|
||||
fprintf(stderr, "%s: Error opening temporary file %s\n",
|
||||
argv[0], source_path);
|
||||
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create another temporary file for passing configuration
|
||||
information to ivl. */
|
||||
iconfig_path = strdup(my_tempfile("ivrlh", &iconfig_file));
|
||||
if (NULL == iconfig_file) {
|
||||
fprintf(stderr, "%s: Error opening temporary file %s\n",
|
||||
argv[0], iconfig_path);
|
||||
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
|
||||
fclose(source_file);
|
||||
remove(source_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:g:hI:M:m:N::o:p:Ss:T:t:vVW:y:Y:")) != EOF) {
|
||||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
@@ -277,55 +399,47 @@ 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;
|
||||
break;
|
||||
case 'f':
|
||||
fprintf(stderr, "warning: The -f flag is moved to -p\n");
|
||||
case 'p':
|
||||
if (f_list == 0) {
|
||||
f_list = malloc(strlen(" -f")+strlen(optarg)+1);
|
||||
strcpy(f_list, " -f");
|
||||
f_list = malloc(strlen(" -p")+strlen(optarg)+1);
|
||||
strcpy(f_list, " -p");
|
||||
strcat(f_list, optarg);
|
||||
} else {
|
||||
f_list = realloc(f_list, strlen(f_list) +
|
||||
strlen(" -f") +
|
||||
strlen(" -p") +
|
||||
strlen(optarg) + 1);
|
||||
strcat(f_list, " -f");
|
||||
strcat(f_list, " -p");
|
||||
strcat(f_list, optarg);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
rc = process_generation(optarg);
|
||||
if (rc != 0)
|
||||
return -1;
|
||||
break;
|
||||
case 'h':
|
||||
fprintf(stderr, "%s\n", HELP);
|
||||
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':
|
||||
depfile = optarg;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (mod_list == 0) {
|
||||
mod_list = malloc(strlen(" -m")+strlen(optarg)+1);
|
||||
@@ -352,7 +466,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) {
|
||||
@@ -373,16 +498,61 @@ int main(int argc, char **argv)
|
||||
case 'v':
|
||||
verbose_flag = 1;
|
||||
break;
|
||||
case 'V':
|
||||
version_flag = 1;
|
||||
break;
|
||||
case 'W':
|
||||
process_warning_switch(optarg);
|
||||
break;
|
||||
case 'y':
|
||||
process_library_switch(optarg);
|
||||
break;
|
||||
case 'Y':
|
||||
process_library2_switch(optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((optind == argc) && !command_filename) {
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION "\n");
|
||||
printf("Copyright 1998-2002 Stephen Williams\n");
|
||||
printf("$Name: $\n");
|
||||
|
||||
if (version_flag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -396,18 +566,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 -D__ICARUS__=1 -f%s ", base,sep,
|
||||
verbose_flag?" -v":"",
|
||||
e_flag?"":" -L");
|
||||
e_flag?"":" -L", source_path);
|
||||
|
||||
ncmd = strlen(tmp);
|
||||
cmd = malloc(ncmd + 1);
|
||||
@@ -425,55 +599,11 @@ 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 (depfile) {
|
||||
cmd = realloc(cmd, ncmd + strlen(depfile) + 5);
|
||||
strcat(cmd, " -M ");
|
||||
strcat(cmd, depfile);
|
||||
ncmd += strlen(depfile) + 4;
|
||||
}
|
||||
|
||||
/* If the -E flag was given on the command line, then all we
|
||||
@@ -492,6 +622,10 @@ int main(int argc, char **argv)
|
||||
printf("preprocess: %s\n", cmd);
|
||||
|
||||
rc = system(cmd);
|
||||
remove(source_path);
|
||||
fclose(iconfig_file);
|
||||
remove(iconfig_path);
|
||||
|
||||
if (rc != 0) {
|
||||
if (WIFEXITED(rc)) {
|
||||
fprintf(stderr, "errors preprocessing Verilog program.\n");
|
||||
@@ -505,33 +639,153 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
/* Write the preprocessor command needed to preprocess a
|
||||
single file. This may be used to preprocess library
|
||||
files. */
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp -D__ICARUS__ -L %s %s\n",
|
||||
base, sep,
|
||||
inc_list? inc_list : "",
|
||||
def_list? def_list : "");
|
||||
|
||||
/* Done writing to the iconfig file. Close it now. */
|
||||
fclose(iconfig_file);
|
||||
|
||||
return t_default(cmd, ncmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: main.c,v $
|
||||
* Revision 1.5 2000/11/30 02:50:54 steve
|
||||
* Add command file (-c) support from Nadim Shaikli.
|
||||
* Revision 1.47 2002/08/12 01:27:48 steve
|
||||
* Escape the backslash in the windows file name.
|
||||
*
|
||||
* Revision 1.4 2000/10/28 17:28:16 steve
|
||||
* Split vpip for everybody.
|
||||
* Revision 1.46 2002/08/10 22:36:59 steve
|
||||
* No longer any nead for -rdynamic flag
|
||||
*
|
||||
* Revision 1.3 2000/10/28 03:47:25 steve
|
||||
* Use the conf file to generate the vvm ivl string.
|
||||
* Revision 1.45 2002/08/10 22:27:13 steve
|
||||
* Kill links to vvm.
|
||||
*
|
||||
* Revision 1.2 2000/10/28 03:45:47 steve
|
||||
* Use the conf file to generate the vvm ivl string.
|
||||
* Revision 1.44 2002/07/15 00:33:50 steve
|
||||
* Improve temporary file name guess.
|
||||
*
|
||||
* Revision 1.1 2000/10/08 22:36:56 steve
|
||||
* iverilog with an iverilog.conf configuration file.
|
||||
* Revision 1.43 2002/07/14 23:32:31 steve
|
||||
* No longer need the .exe on generated files.
|
||||
*
|
||||
* Revision 1.42 2002/07/14 23:11:35 steve
|
||||
* Do temp file creation by hand.
|
||||
*
|
||||
* Revision 1.41 2002/05/28 20:40:37 steve
|
||||
* ivl indexes the search path for libraries, and
|
||||
* supports case insensitive module-to-file lookup.
|
||||
*
|
||||
* Revision 1.40 2002/05/28 02:25:03 steve
|
||||
* Pass library paths through -Cfile instead of command line.
|
||||
*
|
||||
* Revision 1.39 2002/05/28 00:50:40 steve
|
||||
* Add the ivl -C flag for bulk configuration
|
||||
* from the driver, and use that to run library
|
||||
* modules through the preprocessor.
|
||||
*
|
||||
* Revision 1.38 2002/05/27 23:14:06 steve
|
||||
* Predefine __ICARUS__
|
||||
*
|
||||
* Revision 1.37 2002/05/24 01:13:00 steve
|
||||
* Support language generation flag -g.
|
||||
*
|
||||
* Revision 1.36 2002/04/24 02:02:31 steve
|
||||
* add -Wno- arguments to the driver.
|
||||
*
|
||||
* Revision 1.35 2002/04/15 00:04:23 steve
|
||||
* Timescale warnings.
|
||||
*
|
||||
* Revision 1.34 2002/04/04 05:26:13 steve
|
||||
* Add dependency generation.
|
||||
*
|
||||
* Revision 1.33 2002/03/15 23:27:42 steve
|
||||
* Patch to allow user to set place for temporary files.
|
||||
*
|
||||
* Revision 1.32 2002/02/03 07:05:37 steve
|
||||
* Support print of version number.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
+7
-2
@@ -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.5 2002/03/31 04:07:16 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <stdio.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <stdlib.h>
|
||||
# include "globals.h"
|
||||
|
||||
|
||||
@@ -127,7 +132,7 @@ const char*lookup_pattern(const char*key)
|
||||
|
||||
%%
|
||||
|
||||
start: section_list
|
||||
start: section_list ;
|
||||
|
||||
section_list
|
||||
: section
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: substit.c,v 1.4 2002/08/12 01:35:01 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
char* substitutions(const char*str)
|
||||
{
|
||||
size_t nbuf = strlen(str) + 1;
|
||||
char*buf = malloc(nbuf);
|
||||
char*cp = buf;
|
||||
|
||||
while (*str) {
|
||||
|
||||
if ((str[0] == '$') && (str[1] == '(')) {
|
||||
/* If I find a $(x) string in the source, replace
|
||||
it in the destination with the contents of the
|
||||
environment variable x. */
|
||||
char*name;
|
||||
char*value;
|
||||
const char*ep = strchr(str, ')');
|
||||
str += 2;
|
||||
|
||||
name = malloc(ep-str+1);
|
||||
strncpy(name, str, ep-str);
|
||||
name[ep-str] = 0;
|
||||
|
||||
str = ep + 1;
|
||||
|
||||
value = getenv(name);
|
||||
free(name);
|
||||
if (value == 0)
|
||||
continue;
|
||||
|
||||
if (strlen(value) >= (nbuf - (cp-buf))) {
|
||||
size_t old_size = cp - buf;
|
||||
nbuf = (cp - buf) + strlen(value) + 1;
|
||||
buf = realloc(buf, nbuf);
|
||||
cp = buf + old_size;
|
||||
}
|
||||
|
||||
strcpy(cp, value);
|
||||
cp += strlen(cp);
|
||||
|
||||
} else {
|
||||
if ( (cp - buf) == nbuf ) {
|
||||
size_t old_size = nbuf;
|
||||
nbuf = old_size + 32;
|
||||
buf = realloc(buf, nbuf);
|
||||
cp = buf + old_size;
|
||||
}
|
||||
|
||||
*cp++ = *str++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the trailing nul to the string, and reallocate the
|
||||
buffer to be a tight fit. */
|
||||
if ( (cp - buf) == nbuf ) {
|
||||
size_t old_size = nbuf;
|
||||
nbuf = old_size + 1;
|
||||
buf = realloc(buf, nbuf);
|
||||
buf[old_size] = 0;
|
||||
} else {
|
||||
*cp++ = 0;
|
||||
nbuf = cp - buf;
|
||||
buf = realloc(buf, nbuf);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: substit.c,v $
|
||||
* Revision 1.4 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/08/11 23:47:04 steve
|
||||
* Add missing Log and Ident strings.
|
||||
*
|
||||
* Revision 1.2 2002/06/25 01:33:01 steve
|
||||
* include malloc.h only when available.
|
||||
*
|
||||
* Revision 1.1 2002/06/23 20:10:51 steve
|
||||
* Variable substitution in command files.
|
||||
*
|
||||
*/
|
||||
|
||||
+53
-3
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: dup_expr.cc,v 1.4 2000/05/07 18:20:07 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: dup_expr.cc,v 1.8 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include <cassert>
|
||||
|
||||
@@ -29,17 +31,65 @@ NetEScope* NetEScope::dup_expr() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetESelect* NetESelect::dup_expr() const
|
||||
{
|
||||
return new NetESelect(expr_->dup_expr(), base_->dup_expr(),
|
||||
expr_width());
|
||||
}
|
||||
|
||||
NetESFunc* NetESFunc::dup_expr() const
|
||||
{
|
||||
NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1)
|
||||
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.8 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.7 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.6 2001/11/19 01:54:14 steve
|
||||
* Port close cropping behavior from mcrgb
|
||||
* Move window array reset to libmc.
|
||||
*
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2000/05/07 18:20:07 steve
|
||||
* Import MCD support from Stephen Tell, and add
|
||||
* system function parameter support to the IVL core.
|
||||
|
||||
+19
-6
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_anet.cc,v 1.2 2001/01/06 02:29:36 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_anet.cc,v 1.5 2002/08/12 01:34:58 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,17 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_anet.cc,v $
|
||||
* Revision 1.5 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.4 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.3 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.2 2001/01/06 02:29:36 steve
|
||||
* Support arrays of integers.
|
||||
*
|
||||
|
||||
+459
-160
@@ -16,15 +16,19 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_expr.cc,v 1.33 2001/01/13 22:20:08 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_expr.cc,v 1.66 2002/09/21 21:28:18 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
|
||||
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const
|
||||
{
|
||||
cerr << get_line() << ": internal error: I do not know how to elaborate"
|
||||
<< " expression. " << endl;
|
||||
@@ -39,8 +43,11 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
|
||||
* and right sides, and creating one of a variety of different NetExpr
|
||||
* types.
|
||||
*/
|
||||
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
assert(left_);
|
||||
assert(right_);
|
||||
|
||||
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;
|
||||
@@ -111,7 +120,8 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||
case '^':
|
||||
case '&':
|
||||
case '|':
|
||||
case 'O':
|
||||
case 'O': // NOR (~|)
|
||||
case 'A': // NAND (~&)
|
||||
case 'X':
|
||||
tmp = new NetEBBits(op_, lp, rp);
|
||||
tmp->set_line(*this);
|
||||
@@ -145,49 +155,147 @@ 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
|
||||
{
|
||||
|
||||
/* Catch the special case that the system function is the
|
||||
$signed function. This function is special, in that it does
|
||||
not lead to executable code but takes the single parameter
|
||||
and makes it into a signed expression. No bits are changed,
|
||||
it just changes the interpretation. */
|
||||
if (strcmp(path_.peek_name(0), "$signed") == 0) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $signed() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PExpr*expr = parms_[0];
|
||||
NetExpr*sub = expr->elaborate_expr(des, scope, true);
|
||||
sub->cast_signed(true);
|
||||
return sub;
|
||||
}
|
||||
|
||||
/* Interpret the internal $sizeof system function to return
|
||||
the bit width of the sub-expression. The value of the
|
||||
sub-expression is not used, so the expression itself can be
|
||||
deleted. */
|
||||
if ((strcmp(path_.peek_name(0), "$sizeof") == 0)
|
||||
|| (strcmp(path_.peek_name(0), "$bits") == 0)) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $bits() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(path_.peek_name(0), "$sizeof") == 0)
|
||||
cerr << get_line() << ": warning: $sizeof is deprecated."
|
||||
<< " Use $bits() instead." << endl;
|
||||
|
||||
PExpr*expr = parms_[0];
|
||||
NetExpr*sub = expr->elaborate_expr(des, scope, true);
|
||||
verinum val (sub->expr_width(), 8*sizeof(unsigned));
|
||||
delete sub;
|
||||
|
||||
sub = new NetEConst(val);
|
||||
sub->set_line(*this);
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
unsigned wid = 32;
|
||||
|
||||
if (name_ == "$time")
|
||||
if (strcmp(path_.peek_name(0), "$time") == 0)
|
||||
wid = 64;
|
||||
if (strcmp(path_.peek_name(0), "$stime") == 0)
|
||||
wid = 32;
|
||||
|
||||
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, true);
|
||||
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;
|
||||
}
|
||||
|
||||
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) 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
|
||||
list is correct, but there is the special case of a list of
|
||||
1 nil pointer. This is how the parser tells me of no
|
||||
parameter. In other words, ``func()'' is 1 nil parameter. */
|
||||
if (! check_call_matches_definition_(des, dscope))
|
||||
return 0;
|
||||
|
||||
unsigned parms_count = parms_.count();
|
||||
if ((parms_count == 1) && (parms_[0] == 0))
|
||||
parms_count = 0;
|
||||
|
||||
|
||||
|
||||
svector<NetExpr*> parms (parms_count);
|
||||
|
||||
/* Elaborate the input expressions for the function. This is
|
||||
@@ -195,22 +303,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,39 +344,44 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
unsigned repeat = 1;
|
||||
NetExpr* repeat = 0;
|
||||
|
||||
/* If there is a repeat expression, then evaluate the constant
|
||||
value and set the repeat count. */
|
||||
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;
|
||||
}
|
||||
|
||||
/* Make the empty concat expression. */
|
||||
NetEConcat*tmp = new NetEConcat(parms_.count(), repeat);
|
||||
tmp->set_line(*this);
|
||||
|
||||
unsigned wid_sum = 0;
|
||||
|
||||
/* Elaborate all the parameters and attach them to the concat node. */
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
assert(parms_[idx]);
|
||||
NetExpr*ex = parms_[idx]->elaborate_expr(des, scope);
|
||||
NetExpr*ex = elab_and_eval(des, scope, parms_[idx]);
|
||||
if (ex == 0) continue;
|
||||
|
||||
ex->set_line(*parms_[idx]);
|
||||
@@ -263,27 +393,159 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
wid_sum += ex->expr_width();
|
||||
tmp->set(idx, ex);
|
||||
}
|
||||
|
||||
tmp->set_width(wid_sum * tmp->repeat());
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
assert(text_[0] != '$');
|
||||
long val = value_->as_long();
|
||||
return new NetEConst(verinum(val));
|
||||
}
|
||||
|
||||
//string name = path+"."+text_;
|
||||
/*
|
||||
* Elaborate an identifier in an expression. The identifier can be a
|
||||
* parameter name, a signal name or a memory name. It can also be a
|
||||
* scope name (Return a NetEScope) but only certain callers can use
|
||||
* scope names. However, we still support it here.
|
||||
*
|
||||
* Function names are not handled here, they are detected by the
|
||||
* parser and are elaborated by PECallFunction.
|
||||
*
|
||||
* The signal name may be escaped, but that affects nothing here.
|
||||
*/
|
||||
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||
bool sys_task_arg) const
|
||||
{
|
||||
assert(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_);
|
||||
|
||||
if (msb_ && lsb_) {
|
||||
/* If the parameter has a part select, we support
|
||||
it by pulling the right bits out and making a
|
||||
sized unsigned constant. This code assumes the
|
||||
lsb of a parameter is 0 and the msb is the
|
||||
width of the parameter. */
|
||||
|
||||
verinum*lsn = lsb_->eval_const(des, scope);
|
||||
verinum*msn = msb_->eval_const(des, scope);
|
||||
if ((lsn == 0) || (msn == 0)) {
|
||||
cerr << get_line() << ": error: "
|
||||
"Part select expresions must be "
|
||||
"constant expressions." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long lsb = lsn->as_long();
|
||||
long msb = msn->as_long();
|
||||
if ((lsb < 0) || (msb < lsb)) {
|
||||
cerr << get_line() << ": error: invalid part "
|
||||
<< "select: " << path_
|
||||
<< "["<<msb<<":"<<lsb<<"]" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEConst*le = dynamic_cast<NetEConst*>(tmp);
|
||||
assert(le);
|
||||
|
||||
verinum result (verinum::V0, msb-lsb+1, true);
|
||||
verinum exl = le->value();
|
||||
|
||||
/* Pull the bits from the parameter, one at a
|
||||
time. If the bit is within the range, simply
|
||||
copy it to the result. If the bit is outside
|
||||
the range, we sign extend signed unsized
|
||||
numbers, zero extend unsigned unsigned numbers,
|
||||
and X extend sized numbers. */
|
||||
for (long idx = lsb ; idx <= msb ; idx += 1) {
|
||||
if (idx < exl.len())
|
||||
result.set(idx-lsb, exl.get(idx));
|
||||
else if (exl.is_string())
|
||||
result.set(idx-lsb, verinum::V0);
|
||||
else if (exl.has_len())
|
||||
result.set(idx-lsb, verinum::Vx);
|
||||
else if (exl.has_sign())
|
||||
result.set(idx-lsb, exl.get(exl.len()-1));
|
||||
else
|
||||
result.set(idx-lsb, verinum::V0);
|
||||
}
|
||||
|
||||
/* If the input is a string, and the part select
|
||||
is working on byte boundaries, then the result
|
||||
can be made into a string. */
|
||||
if (exl.is_string()
|
||||
&& (lsb%8 == 0)
|
||||
&& (result.len()%8 == 0))
|
||||
result = verinum(result.as_string());
|
||||
|
||||
delete tmp;
|
||||
tmp = new NetEConst(result);
|
||||
|
||||
} else if (msb_) {
|
||||
/* Handle the case where a parameter has a bit
|
||||
select attached to it. Generate a NetESelect
|
||||
object to select the bit as desired. */
|
||||
NetExpr*mtmp = msb_->elaborate_expr(des, scope);
|
||||
if (! dynamic_cast<NetEConst*>(mtmp)) {
|
||||
NetExpr*re = mtmp->eval_tree();
|
||||
if (re) {
|
||||
delete mtmp;
|
||||
mtmp = re;
|
||||
}
|
||||
}
|
||||
|
||||
/* Let's first try to get constant values for both
|
||||
the parameter and the bit select. If they are
|
||||
both constant, then evaluate the bit select and
|
||||
return instead a single-bit constant. */
|
||||
|
||||
NetEConst*le = dynamic_cast<NetEConst*>(tmp);
|
||||
NetEConst*re = dynamic_cast<NetEConst*>(mtmp);
|
||||
if (le && re) {
|
||||
|
||||
verinum lv = le->value();
|
||||
verinum rv = re->value();
|
||||
verinum::V rb = verinum::Vx;
|
||||
|
||||
long ridx = rv.as_long();
|
||||
if ((ridx >= 0) && (ridx < lv.len())) {
|
||||
rb = lv[ridx];
|
||||
|
||||
} else if ((ridx >= 0) && (!lv.has_len())) {
|
||||
if (lv.has_sign())
|
||||
rb = lv[lv.len()-1];
|
||||
else
|
||||
rb = verinum::V0;
|
||||
}
|
||||
|
||||
NetEConst*re = new NetEConst(verinum(rb, 1));
|
||||
delete tmp;
|
||||
delete mtmp;
|
||||
tmp = re;
|
||||
|
||||
} else {
|
||||
|
||||
NetESelect*stmp = new NetESelect(tmp, mtmp, 1);
|
||||
tmp->set_line(*this);
|
||||
tmp = stmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
@@ -291,7 +553,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
|
||||
@@ -299,8 +561,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 "
|
||||
@@ -353,15 +615,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;
|
||||
@@ -371,23 +627,30 @@ 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);
|
||||
|
||||
if (idx >= net->pin_count()) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "bit " << msv << " out of range of net "
|
||||
/* The bit select is out of range of the
|
||||
vector. This is legal, but returns a
|
||||
constant 1'bx value. */
|
||||
verinum x (verinum::Vx);
|
||||
NetEConst*tmp = new NetEConst(x);
|
||||
tmp->set_line(*this);
|
||||
|
||||
cerr << get_line() << ": warning: Bit select ["
|
||||
<< msv << "] out of range of vector "
|
||||
<< net->name() << "[" << net->msb()
|
||||
<< ":" << net->lsb() << "]." << endl;
|
||||
return 0;
|
||||
cerr << get_line() << ": : Replacing "
|
||||
<< "expression with a constant 1'bx." << endl;
|
||||
delete msn;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -400,7 +663,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;
|
||||
}
|
||||
@@ -414,12 +677,25 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
// If the identifier names a memory, then this is a
|
||||
// memory reference and I must generate a NetEMemory
|
||||
// object to handle it.
|
||||
if (NetMemory*mem = des->find_memory(scope, text_)) {
|
||||
if (NetMemory*mem = des->find_memory(scope, path_)) {
|
||||
if (msb_ == 0) {
|
||||
NetEMemory*node = new NetEMemory(mem);
|
||||
node->set_line(*this);
|
||||
return node;
|
||||
|
||||
// If this memory is an argument to a system task,
|
||||
// then it is OK for it to not have an index.
|
||||
if (sys_task_arg) {
|
||||
NetEMemory*node = new NetEMemory(mem);
|
||||
node->set_line(*this);
|
||||
return node;
|
||||
}
|
||||
|
||||
// If it is not a simple system task argument,
|
||||
// this a missing index is an error.
|
||||
cerr << get_line() << ": error: memory " << mem->name()
|
||||
<< " needs an index in this context." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(msb_ != 0);
|
||||
if (lsb_) {
|
||||
cerr << get_line() << ": error: part select of a memory: "
|
||||
@@ -432,7 +708,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
assert(idx_ == 0);
|
||||
NetExpr*i = msb_->elaborate_expr(des, scope);
|
||||
if (msb_ && i == 0) {
|
||||
cerr << get_line() << ": error: Unable to exaborate "
|
||||
cerr << get_line() << ": error: Unable to elaborate "
|
||||
"index expression `" << *msb_ << "'" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
@@ -443,8 +719,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;
|
||||
@@ -452,12 +740,12 @@ 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;
|
||||
}
|
||||
|
||||
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*) const
|
||||
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, bool) const
|
||||
{
|
||||
assert(value_);
|
||||
NetEConst*tmp = new NetEConst(*value_);
|
||||
@@ -465,7 +753,7 @@ NetEConst* PENumber::elaborate_expr(Design*des, NetScope*) const
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEConst* PEString::elaborate_expr(Design*des, NetScope*) const
|
||||
NetEConst* PEString::elaborate_expr(Design*des, NetScope*, bool) const
|
||||
{
|
||||
NetEConst*tmp = new NetEConst(value());
|
||||
tmp->set_line(*this);
|
||||
@@ -477,7 +765,7 @@ NetEConst* PEString::elaborate_expr(Design*des, NetScope*) const
|
||||
* parsed so I can presume that they exist, and call elaboration
|
||||
* methods. If any elaboration fails, then give up and return 0.
|
||||
*/
|
||||
NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
assert(expr_);
|
||||
assert(tru_);
|
||||
@@ -504,7 +792,7 @@ NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
NetExpr*ip = expr_->elaborate_expr(des, scope);
|
||||
if (ip == 0) return 0;
|
||||
@@ -513,13 +801,69 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
* just like in PEBinary::elaborate_expr() ?
|
||||
*/
|
||||
|
||||
NetEUnary*tmp;
|
||||
NetExpr*tmp;
|
||||
switch (op_) {
|
||||
default:
|
||||
tmp = new NetEUnary(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
if (NetEConst*ipc = dynamic_cast<NetEConst*>(ip)) {
|
||||
verinum val = ipc->value();
|
||||
verinum zero (verinum::V0, val.len(), val.has_len());
|
||||
val = zero - val;
|
||||
val.has_sign(ipc->has_sign());
|
||||
tmp = new NetEConst(val);
|
||||
delete ip;
|
||||
} else {
|
||||
tmp = new NetEUnary(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
}
|
||||
break;
|
||||
|
||||
case '+':
|
||||
tmp = ip;
|
||||
break;
|
||||
|
||||
case '!': // Logical NOT
|
||||
/* If the operand to unary ! is a constant, then I can
|
||||
evaluate this expression here and return a logical
|
||||
constant in its place. */
|
||||
if (NetEConst*ipc = dynamic_cast<NetEConst*>(ip)) {
|
||||
verinum val = ipc->value();
|
||||
unsigned v1 = 0;
|
||||
unsigned vx = 0;
|
||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||
switch (val[idx]) {
|
||||
case verinum::V0:
|
||||
break;
|
||||
case verinum::V1:
|
||||
v1 += 1;
|
||||
break;
|
||||
default:
|
||||
vx += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
verinum::V res;
|
||||
if (v1 > 0)
|
||||
res = verinum::V0;
|
||||
else if (vx > 0)
|
||||
res = verinum::Vx;
|
||||
else
|
||||
res = verinum::V1;
|
||||
|
||||
verinum vres (res, 1, true);
|
||||
tmp = new NetEConst(vres);
|
||||
tmp->set_line(*this);
|
||||
delete ip;
|
||||
} else {
|
||||
tmp = new NetEUReduce(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
}
|
||||
break;
|
||||
|
||||
case '&': // Reduction AND
|
||||
case '|': // Reduction OR
|
||||
case '^': // Reduction XOR
|
||||
@@ -529,121 +873,76 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
tmp = new NetEUReduce(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
|
||||
case '~':
|
||||
tmp = new NetEUBits(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_expr.cc,v $
|
||||
* Revision 1.33 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
* Revision 1.66 2002/09/21 21:28:18 steve
|
||||
* Allow constant bit selects out of range.
|
||||
*
|
||||
* Revision 1.32 2001/01/02 04:21:13 steve
|
||||
* Support a bunch of unary operators in parameter expressions.
|
||||
* Revision 1.65 2002/09/18 04:08:45 steve
|
||||
* Spelling errors.
|
||||
*
|
||||
* Revision 1.31 2000/12/10 22:01:35 steve
|
||||
* Support decimal constants in behavioral delays.
|
||||
* Revision 1.64 2002/09/12 15:49:43 steve
|
||||
* Add support for binary nand operator.
|
||||
*
|
||||
* Revision 1.30 2000/11/29 05:24:00 steve
|
||||
* synthesis for unary reduction ! and N operators.
|
||||
* Revision 1.63 2002/08/19 02:39:16 steve
|
||||
* Support parameters with defined ranges.
|
||||
*
|
||||
* Revision 1.29 2000/09/26 05:05:58 steve
|
||||
* Detect indefinite widths where definite widths are required.
|
||||
* Revision 1.62 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.28 2000/09/24 17:41:13 steve
|
||||
* fix null pointer when elaborating undefined task.
|
||||
* Revision 1.61 2002/06/14 21:38:41 steve
|
||||
* Fix expression width for repeat concatenations.
|
||||
*
|
||||
* Revision 1.27 2000/08/26 01:31:29 steve
|
||||
* Handle out of range part select expressions.
|
||||
* Revision 1.60 2002/05/24 00:44:54 steve
|
||||
* Add support for $bits (SystemVerilog)
|
||||
*
|
||||
* Revision 1.26 2000/05/19 01:55:09 steve
|
||||
* Catch part select of memories as an error.
|
||||
* Revision 1.59 2002/05/06 02:30:27 steve
|
||||
* Allow parameters in concatenation of widths are defined.
|
||||
*
|
||||
* 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.58 2002/05/05 21:11:49 steve
|
||||
* Put off evaluation of concatenation repeat expresions
|
||||
* until after parameters are defined. This allows parms
|
||||
* to be used in repeat expresions.
|
||||
*
|
||||
* Revision 1.24 2000/05/04 03:37:58 steve
|
||||
* Add infrastructure for system functions, move
|
||||
* $time to that structure and add $random.
|
||||
* Add the builtin $signed system function.
|
||||
*
|
||||
* Revision 1.23 2000/05/02 03:13:30 steve
|
||||
* Move memories to the NetScope object.
|
||||
* Revision 1.57 2002/04/27 05:03:46 steve
|
||||
* Preserve stringiness string part select and concatenation.
|
||||
*
|
||||
* Revision 1.22 2000/05/02 00:58:11 steve
|
||||
* Move signal tables to the NetScope class.
|
||||
* Revision 1.56 2002/04/27 02:38:04 steve
|
||||
* Support selecting bits from parameters.
|
||||
*
|
||||
* Revision 1.21 2000/04/28 18:43:23 steve
|
||||
* integer division in expressions properly get width.
|
||||
* Revision 1.55 2002/04/25 05:04:31 steve
|
||||
* Evaluate constant bit select of constants.
|
||||
*
|
||||
* Revision 1.20 2000/03/29 04:06:28 steve
|
||||
* Forgot to return elaborate result (Dan Nelsen)
|
||||
* Revision 1.54 2002/04/14 21:16:48 steve
|
||||
* Evaluate logical not at elaboration time.
|
||||
*
|
||||
* Revision 1.19 2000/03/20 16:57:22 steve
|
||||
* select correct bit when reg has non-zero lsb.
|
||||
* Revision 1.53 2002/04/14 03:55:25 steve
|
||||
* Precalculate unary - if possible.
|
||||
*
|
||||
* Revision 1.18 2000/03/12 18:22:11 steve
|
||||
* Binary and unary operators in parameter expressions.
|
||||
* Revision 1.52 2002/04/13 02:33:17 steve
|
||||
* Detect missing indices to memories (PR#421)
|
||||
*
|
||||
* 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.51 2002/03/09 02:10:22 steve
|
||||
* Add the NetUserFunc netlist node.
|
||||
*
|
||||
* 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.50 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.49 2002/01/11 05:25:45 steve
|
||||
* The stime system function is 32bits.
|
||||
*/
|
||||
|
||||
|
||||
+99
-69
@@ -16,13 +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) && !defined(macintosh)
|
||||
#ident "$Id: elab_lval.cc,v 1.11 2001/01/10 03:13:23 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_lval.cc,v 1.20 2002/08/12 01:34:58 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 = 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,25 +135,24 @@ 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());
|
||||
if (mem != 0) {
|
||||
cerr << get_line() << ": sorry: I cannot handle "
|
||||
<< "memories in this l-value context." << endl;
|
||||
} else {
|
||||
cerr << get_line() << ": error: Could not find variable ``"
|
||||
<< name() << "'' in ``" << scope->name() <<
|
||||
"''" << endl;
|
||||
}
|
||||
NetMemory*mem = des->find_memory(scope, path_);
|
||||
if (mem != 0)
|
||||
return elaborate_mem_lval_(des, scope, mem);
|
||||
|
||||
cerr << get_line() << ": error: Could not find variable ``"
|
||||
<< path_ << "'' in ``" << scope->name() <<
|
||||
"''" << endl;
|
||||
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
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 +167,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 +175,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 +196,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 +228,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 +243,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 +251,91 @@ 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;
|
||||
}
|
||||
|
||||
NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope,
|
||||
NetMemory*mem) const
|
||||
{
|
||||
assert(msb_ && !lsb_);
|
||||
|
||||
NetExpr*ix = msb_->elaborate_expr(des, scope);
|
||||
if (ix == 0)
|
||||
return 0;
|
||||
|
||||
NetAssign_*lv = new NetAssign_(mem);
|
||||
lv->set_bmux(ix);
|
||||
lv->set_part(0, mem->width());
|
||||
return lv;
|
||||
}
|
||||
|
||||
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_line() << ": error: Constant values not allowed "
|
||||
<< "in l-value expressions." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_lval.cc,v $
|
||||
* Revision 1.20 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.19 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.18 2002/03/09 04:02:26 steve
|
||||
* Constant expressions are not l-values for task ports.
|
||||
*
|
||||
* Revision 1.17 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.16 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Revision 1.15 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.14 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.13 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.12 2001/02/09 03:16:48 steve
|
||||
* Report bit/part select out of range errors. (PR#133)
|
||||
*
|
||||
* Revision 1.11 2001/01/10 03:13:23 steve
|
||||
* Build task outputs as lval instead of nets. (PR#98)
|
||||
*
|
||||
|
||||
+776
-510
File diff suppressed because it is too large
Load Diff
+94
-18
@@ -16,11 +16,16 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_pexpr.cc,v 1.7 2001/01/02 04:21:13 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_pexpr.cc,v 1.16 2002/08/12 01:34:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "util.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
NetExpr*PExpr::elaborate_pexpr(Design*des, NetScope*sc) const
|
||||
{
|
||||
@@ -61,28 +66,21 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
*/
|
||||
NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
unsigned repeat = 1;
|
||||
NetExpr* repeat = 0;
|
||||
|
||||
/* If there is a repeat expression, then evaluate the constant
|
||||
value and set the repeat count.
|
||||
|
||||
XXXX Potential bug XXX In principle, the repeat expression
|
||||
can have a parameter name in it. Since where are in the
|
||||
working of parameters now, we will not be able to
|
||||
accurately evaluate such expressions. So eventually, I will
|
||||
need to be able to defer the evaluation of the expression. */
|
||||
value and set the repeat count. */
|
||||
if (repeat_) {
|
||||
verinum*vrep = repeat_->eval_const(des, scope->name());
|
||||
if (vrep == 0) {
|
||||
repeat = repeat_->elaborate_pexpr(des, scope);
|
||||
if (repeat == 0) {
|
||||
cerr << get_line() << ": error: "
|
||||
"concatenation repeat expression cannot be evaluated."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
repeat = vrep->as_ulong();
|
||||
delete vrep;
|
||||
/* continue on even if the repeat expression doesn't
|
||||
work, as we can find more errors. */
|
||||
}
|
||||
|
||||
/* Make the empty concat expression. */
|
||||
@@ -96,13 +94,38 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
assert(parms_[idx]);
|
||||
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
|
||||
if (ex == 0) continue;
|
||||
|
||||
ex->set_line(*parms_[idx]);
|
||||
|
||||
if (dynamic_cast<NetEParam*>(ex)) {
|
||||
|
||||
/* If this parameter is a NetEParam, then put off
|
||||
the width check for later. */
|
||||
|
||||
} else if (! ex->has_width()) {
|
||||
cerr << ex->get_line() << ": error: operand of "
|
||||
<< "concatenation has indefinite width: "
|
||||
<< *ex << endl;
|
||||
des->errors += 1;
|
||||
|
||||
} 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);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
return elaborate_expr(des, scope);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parameter expressions may reference other parameters, but only in
|
||||
* the current scope. Preserve the parameter reference in the
|
||||
@@ -111,16 +134,31 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
*/
|
||||
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
const NetExpr*ex = scope->get_parameter(text_);
|
||||
hname_t path = path_;
|
||||
char*name = path.remove_tail_name();
|
||||
|
||||
NetScope*pscope = scope;
|
||||
if (path.peek_name(0))
|
||||
pscope = des->find_scope(scope, path);
|
||||
|
||||
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, scope, text_);
|
||||
if (msb_ || lsb_ || idx_) {
|
||||
cerr << get_line() << ": error: Cannot bit/part select "
|
||||
"bits of parameters." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
|
||||
assert(res);
|
||||
delete name;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -184,6 +222,44 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_pexpr.cc,v $
|
||||
* Revision 1.16 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.15 2002/05/06 02:30:27 steve
|
||||
* Allow parameters in concatenation of widths are defined.
|
||||
*
|
||||
* Revision 1.14 2002/05/05 21:11:50 steve
|
||||
* Put off evaluation of concatenation repeat expresions
|
||||
* until after parameters are defined. This allows parms
|
||||
* to be used in repeat expresions.
|
||||
*
|
||||
* Add the builtin $signed system function.
|
||||
*
|
||||
* Revision 1.13 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.12 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.11 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.10 2001/10/07 03:38:08 steve
|
||||
* parameter names do not have defined size.
|
||||
*
|
||||
* Revision 1.9 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.8 2001/01/14 23:04:56 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
* Revision 1.7 2001/01/02 04:21:13 steve
|
||||
* Support a bunch of unary operators in parameter expressions.
|
||||
*
|
||||
|
||||
+116
-31
@@ -16,10 +16,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_scope.cc,v 1.7 2000/12/16 01:45:48 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_scope.cc,v 1.17 2002/10/19 22:59:49 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
|
||||
@@ -50,7 +54,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// the pform and just place a NetEParam placeholder in the
|
||||
// place of the elaborated expression.
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
typedef map<string,param_expr_t>::const_iterator mparm_it_t;
|
||||
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
|
||||
|
||||
|
||||
// This loop scans the parameters in the module, and creates
|
||||
@@ -59,13 +64,21 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
|
||||
scope->set_parameter((*cur).first, new NetEParam);
|
||||
NetEParam*tmp = new NetEParam;
|
||||
if ((*cur).second.msb)
|
||||
tmp->cast_signed( (*cur).second.signed_flag );
|
||||
|
||||
scope->set_parameter((*cur).first, tmp, 0, 0, false);
|
||||
}
|
||||
|
||||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; cur ++) {
|
||||
|
||||
scope->set_parameter((*cur).first, new NetEParam);
|
||||
NetEParam*tmp = new NetEParam;
|
||||
if ((*cur).second.msb)
|
||||
tmp->cast_signed( (*cur).second.signed_flag );
|
||||
|
||||
scope->set_parameter((*cur).first, tmp, 0, 0, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,11 +90,29 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
|
||||
PExpr*ex = (*cur).second;
|
||||
PExpr*ex = (*cur).second.expr;
|
||||
assert(ex);
|
||||
|
||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||
val = scope->set_parameter((*cur).first, val);
|
||||
NetExpr*msb = 0;
|
||||
NetExpr*lsb = 0;
|
||||
bool signed_flag = false;
|
||||
|
||||
/* If the parameter declaration includes msb and lsb,
|
||||
then use them to calculate a width for the
|
||||
result. Then make sure the constant expression of the
|
||||
parameter value is coerced to have the correct
|
||||
and defined width. */
|
||||
if ((*cur).second.msb) {
|
||||
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
|
||||
assert(msb);
|
||||
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
|
||||
signed_flag = (*cur).second.signed_flag;
|
||||
}
|
||||
|
||||
val->cast_signed(signed_flag);
|
||||
val = scope->set_parameter((*cur).first, val,
|
||||
msb, lsb, signed_flag);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
@@ -89,11 +120,11 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; cur ++) {
|
||||
|
||||
PExpr*ex = (*cur).second;
|
||||
PExpr*ex = (*cur).second.expr;
|
||||
assert(ex);
|
||||
|
||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||
val = scope->set_parameter((*cur).first, val);
|
||||
val = scope->set_parameter((*cur).first, val, 0, 0, false);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
@@ -108,7 +139,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 +161,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 +176,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 +222,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 +252,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 +267,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);
|
||||
@@ -246,8 +282,10 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
// later.)
|
||||
mod->elaborate_scope(des, my_scope);
|
||||
|
||||
// Look for module parameter replacements. This map receives
|
||||
// those replacements.
|
||||
// Look for module parameter replacements. The "replace" map
|
||||
// maps parameter name to replacement expression that is
|
||||
// passed. It is built up by the ordered overrices or named
|
||||
// overrides.
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
map<string,PExpr*> replace;
|
||||
@@ -261,12 +299,18 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
if (overrides_) {
|
||||
assert(parms_ == 0);
|
||||
list<string>::const_iterator cur = mod->param_names.begin();
|
||||
for (unsigned idx = 0
|
||||
; idx < overrides_->count()
|
||||
; idx += 1, cur++) {
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
}
|
||||
unsigned idx = 0;
|
||||
for (;;) {
|
||||
if (idx >= overrides_->count())
|
||||
break;
|
||||
if (cur == mod->param_names.end())
|
||||
break;
|
||||
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
|
||||
idx += 1;
|
||||
cur ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Named parameter overrides carry a name with each override
|
||||
@@ -288,16 +332,21 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
|
||||
PExpr*tmp = (*cur).second;
|
||||
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
||||
val = my_scope->set_parameter((*cur).first, val);
|
||||
assert(val);
|
||||
delete val;
|
||||
bool flag = my_scope->replace_parameter((*cur).first, val);
|
||||
if (! flag) {
|
||||
cerr << val->get_line() << ": warning: parameter "
|
||||
<< (*cur).first << " not found in "
|
||||
<< sc->name() << "." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 +362,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 +387,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 +496,39 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_scope.cc,v $
|
||||
* Revision 1.17 2002/10/19 22:59:49 steve
|
||||
* Redo the parameter vector support to allow
|
||||
* parameter names in range expressions.
|
||||
*
|
||||
* Revision 1.16 2002/09/01 03:01:48 steve
|
||||
* Properly cast signedness of parameters with ranges.
|
||||
*
|
||||
* Revision 1.15 2002/08/19 02:39:16 steve
|
||||
* Support parameters with defined ranges.
|
||||
*
|
||||
* Revision 1.14 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.13 2001/12/30 04:47:57 steve
|
||||
* Properly handle empty target in positionla parameter override.
|
||||
*
|
||||
* Revision 1.12 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.11 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.10 2001/10/09 02:01:04 steve
|
||||
* Tasks can have sub-scopes.
|
||||
*
|
||||
* Revision 1.9 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.8 2001/04/28 23:18:08 steve
|
||||
* UDP instances need not have user supplied names.
|
||||
*
|
||||
* Revision 1.7 2000/12/16 01:45:48 steve
|
||||
* Detect recursive instantiations (PR#2)
|
||||
*
|
||||
|
||||
+222
-48
@@ -16,16 +16,21 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_sig.cc,v 1.10 2001/01/13 22:20:08 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_sig.cc,v 1.25 2002/08/12 01:34:59 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,24 +67,62 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
// Get all the explicitly declared wires of the module and
|
||||
// start the signals list with them.
|
||||
const map<string,PWire*>&wl = get_wires();
|
||||
const map<hname_t,PWire*>&wl = get_wires();
|
||||
|
||||
for (map<string,PWire*>::const_iterator wt = wl.begin()
|
||||
// Scan all the ports of the module, and make sure that each
|
||||
// is connected to wires that have port declarations.
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
Module::port_t*pp = ports[idx];
|
||||
if (pp == 0)
|
||||
continue;
|
||||
|
||||
map<hname_t,PWire*>::const_iterator wt;
|
||||
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
||||
hname_t port_path (pp->expr[cc]->path());
|
||||
wt = wl.find(port_path);
|
||||
|
||||
if (wt == wl.end()) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< "Port " << pp->expr[cc]->path() << " ("
|
||||
<< (idx+1) << ") of module " << name_
|
||||
<< " is not declared within module." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< "Port " << pp->expr[cc]->path() << " ("
|
||||
<< (idx+1) << ") of module " << name_
|
||||
<< " has no direction declaration."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
|
||||
; wt != wl.end()
|
||||
; wt ++ ) {
|
||||
|
||||
PWire*cur = (*wt).second;
|
||||
cur->elaborate_sig(des, scope);
|
||||
|
||||
NetNet*sig = scope->find_signal_in_child(cur->path());
|
||||
|
||||
// If this wire is a signal of the module (as opposed to
|
||||
// a port of a function) and is a port, then check that
|
||||
// the module knows about it.
|
||||
NetNet*sig = scope->find_signal(cur->name());
|
||||
// the module knows about it. We know that the signal is
|
||||
// the name of a signal within a subscope of a module
|
||||
// (a task, a function, etc.) if the name for the PWire
|
||||
// has hierarchy.
|
||||
|
||||
if (sig && (sig->scope() == scope)
|
||||
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
|
||||
string name = (*wt).first;
|
||||
|
||||
if (! signal_is_in_port(ports_, name)) {
|
||||
hname_t name = (*wt).first;
|
||||
|
||||
if (! signal_is_in_port(ports, name)) {
|
||||
|
||||
cerr << cur->get_line() << ": error: Signal "
|
||||
<< name << " has a declared direction "
|
||||
@@ -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
|
||||
@@ -167,6 +237,17 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
string fname = scope->basename();
|
||||
assert(scope->type() == NetScope::FUNC);
|
||||
|
||||
/* Make sure the function has at least one input port. If it
|
||||
fails this test, print an error message. Keep going so we
|
||||
can find more errors. */
|
||||
if (ports_ == 0) {
|
||||
cerr << get_line() << ": error: Function " << fname
|
||||
<< " has no ports." << endl;
|
||||
cerr << get_line() << ": : Functions must have"
|
||||
<< " at least one input port." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
|
||||
|
||||
/* Get the reg for the return value. I know the name of the
|
||||
@@ -189,12 +270,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 +319,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 +336,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 +369,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,9 +386,14 @@ 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());
|
||||
/* There may be places where the signal is declared as a
|
||||
scaler. Count those here, for consistency check
|
||||
later. */
|
||||
unsigned count_scalars = 0;
|
||||
|
||||
/* There may be multiple declarations of ranges, because
|
||||
the symbol may have its range declared in i.e. input
|
||||
@@ -320,29 +401,57 @@ 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) {
|
||||
|
||||
if (msb_[idx] == 0) {
|
||||
count_scalars += 1;
|
||||
assert(lsb_[idx] == 0);
|
||||
mnum[idx] = 0;
|
||||
lnum[idx] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
NetEConst*tmp;
|
||||
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
/* Check that the declarations were all scalar or all
|
||||
vector. It is an error to mix them. Use the
|
||||
count_scalars to know. */
|
||||
if ((count_scalars > 0) && (count_scalars != msb_.count())) {
|
||||
cerr << get_line() << ": error: Signal ``" << hname_
|
||||
<< "'' declared both as a vector and a scalar."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Make sure all the values for msb and lsb match by
|
||||
value. If not, report an error. */
|
||||
for (unsigned idx = 1 ; idx < msb_.count() ; idx += 1) {
|
||||
@@ -350,7 +459,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;
|
||||
}
|
||||
@@ -366,18 +475,22 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
}
|
||||
|
||||
unsigned nattrib = 0;
|
||||
attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
|
||||
des, scope);
|
||||
|
||||
if (lidx_ || ridx_) {
|
||||
assert(lidx_ && ridx_);
|
||||
|
||||
// If the register has indices, then this is a
|
||||
// memory. Create the memory object.
|
||||
verinum*lval = lidx_->eval_const(des, path);
|
||||
verinum*rval = ridx_->eval_const(des, path);
|
||||
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,25 +498,86 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
assert(lval);
|
||||
assert(rval);
|
||||
|
||||
string 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());
|
||||
sig->set_attributes(attributes);
|
||||
sig->set_isint(get_isint());
|
||||
|
||||
for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
|
||||
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_sig.cc,v $
|
||||
* Revision 1.25 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.24 2002/08/05 04:18:45 steve
|
||||
* Store only the base name of memories.
|
||||
*
|
||||
* Revision 1.23 2002/06/21 04:59:35 steve
|
||||
* Carry integerness throughout the compilation.
|
||||
*
|
||||
* Revision 1.22 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.21 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* Revision 1.20 2002/01/26 05:28:28 steve
|
||||
* Detect scalar/vector declarion mismatch.
|
||||
*
|
||||
* Revision 1.19 2002/01/23 03:35:17 steve
|
||||
* Detect incorrect function ports.
|
||||
*
|
||||
* Revision 1.18 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.17 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.16 2001/11/01 05:21:26 steve
|
||||
* Catch ports that have no direction.
|
||||
*
|
||||
* Revision 1.15 2001/10/31 03:11:15 steve
|
||||
* detect module ports not declared within the module.
|
||||
*
|
||||
* Revision 1.14 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.13 2001/05/25 02:21:34 steve
|
||||
* Detect input and input ports declared as reg.
|
||||
*
|
||||
* Revision 1.12 2001/02/17 05:15:33 steve
|
||||
* Allow task ports to be given real types.
|
||||
*
|
||||
* Revision 1.11 2001/02/10 20:29:39 steve
|
||||
* In the context of range declarations, use elab_and_eval instead
|
||||
* of the less robust eval_const methods.
|
||||
*
|
||||
* Revision 1.10 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
+669
-633
File diff suppressed because it is too large
Load Diff
@@ -16,10 +16,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: emit.cc,v 1.55 2000/11/04 01:54:01 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: emit.cc,v 1.69 2002/08/12 01:34:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* The emit function is called to generate the output required of the
|
||||
* target.
|
||||
@@ -41,12 +45,6 @@ bool NetLogic::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->udp_comb(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUDP::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->udp(this);
|
||||
@@ -59,12 +57,6 @@ bool NetAddSub::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAssign_::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_assign(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCaseCmp::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_case_cmp(this);
|
||||
@@ -136,6 +128,11 @@ bool NetRamDq::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUserFunc::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->net_function(this);
|
||||
}
|
||||
|
||||
bool NetBUFZ::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->bufz(this);
|
||||
@@ -164,18 +161,6 @@ bool NetAssignNB::emit_proc(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAssignMem::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_assign_mem(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAssignMemNB::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_assign_mem_nb(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetBlock::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_block(this);
|
||||
@@ -194,8 +179,7 @@ bool NetCAssign::emit_proc(struct target_t*tgt) const
|
||||
|
||||
bool NetCondit::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_condit(this);
|
||||
return true;
|
||||
return tgt->proc_condit(this);
|
||||
}
|
||||
|
||||
bool NetDeassign::emit_proc(struct target_t*tgt) const
|
||||
@@ -271,16 +255,20 @@ void NetBlock::emit_recurse(struct target_t*tgt) const
|
||||
} while (cur != last_);
|
||||
}
|
||||
|
||||
void NetCondit::emit_recurse_if(struct target_t*tgt) const
|
||||
bool NetCondit::emit_recurse_if(struct target_t*tgt) const
|
||||
{
|
||||
if (if_)
|
||||
if_->emit_proc(tgt);
|
||||
return if_->emit_proc(tgt);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetCondit::emit_recurse_else(struct target_t*tgt) const
|
||||
bool NetCondit::emit_recurse_else(struct target_t*tgt) const
|
||||
{
|
||||
if (else_)
|
||||
else_->emit_proc(tgt);
|
||||
return else_->emit_proc(tgt);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetEvProbe::emit_node(struct target_t*tgt) const
|
||||
@@ -354,10 +342,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 +365,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 +381,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;
|
||||
}
|
||||
|
||||
@@ -433,6 +427,11 @@ void NetEScope::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_scope(this);
|
||||
}
|
||||
|
||||
void NetESelect::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_select(this);
|
||||
}
|
||||
|
||||
void NetESFunc::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_sfunc(this);
|
||||
@@ -448,7 +447,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 +475,63 @@ bool emit(const Design*des, const char*type)
|
||||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.69 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.68 2002/06/05 03:44:25 steve
|
||||
* Add support for memory words in l-value of
|
||||
* non-blocking assignments, and remove the special
|
||||
* NetAssignMem_ and NetAssignMemNB classes.
|
||||
*
|
||||
* Revision 1.67 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.66 2002/03/09 02:10:22 steve
|
||||
* Add the NetUserFunc netlist node.
|
||||
*
|
||||
* Revision 1.65 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.64 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.63 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.62 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.61 2001/07/27 04:51:44 steve
|
||||
* Handle part select expressions as variants of
|
||||
* NetESignal/IVL_EX_SIGNAL objects, instead of
|
||||
* creating new and useless temporary signals.
|
||||
*
|
||||
* Revision 1.60 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.59 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.58 2001/04/06 02:28:02 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
*
|
||||
* Revision 1.57 2001/04/02 02:28:12 steve
|
||||
* Generate code for task calls.
|
||||
*
|
||||
* Revision 1.56 2001/03/27 03:31:06 steve
|
||||
* Support error code from target_t::end_design method.
|
||||
*
|
||||
* Revision 1.55 2000/11/04 01:54:01 steve
|
||||
* Modifications in support of gcc 2.96
|
||||
*
|
||||
|
||||
@@ -16,72 +16,86 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval.cc,v 1.17 2001/01/04 04:47:51 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval.cc,v 1.32 2002/10/19 22:59:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include "compiler.h"
|
||||
|
||||
verinum* PExpr::eval_const(const Design*, const string&) const
|
||||
verinum* PExpr::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum* PEBinary::eval_const(const Design*des, const string&path) const
|
||||
verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*l = left_->eval_const(des, path);
|
||||
verinum*l = left_->eval_const(des, scope);
|
||||
if (l == 0) return 0;
|
||||
verinum*r = right_->eval_const(des, path);
|
||||
verinum*r = right_->eval_const(des, scope);
|
||||
if (r == 0) {
|
||||
delete l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum*res;
|
||||
|
||||
switch (op_) {
|
||||
case '+': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv+rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv+rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '-': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv-rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv-rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '*': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv * rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv * rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '/': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv / rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv / rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '%': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv % rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv % rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
case 'l': { // left shift (<<)
|
||||
assert(r->is_defined());
|
||||
unsigned long rv = r->as_ulong();
|
||||
res = new verinum(verinum::V0, l->len());
|
||||
@@ -92,6 +106,17 @@ verinum* PEBinary::eval_const(const Design*des, const string&path) const
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'r': { // right shift (>>)
|
||||
assert(r->is_defined());
|
||||
unsigned long rv = r->as_ulong();
|
||||
res = new verinum(verinum::V0, l->len());
|
||||
if (rv < res->len()) {
|
||||
unsigned cnt = res->len() - rv;
|
||||
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
|
||||
res->set(idx, l->get(idx+rv));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
delete l;
|
||||
@@ -104,46 +129,55 @@ verinum* PEBinary::eval_const(const Design*des, const string&path) const
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Evaluate an identifier as a constant expression. This is only
|
||||
* possible if the identifier is that of a parameter.
|
||||
*/
|
||||
verinum* PEIdent::eval_const(const Design*des, const string&path) const
|
||||
verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
const NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
const NetExpr*expr = des->find_parameter(scope, text_);
|
||||
const NetExpr*expr = des->find_parameter(scope, path_);
|
||||
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
||||
assert(msb_ == 0);
|
||||
|
||||
if (dynamic_cast<const NetEParam*>(expr)) {
|
||||
cerr << get_line() << ": sorry: I cannot evaluate ``" <<
|
||||
text_ << "'' in this context." << endl;
|
||||
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
|
||||
if (eval == 0) {
|
||||
cerr << get_line() << ": internal error: Unable to evaluate "
|
||||
<< "constant expression (parameter=" << path_
|
||||
<< "): " << *expr << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
|
||||
assert(eval);
|
||||
|
||||
if (msb_ || lsb_)
|
||||
return 0;
|
||||
|
||||
|
||||
return new verinum(eval->value());
|
||||
}
|
||||
|
||||
verinum* PEFNumber::eval_const(const Design*, const string&) const
|
||||
verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
long val = value_->as_long();
|
||||
return new verinum(val);
|
||||
}
|
||||
|
||||
verinum* PENumber::eval_const(const Design*, const string&) const
|
||||
verinum* PENumber::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
return new verinum(value());
|
||||
}
|
||||
|
||||
verinum* PETernary::eval_const(const Design*des, const string&path) const
|
||||
verinum* PEString::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
verinum*test = expr_->eval_const(des, path);
|
||||
return new verinum(string(text_));
|
||||
}
|
||||
|
||||
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*test = expr_->eval_const(des, scope);
|
||||
if (test == 0)
|
||||
return 0;
|
||||
|
||||
@@ -151,9 +185,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_
|
||||
@@ -161,9 +195,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;
|
||||
|
||||
@@ -171,9 +205,18 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const
|
||||
case '+':
|
||||
return val;
|
||||
|
||||
case '-':
|
||||
*val = v_not(*val) + verinum(verinum::V1, 1);
|
||||
return val;
|
||||
case '-': {
|
||||
/* We need to expand the value a bit if we are
|
||||
taking the 2's complement so that we are
|
||||
guaranteed to not overflow. */
|
||||
verinum tmp (0UL, val->len()+1);
|
||||
for (unsigned idx = 0 ; idx < val->len() ; idx += 1)
|
||||
tmp.set(idx, val->get(idx));
|
||||
|
||||
*val = v_not(tmp) + verinum(verinum::V1, 1);
|
||||
val->has_sign(true);
|
||||
return val;
|
||||
}
|
||||
|
||||
}
|
||||
delete val;
|
||||
@@ -183,6 +226,62 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const
|
||||
|
||||
/*
|
||||
* $Log: eval.cc,v $
|
||||
* Revision 1.32 2002/10/19 22:59:49 steve
|
||||
* Redo the parameter vector support to allow
|
||||
* parameter names in range expressions.
|
||||
*
|
||||
* Revision 1.31 2002/10/13 05:01:07 steve
|
||||
* More verbose eval_const assert message.
|
||||
*
|
||||
* Revision 1.30 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.29 2002/06/07 02:57:54 steve
|
||||
* Simply give up on constants with indices.
|
||||
*
|
||||
* Revision 1.28 2002/06/06 18:57:04 steve
|
||||
* Better error for identifier index eval.
|
||||
*
|
||||
* Revision 1.27 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.26 2001/12/29 22:10:10 steve
|
||||
* constant eval of arithmetic with x and z.
|
||||
*
|
||||
* Revision 1.25 2001/12/29 00:43:55 steve
|
||||
* Evaluate constant right shifts.
|
||||
*
|
||||
* Revision 1.24 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.23 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.22 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* Revision 1.21 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.20 2001/02/09 02:49:59 steve
|
||||
* Be more clear about scope of failure.
|
||||
*
|
||||
* Revision 1.19 2001/01/27 05:41:48 steve
|
||||
* Fix sign extension of evaluated constants. (PR#91)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
* Revision 1.17 2001/01/04 04:47:51 steve
|
||||
* Add support for << is signal indices.
|
||||
*
|
||||
@@ -191,59 +290,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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval_attrib.cc,v 1.5 2002/08/12 01:34:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "util.h"
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include <iostream>
|
||||
# include <assert.h>
|
||||
|
||||
/*
|
||||
* The evaluate_attributes function evaluates the attribute
|
||||
* expressions from the map, and resturns a table in a form suitable
|
||||
* for passing to netlist devices.
|
||||
*/
|
||||
|
||||
attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
|
||||
unsigned&natt,
|
||||
const Design*des,
|
||||
const NetScope*scope)
|
||||
{
|
||||
natt = att.size();
|
||||
if (natt == 0)
|
||||
return 0;
|
||||
|
||||
attrib_list_t*table = new attrib_list_t [natt];
|
||||
|
||||
unsigned idx = 0;
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator iter_t;
|
||||
for (iter_t cur = att.begin() ; cur != att.end() ; cur ++, idx++) {
|
||||
table[idx].key = (*cur).first;
|
||||
PExpr*exp = (*cur).second;
|
||||
|
||||
/* If the attribute value is given in the source, then
|
||||
evalulate it as a constant. If the value is not
|
||||
given, then assume the value is 1. */
|
||||
verinum*tmp;
|
||||
if (exp)
|
||||
tmp = exp->eval_const(des, scope);
|
||||
else
|
||||
tmp = new verinum(1);
|
||||
|
||||
if (tmp == 0)
|
||||
cerr << "internal error: no result for " << *exp << endl;
|
||||
assert(tmp);
|
||||
|
||||
table[idx].val = *tmp;
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
assert(idx == natt);
|
||||
return table;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: eval_attrib.cc,v $
|
||||
* Revision 1.5 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.4 2002/08/10 21:59:39 steve
|
||||
* The default attribute value is 1.
|
||||
*
|
||||
* Revision 1.3 2002/06/06 18:57:18 steve
|
||||
* Use standard name for iostream.
|
||||
*
|
||||
* Revision 1.2 2002/06/03 03:55:14 steve
|
||||
* compile warnings.
|
||||
*
|
||||
* Revision 1.1 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
*/
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval_rconst.cc,v 1.5 2002/08/12 01:34:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
|
||||
verireal* PExpr::eval_rconst(const Design*, const NetScope*) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
verireal* PEFNumber::eval_rconst(const Design*, const NetScope*) const
|
||||
{
|
||||
verireal*res = new verireal;
|
||||
*res = *value_;
|
||||
return res;
|
||||
}
|
||||
|
||||
verireal* PENumber::eval_rconst(const Design*, const NetScope*) const
|
||||
{
|
||||
verireal*res = new verireal(value_->as_long());
|
||||
return res;
|
||||
}
|
||||
|
||||
verireal* PEBinary::eval_rconst(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verireal*lef = left_->eval_rconst(des, scope);
|
||||
verireal*rig = right_->eval_rconst(des, scope);
|
||||
verireal*res = 0;
|
||||
|
||||
switch (op_) {
|
||||
case '*':
|
||||
if (lef == 0)
|
||||
break;
|
||||
if (rig == 0)
|
||||
break;
|
||||
res = new verireal;
|
||||
*res = (*lef) * (*rig);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
delete lef;
|
||||
delete rig;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
verireal* PEIdent::eval_rconst(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum* val = eval_const(des, scope);
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
verireal*res = new verireal(val->as_long());
|
||||
delete val;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: eval_rconst.cc,v $
|
||||
* Revision 1.5 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.4 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.3 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2001/01/14 23:04:56 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
*/
|
||||
|
||||
+462
-65
@@ -16,10 +16,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval_tree.cc,v 1.20 2001/01/04 16:49:50 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval_tree.cc,v 1.42 2002/10/19 22:59:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "netlist.h"
|
||||
|
||||
NetExpr* NetExpr::eval_tree()
|
||||
@@ -77,8 +81,22 @@ NetEConst* NetEBBits::eval_tree()
|
||||
eval_sub_tree_();
|
||||
|
||||
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
|
||||
if (lc == 0) return 0;
|
||||
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
|
||||
|
||||
/* Notice the special case where one of the operands is 0 and
|
||||
this is a bitwise &. If this happens, then the result is
|
||||
known to be 0. */
|
||||
if ((op() == '&') && lc && (lc->value() == verinum(0))) {
|
||||
verinum res (verinum::V0, expr_width());
|
||||
return new NetEConst(res);
|
||||
}
|
||||
|
||||
if ((op() == '&') && rc && (rc->value() == verinum(0))) {
|
||||
verinum res (verinum::V0, expr_width());
|
||||
return new NetEConst(res);
|
||||
}
|
||||
|
||||
if (lc == 0) return 0;
|
||||
if (rc == 0) return 0;
|
||||
|
||||
verinum lval = lc->value();
|
||||
@@ -112,11 +130,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 +166,80 @@ 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()) {
|
||||
if (lv.as_long() < rv.as_long()) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
} else {
|
||||
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_);
|
||||
@@ -172,6 +251,7 @@ NetEConst* NetEBComp::eval_leeq_()
|
||||
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. */
|
||||
@@ -191,12 +271,100 @@ NetEConst* NetEBComp::eval_leeq_()
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
if (lv.has_sign() && rv.has_sign() && (lv.as_long() <= rv.as_long())) {
|
||||
if (lv.has_sign() && rv.has_sign()) {
|
||||
if (lv.as_long() <= rv.as_long()) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
} else {
|
||||
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_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);
|
||||
}
|
||||
|
||||
if (lv.as_ulong() <= rv.as_ulong()) {
|
||||
/* 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);
|
||||
}
|
||||
@@ -349,6 +517,9 @@ NetEConst* NetEBComp::eval_tree()
|
||||
case 'e': // Equality (==)
|
||||
return eval_eqeq_();
|
||||
|
||||
case 'G': // >=
|
||||
return eval_gteq_();
|
||||
|
||||
case 'L': // <=
|
||||
return eval_leeq_();
|
||||
|
||||
@@ -358,14 +529,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;
|
||||
}
|
||||
|
||||
@@ -521,6 +719,10 @@ NetEConst* NetEBShift::eval_tree()
|
||||
|
||||
NetEConst* NetEConcat::eval_tree()
|
||||
{
|
||||
unsigned repeat_val = repeat();
|
||||
unsigned local_errors = 0;
|
||||
|
||||
unsigned gap = 0;
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
|
||||
// Parameter not here? This is an error, but presumably
|
||||
@@ -528,10 +730,13 @@ NetEConst* NetEConcat::eval_tree()
|
||||
if (parms_[idx] == 0)
|
||||
continue;
|
||||
|
||||
|
||||
// If this parameter is already a constant, all is well
|
||||
// so go on.
|
||||
if (dynamic_cast<NetEConst*>(parms_[idx]))
|
||||
if (dynamic_cast<NetEConst*>(parms_[idx])) {
|
||||
gap += parms_[idx]->expr_width();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Finally, try to evaluate the parameter expression
|
||||
// that is here. If I succeed, reset the parameter to
|
||||
@@ -541,25 +746,58 @@ NetEConst* NetEConcat::eval_tree()
|
||||
if (expr) {
|
||||
delete parms_[idx];
|
||||
parms_[idx] = expr;
|
||||
|
||||
if (! expr->has_width()) {
|
||||
cerr << get_line() << ": error: concatenation "
|
||||
<< "operand has indefinite width: "
|
||||
<< *parms_[idx] << endl;
|
||||
local_errors += 1;
|
||||
}
|
||||
gap += expr->expr_width();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned gap = expr_width() / repeat_;
|
||||
verinum val (verinum::Vx, repeat_ * gap);
|
||||
if (local_errors > 0)
|
||||
return 0;
|
||||
|
||||
// Handle the special case that the repeat expression is
|
||||
// zero. In this case, just return a 0 value with the expected
|
||||
// width.
|
||||
if (repeat_val == 0) {
|
||||
verinum val (verinum::V0, expr_width());
|
||||
NetEConst*res = new NetEConst(val);
|
||||
res->set_width(val.len());
|
||||
return res;
|
||||
}
|
||||
|
||||
// At this point, the "gap" is the width of a single repeat of
|
||||
// the concatenation. The total width of the result is the gap
|
||||
// times the repeat count.
|
||||
verinum val (verinum::Vx, repeat_val * gap);
|
||||
|
||||
// build up the result from least significant to most.
|
||||
|
||||
unsigned cur = 0;
|
||||
bool is_string_flag = true;
|
||||
for (unsigned idx = parms_.count() ; idx > 0 ; idx -= 1) {
|
||||
NetEConst*expr = dynamic_cast<NetEConst*>(parms_[idx-1]);
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
||||
verinum tmp = expr->value();
|
||||
for (unsigned bit = 0 ; bit < tmp.len() ; bit += 1, cur += 1)
|
||||
for (unsigned rep = 0 ; rep < repeat_ ; rep += 1)
|
||||
for (unsigned bit = 0; bit < tmp.len(); bit += 1, cur += 1)
|
||||
for (unsigned rep = 0 ; rep < repeat_val ; rep += 1)
|
||||
val.set(rep*gap+cur, tmp[bit]);
|
||||
|
||||
is_string_flag = is_string_flag && tmp.is_string();
|
||||
}
|
||||
|
||||
/* If all the values were strings, then re-stringify this
|
||||
constant. This might be useful information in the code
|
||||
generator or other optimizer steps. */
|
||||
if (is_string_flag) {
|
||||
val = verinum(val.as_string());
|
||||
}
|
||||
|
||||
NetEConst*res = new NetEConst(val);
|
||||
@@ -567,13 +805,65 @@ NetEConst* NetEConcat::eval_tree()
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* There are limits to our ability to evaluate a memory reference
|
||||
* expression, because the content of a memory is never
|
||||
* constant. However, the index expression may be precalculated, and
|
||||
* there are certain index values that do give us constant results.
|
||||
*/
|
||||
NetExpr* NetEMemory::eval_tree()
|
||||
{
|
||||
/* Attempt to evaluate the index expression to a constant, if
|
||||
it is not already. */
|
||||
if (idx_ && !dynamic_cast<NetEConst*>(idx_)) {
|
||||
NetExpr* tmp = idx_->eval_tree();
|
||||
if (tmp) {
|
||||
delete idx_;
|
||||
idx_ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
NetEConst*itmp = dynamic_cast<NetEConst*>(idx_);
|
||||
if (itmp == 0)
|
||||
return 0;
|
||||
|
||||
verinum ival = itmp->value();
|
||||
|
||||
/* If the index expression has any x or z bits, then we know
|
||||
already that the expression result is a constant x. */
|
||||
if (! ival.is_defined()) {
|
||||
verinum xres (verinum::Vx, mem_->width(), false);
|
||||
NetEConst*res = new NetEConst(xres);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* If the index expression is outside the range of the memory,
|
||||
then the result is a constant x. */
|
||||
unsigned norm_idx = mem_->index_to_address(ival.as_long());
|
||||
if (norm_idx >= mem_->count()) {
|
||||
verinum xres (verinum::Vx, mem_->width(), false);
|
||||
NetEConst*res = new NetEConst(xres);
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr* NetEParam::eval_tree()
|
||||
{
|
||||
if (des_ == 0)
|
||||
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 "
|
||||
<< scope_->name() << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(expr);
|
||||
|
||||
NetExpr*nexpr = expr->dup_expr();
|
||||
@@ -594,7 +884,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_->replace_parameter(name_.peek_name(0), res);
|
||||
return res->dup_expr();
|
||||
}
|
||||
|
||||
@@ -609,48 +899,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
|
||||
@@ -658,27 +949,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());
|
||||
@@ -701,6 +979,7 @@ NetExpr* NetETernary::eval_tree()
|
||||
|
||||
void NetEUnary::eval_expr_()
|
||||
{
|
||||
assert(expr_);
|
||||
if (dynamic_cast<NetEConst*>(expr_))
|
||||
return;
|
||||
|
||||
@@ -723,6 +1002,24 @@ NetEConst* NetEUnary::eval_tree()
|
||||
|
||||
switch (op_) {
|
||||
|
||||
case '+':
|
||||
/* Unary + is a no-op. */
|
||||
return new NetEConst(val);
|
||||
|
||||
case '-': {
|
||||
if (val.is_defined()) {
|
||||
|
||||
verinum tmp (verinum::V0, val.len());
|
||||
tmp.has_sign(val.has_sign());
|
||||
val = tmp - val;
|
||||
|
||||
} else {
|
||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||
val.set(idx, verinum::Vx);
|
||||
}
|
||||
|
||||
return new NetEConst(val);
|
||||
}
|
||||
|
||||
case '~': {
|
||||
/* Bitwise not is even simpler then logical
|
||||
@@ -744,7 +1041,6 @@ NetEConst* NetEUnary::eval_tree()
|
||||
}
|
||||
|
||||
default:
|
||||
delete rval;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -789,6 +1085,7 @@ NetEConst* NetEUReduce::eval_tree()
|
||||
}
|
||||
|
||||
res = v1? verinum::V0 : (vx? verinum::Vx : verinum::V1);
|
||||
break;
|
||||
}
|
||||
|
||||
case '&': {
|
||||
@@ -805,6 +1102,28 @@ NetEConst* NetEUReduce::eval_tree()
|
||||
break;
|
||||
}
|
||||
|
||||
case '^': {
|
||||
/* Reduction XOR. */
|
||||
unsigned ones = 0, unknown = 0;
|
||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||
switch (val.get(idx)) {
|
||||
case verinum::V0:
|
||||
break;
|
||||
case verinum::V1:
|
||||
ones += 1;
|
||||
break;
|
||||
default:
|
||||
unknown += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unknown)
|
||||
return new NetEConst(verinum(verinum::Vx,1,true));
|
||||
if (ones%2)
|
||||
return new NetEConst(verinum(verinum::V1,1,true));
|
||||
return new NetEConst(verinum(verinum::V0,1,true));
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -815,6 +1134,84 @@ NetEConst* NetEUReduce::eval_tree()
|
||||
|
||||
/*
|
||||
* $Log: eval_tree.cc,v $
|
||||
* Revision 1.42 2002/10/19 22:59:49 steve
|
||||
* Redo the parameter vector support to allow
|
||||
* parameter names in range expressions.
|
||||
*
|
||||
* Revision 1.41 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.40 2002/05/25 16:43:47 steve
|
||||
* Eval ^ and &0 expressions.
|
||||
*
|
||||
* Revision 1.39 2002/05/06 02:30:27 steve
|
||||
* Allow parameters in concatenation of widths are defined.
|
||||
*
|
||||
* Revision 1.38 2002/05/05 21:11:50 steve
|
||||
* Put off evaluation of concatenation repeat expresions
|
||||
* until after parameters are defined. This allows parms
|
||||
* to be used in repeat expresions.
|
||||
*
|
||||
* Add the builtin $signed system function.
|
||||
*
|
||||
* Revision 1.37 2002/04/27 05:03:46 steve
|
||||
* Preserve stringiness string part select and concatenation.
|
||||
*
|
||||
* Revision 1.36 2002/04/27 03:17:15 steve
|
||||
* Fixup eval of signed constants.
|
||||
*
|
||||
* Revision 1.35 2002/04/24 02:47:02 steve
|
||||
* Fix compile time eval of signed <= signed.
|
||||
*
|
||||
* Revision 1.34 2002/04/14 19:28:47 steve
|
||||
* Fix constant evaluation of unary
|
||||
*
|
||||
* Revision 1.33 2002/02/01 05:09:14 steve
|
||||
* Propagate sign in unary minus.
|
||||
*
|
||||
* Revision 1.32 2002/01/22 01:40:04 steve
|
||||
* Precalculate constant results of memory index expressions.
|
||||
*
|
||||
* Revision 1.31 2001/12/30 00:39:25 steve
|
||||
* Evaluate constant unary minus.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
* Revision 1.20 2001/01/04 16:49:50 steve
|
||||
* Evaluate constant === and !== expressions.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
,*
|
||||
hello_vpi.vpi
|
||||
show_vcd.vcd
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
*
|
||||
* To compile this for XNF, try a command like this:
|
||||
*
|
||||
* iverilog -txnf -fpart=XC4010XLPQ160 -fncf=clbff.ncf -oclbff.xnf clbff.v
|
||||
* iverilog -txnf -ppart=XC4010XLPQ160 -pncf=clbff.ncf -oclbff.xnf clbff.v
|
||||
*
|
||||
* That command causes an clbff.xnf and clbff.ncf file to be created.
|
||||
* Next, make the clbff.ngd file with the command:
|
||||
|
||||
+1035
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: hello_vpi.c,v 1.3 2002/08/12 01:35:01 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file contains an example VPI module to demonstrate the tools
|
||||
* to create vpi modules. To compile this module, use the iverilog-vpi
|
||||
* command like so:
|
||||
*
|
||||
* iverilog-vpi hello_vpi.c
|
||||
*
|
||||
* The result is the hello_vpi.vpi module. See the hello_vpi.vl
|
||||
* program for example Verilog code to call this module.
|
||||
*/
|
||||
|
||||
# include <vpi_user.h>
|
||||
|
||||
static int my_hello_calltf(char *xx)
|
||||
{
|
||||
vpi_printf("Hello World, from VPI.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void my_hello_register()
|
||||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$my_hello";
|
||||
tf_data.calltf = my_hello_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a table of register functions. This table is the external
|
||||
* symbol that the simulator looks for when loading this .vpi module.
|
||||
*/
|
||||
void (*vlog_startup_routines[])() = {
|
||||
my_hello_register,
|
||||
0
|
||||
};
|
||||
/*
|
||||
* $Log: hello_vpi.c,v $
|
||||
* Revision 1.3 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/08/11 23:47:04 steve
|
||||
* Add missing Log and Ident strings.
|
||||
*
|
||||
* Revision 1.1 2002/04/18 03:25:16 steve
|
||||
* More examples.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Here we have the canonical "Hello, World" program written in Verilog,
|
||||
* with VPI. It uses the hello_vpi.vpi module that is compiled from
|
||||
* the hello_vpi.c program also in this directory. See the
|
||||
* hello_vpi.c for instructions on how to compile it.
|
||||
*
|
||||
* Compile this program with the command:
|
||||
*
|
||||
* iverilog -ohello_vpi hello_vpi.vl
|
||||
*
|
||||
* After churning for a little while, the program will create the output
|
||||
* file "hello" which is compiled, linked and ready to run. Run this
|
||||
* program like so:
|
||||
*
|
||||
* vvp -M. -mhello_vpi hello_vpi
|
||||
*
|
||||
* and the program will print the message to its output. Easy! For
|
||||
* more on how to make the iverilog command work, see the iverilog
|
||||
* manual page.
|
||||
*/
|
||||
|
||||
module main();
|
||||
|
||||
initial
|
||||
begin
|
||||
$my_hello;
|
||||
$finish ;
|
||||
end
|
||||
|
||||
endmodule
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
*
|
||||
* To compile this for XNF, try a command like this:
|
||||
*
|
||||
* iverilog -txnf -fpart=XC4010XLPQ160 -ooutff.xnf -fncf=outff.ncf outff.v
|
||||
* iverilog -txnf -ppart=XC4010XLPQ160 -ooutff.xnf -pncf=outff.ncf outff.v
|
||||
*
|
||||
* That command causes an outff.xnf and outff.ncf file to be created.
|
||||
* Next, make the outff.ngd file with the command:
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
* pin assignments locked down by design. The command to compile this
|
||||
* into a jedec file is;
|
||||
*
|
||||
* iverilog -tpal -fpart=generic-22v10-plcc -opal_reg.jed pal_reg.v
|
||||
* iverilog -tpal -ppart=generic-22v10-plcc -opal_reg.jed pal_reg.v
|
||||
*
|
||||
* The output file name (passed through the -o<file> switch) can be
|
||||
* any file you desire. If the compilation and fittin all succeed, the
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
* To view the output generated by running show_vcd, start the GTKWave
|
||||
* viewer with the command:
|
||||
*
|
||||
* wave show_vcd.vcd
|
||||
* gtkwave show_vcd.vcd
|
||||
*
|
||||
* The GTKWave program will display its main window, and show in a small
|
||||
* status box (upper left corner) that it succeeded in loading the dump
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
*
|
||||
* To compile this for XNF, try a command like this:
|
||||
*
|
||||
* iverilog -txnf -fpart=XC4010XLPQ160 -fncf=xnf_add.ncf -oxnf_add.xnf xnf_add.v
|
||||
* iverilog -txnf -ppart=XC4010XLPQ160 -pncf=xnf_add.ncf -oxnf_add.xnf xnf_add.v
|
||||
*
|
||||
* That command causes an xnf_add.xnf and xnf_add.ncf file to be created.
|
||||
* Next, Use Xilinx Alliance or Foundation tools to make the xnf_add.ngd
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
// This example describes a 16x1 RAM that can be synthesized into
|
||||
// a CLB ram in a Xilinx FPGA.
|
||||
|
||||
module ram16x1 (q, d, a, we, wclk);
|
||||
output q;
|
||||
input d;
|
||||
input [3:0] a;
|
||||
input we;
|
||||
input wclk;
|
||||
|
||||
reg mem[15:0];
|
||||
|
||||
assign q = mem[a];
|
||||
always @(posedge wclk) if (we) mem[a] = d;
|
||||
|
||||
endmodule /* ram16x1 */
|
||||
|
||||
module main;
|
||||
wire q;
|
||||
reg d;
|
||||
reg [3:0] a;
|
||||
reg we, wclk;
|
||||
|
||||
ram16x1 r1 (q, d, a, we, wclk);
|
||||
|
||||
initial begin
|
||||
$monitor("q = %b", q);
|
||||
d = 0;
|
||||
wclk = 0;
|
||||
a = 5;
|
||||
we = 1;
|
||||
#1 wclk = 1;
|
||||
#1 wclk = 0;
|
||||
end
|
||||
endmodule /* main */
|
||||
+251
-23
@@ -16,12 +16,16 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: expr_synth.cc,v 1.18 2000/11/29 23:16:18 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: expr_synth.cc,v 1.36 2002/08/12 01:34:59 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,18 @@ 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);
|
||||
osig->local_flag(true);
|
||||
|
||||
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));
|
||||
@@ -58,10 +63,10 @@ NetNet* NetEBAdd::synthesize(Design*des)
|
||||
|
||||
switch (op()) {
|
||||
case '+':
|
||||
adder->attribute("LPM_Direction", "ADD");
|
||||
adder->attribute("LPM_Direction", verinum("ADD"));
|
||||
break;
|
||||
case '-':
|
||||
adder->attribute("LPM_Direction", "SUB");
|
||||
adder->attribute("LPM_Direction", verinum("SUB"));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -83,6 +88,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());
|
||||
@@ -92,6 +108,26 @@ NetNet* NetEBBits::synthesize(Design*des)
|
||||
string oname = des->local_symbol(path);
|
||||
NetLogic*gate;
|
||||
|
||||
/* If the rsig bit is constant, then look for special
|
||||
cases that I can use to reduce the generated
|
||||
logic. If I find one, then handle it immediately and
|
||||
skip the rest of the processing of this bit. */
|
||||
if (rsig->pin(idx).nexus()->drivers_constant()) {
|
||||
verinum::V bval = rsig->pin(idx).nexus()->driven_value();
|
||||
|
||||
/* (A & 0) is (0) */
|
||||
if ((op() == '&') && bval == verinum::V0) {
|
||||
connect(osig->pin(idx), rsig->pin(idx));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* (A & 1) is A */
|
||||
if ((op() == '&') && bval == verinum::V1) {
|
||||
connect(osig->pin(idx), lsig->pin(idx));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
switch (op()) {
|
||||
case '&':
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::AND);
|
||||
@@ -124,6 +160,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 +215,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 +247,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 +374,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_refs() == 0)
|
||||
delete tmp[idx-1];
|
||||
}
|
||||
|
||||
delete[]tmp;
|
||||
return osig;
|
||||
}
|
||||
|
||||
@@ -320,12 +412,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));
|
||||
|
||||
@@ -396,6 +488,26 @@ NetNet* NetEUReduce::synthesize(Design*des)
|
||||
NetLogic::AND);
|
||||
break;
|
||||
|
||||
case '|':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::OR);
|
||||
break;
|
||||
|
||||
case '^':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::XOR);
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::NAND);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::XNOR);
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Unable to synthesize " << *this << "." << endl;
|
||||
@@ -410,14 +522,20 @@ NetNet* NetEUReduce::synthesize(Design*des)
|
||||
return osig;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Synthesize a ?: operator an a NetMux device. Connect the condition
|
||||
* expression to the select input, then connect the true and false
|
||||
* expressions to the B and A inputs. This way, when the select input
|
||||
* is one, the B input, which is the true expression, is selected.
|
||||
*/
|
||||
NetNet* NetETernary::synthesize(Design *des)
|
||||
{
|
||||
string path = des->local_symbol("SYNTH");
|
||||
NetNet*csig = cond_->synthesize(des);
|
||||
NetNet*tsig = true_val_->synthesize(des);
|
||||
NetNet*fsig = false_val_->synthesize(des);
|
||||
|
||||
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();
|
||||
@@ -425,7 +543,7 @@ NetNet* NetETernary::synthesize(Design *des)
|
||||
osig->local_flag(true);
|
||||
|
||||
string oname = des->local_symbol(path);
|
||||
NetMux *mux = new NetMux(oname, width, 2, 1);
|
||||
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, 1);
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1) {
|
||||
connect(tsig->pin(idx), mux->pin_Data(idx, 1));
|
||||
connect(fsig->pin(idx), mux->pin_Data(idx, 0));
|
||||
@@ -437,13 +555,123 @@ 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.36 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.35 2002/07/07 22:31:39 steve
|
||||
* Smart synthesis of binary AND expressions.
|
||||
*
|
||||
* Revision 1.34 2002/07/05 21:26:17 steve
|
||||
* Avoid emitting to vvp local net symbols.
|
||||
*
|
||||
* Revision 1.33 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.32 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.31 2001/12/30 17:06:52 steve
|
||||
* Synthesize reduction logic.
|
||||
*
|
||||
* Revision 1.30 2001/12/18 05:34:02 steve
|
||||
* Comments about MUX synthesis.
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
* Revision 1.18 2000/11/29 23:16:18 steve
|
||||
* Do not delete synthesized signals used in expressions.
|
||||
*
|
||||
|
||||
+57
-118
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2002 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,10 +16,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: functor.cc,v 1.24 2000/11/19 20:48:30 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: functor.cc,v 1.31 2002/08/16 05:18:27 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
|
||||
@@ -110,7 +114,9 @@ void NetScope::run_functor(Design*des, functor_t*fun)
|
||||
void Design::functor(functor_t*fun)
|
||||
{
|
||||
// Scan the scopes
|
||||
root_scope_->run_functor(this, fun);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->run_functor(this, fun);
|
||||
|
||||
// apply to processes
|
||||
procs_idx_ = procs_;
|
||||
@@ -122,30 +128,31 @@ void Design::functor(functor_t*fun)
|
||||
|
||||
// apply to nodes
|
||||
if (nodes_) {
|
||||
assert(nodes_functor_cur_ == 0);
|
||||
assert(nodes_functor_nxt_ == 0);
|
||||
|
||||
/* Scan the circular list of nodes, starting with the
|
||||
front of the list. (nodes_ points to the *end* of the
|
||||
list.) The bar is the end point. At the end of the
|
||||
do-while loop, I know that the bar has been
|
||||
processed or (if bar == 0) no undeleted node has been
|
||||
processed. */
|
||||
NetNode*cur = nodes_->node_next_;
|
||||
NetNode*bar = 0;
|
||||
front of the list.
|
||||
|
||||
This loop interacts with the Design::del_node method
|
||||
so that the functor is free to delete any nodes it
|
||||
choose. The destructors of the NetNode objects call
|
||||
the del_node method, which checks with the
|
||||
nodes_functor_* members, to keep the iterator
|
||||
operating safely. */
|
||||
nodes_functor_cur_ = nodes_;
|
||||
do {
|
||||
NetNode*tmp = cur->node_next_;
|
||||
cur->functor_node(this, fun);
|
||||
nodes_functor_nxt_ = nodes_functor_cur_->node_next_;
|
||||
nodes_functor_cur_->functor_node(this, fun);
|
||||
|
||||
/* Detect the case that cur has been deleted by
|
||||
noticing if tmp->node_prev_ no longer points to
|
||||
cur. If that's the case, clear the bar. */
|
||||
if (tmp->node_prev_ != cur) {
|
||||
if (cur == bar)
|
||||
bar = 0;
|
||||
} else if (bar == 0) {
|
||||
bar = cur;
|
||||
}
|
||||
cur = tmp;
|
||||
if (nodes_functor_nxt_ == 0)
|
||||
break;
|
||||
|
||||
nodes_functor_cur_ = nodes_functor_nxt_;
|
||||
} while (nodes_ && (nodes_functor_cur_ != nodes_));
|
||||
nodes_functor_cur_ = 0;
|
||||
nodes_functor_nxt_ = 0;
|
||||
|
||||
} while (nodes_ && (cur != bar));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,35 +235,13 @@ int NetAssignNB::match_proc(proc_match_t*that)
|
||||
return that->assign_nb(this);
|
||||
}
|
||||
|
||||
int proc_match_t::assign_mem(NetAssignMem*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetAssignMem::match_proc(proc_match_t*that)
|
||||
{
|
||||
return that->assign_mem(this);
|
||||
}
|
||||
|
||||
int proc_match_t::assign_mem_nb(NetAssignMemNB*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetAssignMemNB::match_proc(proc_match_t*that)
|
||||
{
|
||||
return that->assign_mem_nb(this);
|
||||
}
|
||||
|
||||
int proc_match_t::block(NetBlock*)
|
||||
{
|
||||
cerr << "default (failing) match for block" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetBlock::match_proc(proc_match_t*that)
|
||||
{
|
||||
cerr << "NetBlock::match_proc" << endl;
|
||||
return that->block(this);
|
||||
}
|
||||
|
||||
@@ -282,6 +267,32 @@ int proc_match_t::event_wait(NetEvWait*)
|
||||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.31 2002/08/16 05:18:27 steve
|
||||
* Fix intermix of node functors and node delete.
|
||||
*
|
||||
* Revision 1.30 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.29 2002/08/10 22:07:38 steve
|
||||
* Remove useless error messages.
|
||||
*
|
||||
* Revision 1.28 2002/06/05 03:44:25 steve
|
||||
* Add support for memory words in l-value of
|
||||
* non-blocking assignments, and remove the special
|
||||
* NetAssignMem_ and NetAssignMemNB classes.
|
||||
*
|
||||
* Revision 1.27 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.26 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.25 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.24 2000/11/19 20:48:30 steve
|
||||
* Fix cases where signal iteration might die early.
|
||||
*
|
||||
@@ -293,77 +304,5 @@ int proc_match_t::event_wait(NetEvWait*)
|
||||
*
|
||||
* Revision 1.21 2000/08/01 02:48:41 steve
|
||||
* Support <= in synthesis of DFF and ram devices.
|
||||
*
|
||||
* Revision 1.20 2000/07/16 04:56:07 steve
|
||||
* Handle some edge cases during node scans.
|
||||
*
|
||||
* Revision 1.19 2000/07/15 05:13:43 steve
|
||||
* Detect muxing Vz as a bufufN.
|
||||
*
|
||||
* Revision 1.18 2000/05/02 00:58:12 steve
|
||||
* Move signal tables to the NetScope class.
|
||||
*
|
||||
* Revision 1.17 2000/04/20 00:28:03 steve
|
||||
* Catch some simple identity compareoptimizations.
|
||||
*
|
||||
* Revision 1.16 2000/04/18 04:50:19 steve
|
||||
* Clean up unneeded NetEvent objects.
|
||||
*
|
||||
* Revision 1.15 2000/04/16 23:32:18 steve
|
||||
* Synthesis of comparator in expressions.
|
||||
*
|
||||
* Connect the NetEvent and related classes
|
||||
* together better.
|
||||
*
|
||||
* Revision 1.14 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.13 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.12 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.11 2000/02/13 04:35:43 steve
|
||||
* Include some block matching from Larry.
|
||||
*
|
||||
* Revision 1.10 2000/01/13 03:35:35 steve
|
||||
* Multiplication all the way to simulation.
|
||||
*
|
||||
* Revision 1.9 2000/01/02 17:57:20 steve
|
||||
* Handle nodes running out during node scan.
|
||||
*
|
||||
* Revision 1.8 1999/12/30 04:19:12 steve
|
||||
* Propogate constant 0 in low bits of adders.
|
||||
*
|
||||
* Revision 1.7 1999/12/17 06:18:16 steve
|
||||
* Rewrite the cprop functor to use the functor_t interface.
|
||||
*
|
||||
* Revision 1.6 1999/12/05 02:24:08 steve
|
||||
* Synthesize LPM_RAM_DQ for writes into memories.
|
||||
*
|
||||
* Revision 1.5 1999/12/01 06:06:16 steve
|
||||
* Redo synth to use match_proc_t scanner.
|
||||
*
|
||||
* Revision 1.4 1999/11/18 03:52:19 steve
|
||||
* Turn NetTmp objects into normal local NetNet objects,
|
||||
* and add the nodangle functor to clean up the local
|
||||
* symbols generated by elaboration and other steps.
|
||||
*
|
||||
* Revision 1.3 1999/11/01 02:07:40 steve
|
||||
* Add the synth functor to do generic synthesis
|
||||
* and add the LPM_FF device to handle rows of
|
||||
* flip-flops.
|
||||
*
|
||||
* Revision 1.2 1999/07/18 05:52:46 steve
|
||||
* xnfsyn generates DFF objects for XNF output, and
|
||||
* properly rewrites the Design netlist in the process.
|
||||
*
|
||||
* Revision 1.1 1999/07/17 22:01:13 steve
|
||||
* Add the functor interface for functor transforms.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: functor.h,v 1.17 2000/09/17 21:26:15 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: functor.h,v 1.20 2002/08/12 01:34:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -83,9 +83,7 @@ struct proc_match_t {
|
||||
virtual ~proc_match_t();
|
||||
|
||||
virtual int assign(class NetAssign*);
|
||||
virtual int assign_mem(class NetAssignMem*);
|
||||
virtual int assign_nb(class NetAssignNB*);
|
||||
virtual int assign_mem_nb(class NetAssignMemNB*);
|
||||
virtual int condit(class NetCondit*);
|
||||
virtual int event_wait(class NetEvWait*);
|
||||
virtual int block(class NetBlock*);
|
||||
@@ -94,6 +92,19 @@ struct proc_match_t {
|
||||
|
||||
/*
|
||||
* $Log: functor.h,v $
|
||||
* Revision 1.20 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.19 2002/06/05 03:44:25 steve
|
||||
* Add support for memory words in l-value of
|
||||
* non-blocking assignments, and remove the special
|
||||
* NetAssignMem_ and NetAssignMemNB classes.
|
||||
*
|
||||
* Revision 1.18 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.17 2000/09/17 21:26:15 steve
|
||||
* Add support for modulus (Eric Aardoom)
|
||||
*
|
||||
@@ -108,32 +119,5 @@ struct proc_match_t {
|
||||
*
|
||||
* Revision 1.13 2000/04/20 00:28:03 steve
|
||||
* Catch some simple identity compareoptimizations.
|
||||
*
|
||||
* Revision 1.12 2000/04/18 04:50:19 steve
|
||||
* Clean up unneeded NetEvent objects.
|
||||
*
|
||||
* Revision 1.11 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.10 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.9 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.8 2000/02/13 04:35:43 steve
|
||||
* Include some block matching from Larry.
|
||||
*
|
||||
* Revision 1.7 2000/01/13 03:35:35 steve
|
||||
* Multiplication all the way to simulation.
|
||||
*
|
||||
* Revision 1.6 1999/12/30 04:19:12 steve
|
||||
* Propogate constant 0 in low bits of adders.
|
||||
*
|
||||
* Revision 1.5 1999/12/17 06:18:16 steve
|
||||
* Rewrite the cprop functor to use the functor_t interface.
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -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.
|
||||
|
||||
+234
-4
@@ -86,7 +86,7 @@ tool so it is not clear that the standard really is at fault. It is
|
||||
clear, however, that somebody goofed somewhere.
|
||||
|
||||
My personal opinion is that there is no logical need to require that
|
||||
all module_item_declarations preceed any other module items. I
|
||||
all module_item_declarations precede any other module items. I
|
||||
personally would oppose such a restriction. It may make sense to
|
||||
require that declarations of variables within a module be preceded by
|
||||
their use, although even that is not necessary for the implementation
|
||||
@@ -97,7 +97,7 @@ sample2 can have implications that affect any declaration order
|
||||
rules. When reaching into a module with a hierarchical name, the
|
||||
module being referenced is already completely declared (or not
|
||||
declared at all, as in sample2) so module_item order is completely
|
||||
irrelevent. But a "declare before use" rule would infect module
|
||||
irrelevant. But a "declare before use" rule would infect module
|
||||
ordering, by requiring that modules that are used be first defined.
|
||||
|
||||
|
||||
@@ -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 as reg or integer. Without this, there would be no
|
||||
portable way to pass integers into functions/tasks. The standard does
|
||||
not say it is allowed, but it doesn't *disallow* it, and other
|
||||
commercial tools seem to work similarly.
|
||||
|
||||
|
||||
* ROUNDING OF TIME
|
||||
|
||||
@@ -165,7 +172,7 @@ take it that x is allowed, as that is what Verilog-XL does.
|
||||
|
||||
There seems to be ambiguity in how code like this should be parsed:
|
||||
|
||||
repeat (5) @(posedge clk) <statment>;
|
||||
repeat (5) @(posedge clk) <statement>;
|
||||
|
||||
There are two valid interpretations of this code, from the
|
||||
IEEE1364-1995 standard. One looks like this:
|
||||
@@ -197,9 +204,232 @@ 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.
|
||||
|
||||
* UNKNOWN VALUES IN L-VALUE BIT SELECTS
|
||||
|
||||
Consider this example:
|
||||
|
||||
reg [7:0] vec;
|
||||
wire [4:0] idx = <expr>;
|
||||
[...]
|
||||
vec[idx] = 1;
|
||||
|
||||
So long as the value of idx is a valid bit select address, the
|
||||
behavior of this assignment is obvious. However, there is no explicit
|
||||
word in the standard as to what happens if the value is out of
|
||||
range. The standard clearly states the value of an expression when the
|
||||
bit-select or part select is out of range (the value is x) but does
|
||||
not address the behavior when the expression is an l-value.
|
||||
|
||||
Icarus Verilog will take the position that bit select expressions in
|
||||
the l-value will select oblivion if it is out of range. That is, if
|
||||
idx has a value that is not a valid bit select of vec, then the
|
||||
assignment will have no effect.
|
||||
|
||||
|
||||
* SCHEDULING VALUES IN LOGIC
|
||||
|
||||
The interaction between blocking assignments in procedural code and
|
||||
logic gates in gate-level code and expressions is poorly defined in
|
||||
Verilog. Consider this example:
|
||||
|
||||
reg a;
|
||||
reg b;
|
||||
wire q = a & b;
|
||||
|
||||
initial begin
|
||||
a = 1;
|
||||
b = 0;
|
||||
#1 b = 1;
|
||||
if (q !== 0) begin
|
||||
$display("FAILED -- q changed too soon? %b", q);
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
This is a confusing situation. It is clear from the Verilog standard
|
||||
that an assignment to a variable using a blocking assign causes the
|
||||
l-value to receive the value before the assignment completes. This
|
||||
means that a subsequent read of the assigned variable *must* read back
|
||||
what was blocking-assigned.
|
||||
|
||||
However, in the example above, the "wire q = a & b" expresses some
|
||||
gate logic between a/b and q. The standard does not say whether a read
|
||||
out of logic should read the value computed from previous assigns to
|
||||
the input from the same thread. Specifically, when "a" and "b" are
|
||||
assigned by blocking assignments, will a read of "q" get the computed
|
||||
value or the existing value?
|
||||
|
||||
In fact, existing commercial tools do it both ways. Some tools print
|
||||
the FAILED message in the above example, and some do not. Icarus
|
||||
Verilog does not print the FAILED message in the above example,
|
||||
because the gate value change is *scheduled* when inputs are assigned,
|
||||
but not propagated until the thread gives up the processor.
|
||||
|
||||
Icarus Verilog chooses this behavior in order to filter out zero-width
|
||||
pulses as early as possible. The implication of this is that a read of
|
||||
the output of combinational logic will most likely *not* reflect the
|
||||
changes in inputs until the thread that changed the inputs yields
|
||||
execution.
|
||||
|
||||
|
||||
* BIT AND PART SELECTS OF PARAMETERS
|
||||
|
||||
Bit and part selects are supposed to only be supported on vector nets
|
||||
and variables (wires, regs, etc.) However, it is common for Verilog
|
||||
compilers to also support bit and part select on parameters. Icarus
|
||||
Verilog also chooses to support bit and part selects on parameter
|
||||
names, but we need to define what that means.
|
||||
|
||||
A bit or a part select on a parameter expression returns an unsigned
|
||||
value with a defined size. The parameter value is considered be a
|
||||
constant vector of bits foo[X:0]. That is, zero based. The bit and
|
||||
part selects operate from that assumption.
|
||||
|
||||
Verilog 2001 adds syntax to allow the user to explicitly declare the
|
||||
parameter range (i.e. parameter [5:0] foo = 9;) so Icarus Verilog will
|
||||
(or should) use the explicitly declared vector dimensions to interpret
|
||||
bit and part selects.
|
||||
|
||||
$Id: ieee1364-notes.txt,v 1.13 2002/08/20 04:11:53 steve Exp $
|
||||
$Log: ieee1364-notes.txt,v $
|
||||
Revision 1.13 2002/08/20 04:11:53 steve
|
||||
Support parameters with defined ranges.
|
||||
|
||||
Revision 1.12 2002/06/11 03:34:33 steve
|
||||
Spelling patch (Larry Doolittle)
|
||||
|
||||
Revision 1.11 2002/04/27 02:38:04 steve
|
||||
Support selecting bits from parameters.
|
||||
|
||||
Revision 1.10 2002/03/31 01:54:13 steve
|
||||
Notes about scheduling
|
||||
|
||||
Revision 1.9 2002/01/26 02:08:07 steve
|
||||
Handle x in l-value of set/x
|
||||
|
||||
Revision 1.8 2001/08/01 05:17:31 steve
|
||||
Accept empty port lists to module instantiation.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
.TH iverilog-vpi 1 "$Date: 2002/07/05 17:17:20 $" Version "$Date: 2002/07/05 17:17:20 $"
|
||||
.SH NAME
|
||||
iverilog-vpi - Compile front end for VPI modules
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog-vpi
|
||||
[--name=\fIname\fP]
|
||||
\fIsourcefile\fP...
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fIiverilog-vpi\fP is a tool to simplify the compilation of VPI
|
||||
modules for use with Icarus Verilog. It takes on the command line a
|
||||
list of C or C++ source files, and generates as output a linked VPI
|
||||
module. See the \fBvvp\fP(1) man page for a description of how the
|
||||
linked module is loaded by a simulation.
|
||||
|
||||
The output is named after the first source file. For example, if the
|
||||
first source file is named \fIfoo.c\fP, the output becomes
|
||||
\fIfoo.vpi\fP.
|
||||
|
||||
.SH OPTIONS
|
||||
.l
|
||||
\fIiverilog-vpi\fP accepts the following options:
|
||||
.TP 8
|
||||
.B -l\fIlibrary\fP
|
||||
Include the named library in the link of the VPI module. This allows
|
||||
VPI modules to further reference external libraries.
|
||||
|
||||
.TP 8
|
||||
.B --name=\fIname\fP
|
||||
Normally, the output VPI module will be named after the first source
|
||||
file passed to the command. This flag sets the name (without the .vpi
|
||||
suffix) of the output vpi module.
|
||||
.SH "AUTHOR"
|
||||
.nf
|
||||
Steve Williams ([email protected])
|
||||
|
||||
.SH SEE ALSO
|
||||
iverilog(1), vvp(1),
|
||||
.BR "<http://www.icarus.com/eda/verilog/>"
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This source code is free software; you can redistribute it
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: iverilog-vpi.sh,v 1.9 2002/10/19 23:18:52 steve Exp $"
|
||||
|
||||
# These are the variables used for compiling files
|
||||
CC=gcc
|
||||
CXX=gcc
|
||||
CFLAGS="@PIC@ -O -I@INCLUDEDIR@"
|
||||
|
||||
# These are used for linking...
|
||||
LD=gcc
|
||||
LDFLAGS="@SHARED@"
|
||||
LDLIBS="-L@LIBDIR@ -lveriuser -lvpi"
|
||||
|
||||
CCSRC=
|
||||
CXSRC=
|
||||
OBJ=
|
||||
LIB=
|
||||
OUT=
|
||||
|
||||
# --
|
||||
# parse the command line switches. This collects the source files
|
||||
# and precompiled object files, and maybe user libraries. As we are
|
||||
# going, guess an output file name.
|
||||
for parm
|
||||
do
|
||||
case $parm
|
||||
in
|
||||
|
||||
*.c) CCSRC="$CCSRC $parm"
|
||||
if [ x$OUT = x ]; then
|
||||
OUT=`basename $parm .c`
|
||||
fi
|
||||
;;
|
||||
|
||||
*.cc) CXSRC="$CXSRC $parm"
|
||||
if [ x$OUT = x ]; then
|
||||
OUT=`basename $parm .cc`
|
||||
fi
|
||||
;;
|
||||
|
||||
*.o) OBJ="$OBJ $parm"
|
||||
if [ x$OUT = x ]; then
|
||||
OUT=`basename $parm .o`
|
||||
fi
|
||||
;;
|
||||
|
||||
--name=*)
|
||||
OUT=`echo $parm | cut -b8-`
|
||||
;;
|
||||
|
||||
-l*) LIB="$LIB $parm"
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
done
|
||||
|
||||
if [ x$OUT = x ]; then
|
||||
echo "Usage: $0 [src and obj files]..."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Put the .vpi on the result file.
|
||||
OUT=$OUT".vpi"
|
||||
|
||||
compile_errors=0
|
||||
|
||||
# Compile all the source files into object files
|
||||
for src in $CCSRC
|
||||
do
|
||||
base=`basename $src .c`
|
||||
obj=$base".o"
|
||||
|
||||
echo "Compiling $src..."
|
||||
$CC -c -o $obj $CFLAGS $src || compile_errors=`expr $compile_errors + 1`
|
||||
OBJ="$OBJ $obj"
|
||||
done
|
||||
|
||||
for src in $CXSRC
|
||||
do
|
||||
base=`basename $src .cc`
|
||||
obj=$base".o"
|
||||
|
||||
echo "Compiling $src..."
|
||||
$CXX -c -o $obj $CFLAGS $src || compile_errors=`expr $compile_errors + 1`
|
||||
OBJ="$OBJ $obj"
|
||||
done
|
||||
|
||||
if test $compile_errors -gt 0
|
||||
then
|
||||
echo "Some ($compile_errors) files failed to compile."
|
||||
exit $compile_errors
|
||||
fi
|
||||
|
||||
echo "Making $OUT from $OBJ..."
|
||||
exec $LD -o $OUT $LDFLAGS $OBJ $LIB $LDLIBS
|
||||
+20
-11
@@ -28,10 +28,16 @@
|
||||
#
|
||||
# %B Substitute the base libdir, -B flag of iverilog.
|
||||
#
|
||||
# %C Substitute the path to the temporary config file.
|
||||
#
|
||||
# %f Substitute the -f flags from the command line.
|
||||
#
|
||||
# %g Substitule the -g flag
|
||||
#
|
||||
# %s Substitute the start module (-s flag) from the user.
|
||||
#
|
||||
# %M Substitute the value of the -M<depfile> flag.
|
||||
#
|
||||
# %N Substitute the value of the -N<path> flag.
|
||||
#
|
||||
# %o Substitute the value of the -o<path> flag, or the default
|
||||
@@ -56,29 +62,32 @@
|
||||
# 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] -C%C %g %W %s %[M-M%M] %[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] -C%C %g %W %s %[M-M%M] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- -
|
||||
|
||||
# --
|
||||
# The vvm target uses the <ivl> string to take the preprocessed code from
|
||||
# standard input, compile it with the vvm code generator and write the
|
||||
# result to %o.cc. The driver assumes this when invoking the C++ compiler
|
||||
# on the result.
|
||||
# The vvp target generates code that the vvp simulation engine can execute.
|
||||
# These rules support synthesized and non-synthesized variants.
|
||||
|
||||
[-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 -- -
|
||||
[-tvvp -S]
|
||||
<ivl>%B/ivl %[v-v] -C%C %g %W %s %[M-M%M] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fsynth2 -Fsynth -Fsyn-rules -Fcprop -Fnodangle %f %m -o%o -- -
|
||||
|
||||
[-tvvp]
|
||||
<ivl>%B/ivl %[v-v] -C%C %g %W %s %[M-M%M] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fcprop -Fnodangle %f %m -o%o -- -
|
||||
|
||||
# -- (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 -C%C %[v-v] %g %s %[M-M%M] %[N-N%N] %[T-T%T] -txnf -Fsynth2 -Fsynth -Fsyn-rules -Fxnfio -Fcprop -Fnodangle -o%o -- -
|
||||
|
||||
# And this is another XNF code generator, under development.
|
||||
[-tfpga]
|
||||
<ivl>%B/ivl -C%C %[v-v] %g %s %[M-M%M] %[N-N%N] %[T-T%T] %f -tdll -fDLL=%B/fpga.tgt -Fsynth2 -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 -C%C %[v-v] %g %s %[M-M%M] %[N-N%N] %[T-T%T] %f -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,71 +35,142 @@ 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_attr_cnt
|
||||
ivl_logic_attr_val
|
||||
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_aset_value
|
||||
ivl_lpm_async_clr
|
||||
ivl_lpm_async_set
|
||||
ivl_lpm_basename
|
||||
ivl_lpm_clk
|
||||
ivl_lpm_data
|
||||
ivl_lpm_datab
|
||||
ivl_lpm_data2
|
||||
ivl_lpm_data2_width
|
||||
ivl_lpm_define
|
||||
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_root
|
||||
ivl_memory_scope
|
||||
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
|
||||
ivl_scope_tname
|
||||
|
||||
ivl_signal_attr
|
||||
ivl_signal_attr_cnt
|
||||
ivl_signal_attr_val
|
||||
ivl_signal_integer
|
||||
ivl_signal_local
|
||||
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_attr_cnt
|
||||
ivl_process_attr_val
|
||||
ivl_process_scope
|
||||
ivl_process_stmt
|
||||
ivl_process_type
|
||||
|
||||
ivl_statement_type
|
||||
|
||||
ivl_stmt_block_count
|
||||
ivl_stmt_block_scope
|
||||
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
|
||||
|
||||
+590
-135
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
||||
|
||||
Icarus Verilog LOADABLE TARGET API (ivl_target)
|
||||
|
||||
Copyright 2002 Stephen Williams <[email protected]>
|
||||
$Id: ivl_target.txt,v 1.3 2002/06/11 03:34:33 steve Exp $
|
||||
|
||||
|
||||
The ivl_target API is the interface available to modules that the
|
||||
Icarus Verilog compiler loads to act as a code generator. The API
|
||||
provides an interface to the elaborated, possibly synthesized, design
|
||||
for code generators that are intended to write netlist files or
|
||||
executable programs.
|
||||
|
||||
The functions and types of the API are summarized in the ivl_target.h
|
||||
header file. This document describes how the functions and types of
|
||||
the API are used to access and interpret the netlist of the design.
|
||||
|
||||
|
||||
LPM DEVICES
|
||||
|
||||
All LPM devices support a small set of common LPM functions, as
|
||||
described in the ivl_target header file. The ivl_lpm_t object has a
|
||||
type enumerated by ivl_lpm_type_t, and that type is accessible via the
|
||||
ivl_lpm_type function.
|
||||
|
||||
The following are type specific aspects of LPM devices.
|
||||
|
||||
* IVL_LPM_UFUNC
|
||||
|
||||
This LPM represents a user defined function. It is a way to connect
|
||||
behavioral code into a structural network. The UFUNC device has a
|
||||
vector output and a set of inputs. The ivl_lpm_define function returns
|
||||
the definition as an ivl_scope_t object.
|
||||
|
||||
The output vector is accessible through the ivl_lpm_q, and the output
|
||||
has the width defined by ivl_lpm_width. This similar to most every
|
||||
other LPM device with outputs.
|
||||
|
||||
There are ivl_lpm_size() input ports, each with the width
|
||||
ivl_lpm_data2_width(). The actual nexus is indexed by ivl_lpm_data2().
|
||||
|
||||
$Log: ivl_target.txt,v $
|
||||
Revision 1.3 2002/06/11 03:34:33 steve
|
||||
Spelling patch (Larry Doolittle)
|
||||
|
||||
Revision 1.2 2002/03/17 19:31:17 steve
|
||||
Add API to support user defined function.
|
||||
|
||||
Revision 1.1 2002/03/09 02:10:22 steve
|
||||
Add the NetUserFunc netlist node.
|
||||
|
||||
+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
|
||||
|
||||
|
||||
+10
-2
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: globals.h,v 1.5 2000/09/13 22:33:13 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: globals.h,v 1.7 2002/08/12 01:35:02 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
@@ -37,11 +37,19 @@ extern int line_direct_flag;
|
||||
|
||||
extern unsigned error_count;
|
||||
|
||||
extern FILE *depend_file;
|
||||
|
||||
/* This is the entry to the parser. */
|
||||
extern int yyparse();
|
||||
|
||||
/*
|
||||
* $Log: globals.h,v $
|
||||
* Revision 1.7 2002/08/12 01:35:02 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2002/04/04 05:26:13 steve
|
||||
* Add dependency generation.
|
||||
*
|
||||
* Revision 1.5 2000/09/13 22:33:13 steve
|
||||
* undefined macros are null (with warnings.)
|
||||
*
|
||||
|
||||
+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.
|
||||
|
||||
|
||||
+187
-40
@@ -1,7 +1,7 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1999 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2002 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -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.21 2000/09/13 22:33:13 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.35 2002/09/25 02:23:08 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>
|
||||
|
||||
@@ -38,6 +43,7 @@ static void def_start();
|
||||
static void def_finish();
|
||||
static void def_undefine();
|
||||
static void do_define();
|
||||
static int def_is_done();
|
||||
static int is_defined(const char*name);
|
||||
|
||||
static void include_filename();
|
||||
@@ -61,6 +67,8 @@ struct include_stack_t {
|
||||
struct include_stack_t*next;
|
||||
};
|
||||
|
||||
static void emit_pathline(struct include_stack_t *isp);
|
||||
|
||||
static struct include_stack_t*file_queue = 0;
|
||||
static struct include_stack_t*istack = 0;
|
||||
static struct include_stack_t*standby = 0;
|
||||
@@ -84,7 +92,9 @@ static int comment_enter = 0;
|
||||
%x PPINCLUDE
|
||||
%x PPDEFINE
|
||||
%x CCOMMENT
|
||||
%x PCOMENT
|
||||
%x CSTRING
|
||||
%x ERROR_LINE
|
||||
|
||||
%x IFDEF_FALSE
|
||||
%s IFDEF_TRUE
|
||||
@@ -105,6 +115,15 @@ W [ \t\b\f]+
|
||||
<CCOMMENT>\n { istack->lineno += 1; ECHO; }
|
||||
<CCOMMENT>"*/" { BEGIN(comment_enter); ECHO; }
|
||||
|
||||
/* Detect and pass multiline pragma comments. As with C-style
|
||||
comments, pragma comments are passed through, and CPP directives
|
||||
contained within are ignored. */
|
||||
|
||||
"(*" { comment_enter = YY_START; BEGIN(PCOMENT); ECHO; }
|
||||
<PCOMENT>. { ECHO; }
|
||||
<PCOMENT>\n { istack->lineno += 1; ECHO; }
|
||||
<PCOMENT>"*)" { BEGIN(comment_enter); ECHO; }
|
||||
|
||||
/* Strings do not contain macros or preprocessor directives. */
|
||||
\" { comment_enter = YY_START; BEGIN(CSTRING); ECHO; }
|
||||
<CSTRING>\\\" { yymore(); }
|
||||
@@ -118,6 +137,7 @@ W [ \t\b\f]+
|
||||
|
||||
^{W}?`include { yy_push_state(PPINCLUDE); }
|
||||
|
||||
<PPINCLUDE>`[a-zA-Z][a-zA-Z0-9_]* { def_match(); }
|
||||
<PPINCLUDE>\"[^\"]*\" { include_filename(); }
|
||||
|
||||
<PPINCLUDE>[ \t\b\f] { ; }
|
||||
@@ -136,23 +156,37 @@ W [ \t\b\f]+
|
||||
<PPINCLUDE>\n\r { istack->lineno += 1; yy_pop_state(); do_include(); }
|
||||
<PPINCLUDE><<EOF>> { istack->lineno += 1; yy_pop_state(); do_include(); }
|
||||
|
||||
/* Anything that is not matched by the above is an error of some
|
||||
sort. Print and error message and absorb the rest of the line. */
|
||||
<PPINCLUDE>. {
|
||||
emit_pathline(istack);
|
||||
fprintf(stderr, "error: malformed `include directive."
|
||||
" Did you quote the file name?\n");
|
||||
error_count += 1;
|
||||
BEGIN(ERROR_LINE); }
|
||||
|
||||
/* Detect the define directive, and match the name. Match any
|
||||
white space that might be found, as well. After I get the
|
||||
directive and the name, go into PPDEFINE mode and prepare to
|
||||
collect the defined value. */
|
||||
|
||||
`define{W}[a-zA-Z][a-zA-Z0-9_]*{W}? { yy_push_state(PPDEFINE); def_start(); }
|
||||
`define{W}[a-zA-Z_][a-zA-Z0-9_$]*{W}? { yy_push_state(PPDEFINE); def_start(); }
|
||||
|
||||
<PPDEFINE>.* { do_define(); }
|
||||
|
||||
<PPDEFINE>(\n|"\r\n"|"\n\r") {
|
||||
def_finish();
|
||||
istack->lineno += 1;
|
||||
fputc('\n', yyout);
|
||||
yy_pop_state();
|
||||
<PPDEFINE>.* {
|
||||
do_define();
|
||||
}
|
||||
|
||||
<PPDEFINE>(\n|"\r\n"|"\n\r") {
|
||||
if (def_is_done()) {
|
||||
def_finish();
|
||||
istack->lineno += 1;
|
||||
yy_pop_state();
|
||||
}
|
||||
fputc('\n', yyout);
|
||||
}
|
||||
|
||||
/* If the define is terminated by an EOF, then finish the define
|
||||
whether there was a continuation or not. */
|
||||
<PPDEFINE><<EOF>> {
|
||||
def_finish();
|
||||
istack->lineno += 1;
|
||||
@@ -160,7 +194,7 @@ W [ \t\b\f]+
|
||||
yy_pop_state();
|
||||
}
|
||||
|
||||
`undef{W}[a-zA-Z][a-zA-Z0-9_]*{W}?.* { def_undefine(); }
|
||||
`undef{W}[a-zA-Z_][a-zA-Z0-9_$]*{W}?.* { def_undefine(); }
|
||||
|
||||
|
||||
/* Detect conditional compilation directives, and parse them. If I
|
||||
@@ -172,12 +206,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_]*.* {
|
||||
`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);
|
||||
@@ -186,21 +219,35 @@ W [ \t\b\f]+
|
||||
}
|
||||
}
|
||||
|
||||
<IFDEF_FALSE,IFDEF_SUPR>^{W}?`ifdef{W}.* { yy_push_state(IFDEF_SUPR); }
|
||||
`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>`ifdef{W} { yy_push_state(IFDEF_SUPR); }
|
||||
<IFDEF_FALSE,IFDEF_SUPR>`ifndef{W} { yy_push_state(IFDEF_SUPR); }
|
||||
|
||||
<IFDEF_TRUE>`else { BEGIN(IFDEF_FALSE); }
|
||||
<IFDEF_FALSE>`else { BEGIN(IFDEF_TRUE); }
|
||||
<IFDEF_SUPR>`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>`endif {
|
||||
yy_pop_state();
|
||||
}
|
||||
|
||||
/* This pattern notices macros and arranges for them to be replaced. */
|
||||
`[a-zA-Z][a-zA-Z0-9_]* { def_match(); }
|
||||
`[a-zA-Z][a-zA-Z0-9_$]* { def_match(); }
|
||||
|
||||
/* Any text that is not a directive just gets passed through to the
|
||||
output. Very easy. */
|
||||
@@ -208,6 +255,9 @@ W [ \t\b\f]+
|
||||
. { ECHO; }
|
||||
\n { istack->lineno += 1; ECHO; }
|
||||
|
||||
/* Absorb the rest of the line when a broken directive is detected. */
|
||||
<ERROR_LINE>.* { yy_pop_state(); }
|
||||
|
||||
%%
|
||||
/* Defined macros are kept in this table for convenient lookup. As
|
||||
`define directives are matched (and the do_define() function
|
||||
@@ -272,9 +322,9 @@ static void def_match()
|
||||
yy_switch_to_buffer(yy_new_buffer(istack->file, YY_BUF_SIZE));
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "%s:%u: warning: macro %s undefined "
|
||||
"(and assumed null) at this point.\n",
|
||||
istack->path, istack->lineno, yytext);
|
||||
emit_pathline(istack);
|
||||
fprintf(stderr, "warning: macro %s undefined "
|
||||
"(and assumed null) at this point.\n", yytext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,33 +381,98 @@ void define_macro(const char*name, const char*value, int keyword)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The do_define function accumulates the defined value in these
|
||||
* variables. When the define is over, the def_finish() function
|
||||
* executes the define and clears this text. The define_continue_flag
|
||||
* is set if do_define detects that the definition is to be continued
|
||||
* on the next line.
|
||||
*/
|
||||
static char* define_text = 0;
|
||||
static size_t define_cnt = 0;
|
||||
|
||||
static int define_continue_flag = 0;
|
||||
|
||||
/*
|
||||
* Collect the definition. Normally, this returns 0. If there is a
|
||||
* continuation, then return 1 and this function may be called again
|
||||
* to collect another line of the definition.
|
||||
*/
|
||||
static void do_define()
|
||||
{
|
||||
char *cp;
|
||||
|
||||
define_continue_flag = 0;
|
||||
|
||||
/* FIXME: This strips trailing line comments out of the
|
||||
definition. It's not adequate as the "//" may have been
|
||||
quoted or commented, but it'll do for now. */
|
||||
char *cp;
|
||||
if(cp = strstr(yytext, "//"))
|
||||
*cp = 0;
|
||||
|
||||
/* Trim trailing white space. */
|
||||
cp = yytext + strlen(yytext);
|
||||
while (cp > yytext) {
|
||||
cp -= 1;
|
||||
if (!isspace(*cp))
|
||||
if (!isspace(cp[-1]))
|
||||
break;
|
||||
|
||||
cp -= 1;
|
||||
*cp = 0;
|
||||
}
|
||||
|
||||
define_macro(def_name, yytext, 0);
|
||||
def_name[0] = 0;
|
||||
/* Detect the continuation sequence. If I find it, remove it
|
||||
and the white space that preceeds it, then replace all that
|
||||
with a single newline. */
|
||||
if ((cp > yytext) && (cp[-1] == '\\')) {
|
||||
|
||||
cp -= 1;
|
||||
cp[0] = 0;
|
||||
while ((cp > yytext) && isspace(cp[-1])) {
|
||||
cp -= 1;
|
||||
*cp = 0;
|
||||
}
|
||||
|
||||
*cp++ = '\n';
|
||||
*cp = 0;
|
||||
define_continue_flag = 1;
|
||||
}
|
||||
|
||||
/* Accumulate this text into the define_text string. */
|
||||
define_text = realloc(define_text, define_cnt + (cp-yytext) + 1);
|
||||
strcpy(define_text+define_cnt, yytext);
|
||||
define_cnt += cp-yytext;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the definition text is done. This is the opposite of
|
||||
* the define_continue_flag.
|
||||
*/
|
||||
static int def_is_done()
|
||||
{
|
||||
return define_continue_flag? 0 : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* After some number of calls to do_define, this function is called to
|
||||
* assigned value to the parsed name. If there is no value, then
|
||||
* assign the string "1"
|
||||
*/
|
||||
static void def_finish()
|
||||
{
|
||||
if (def_name[0])
|
||||
define_macro(def_name, "1", 0);
|
||||
define_continue_flag = 0;
|
||||
|
||||
if (def_name[0]) {
|
||||
if (define_text) {
|
||||
define_macro(def_name, define_text, 0);
|
||||
free(define_text);
|
||||
define_text = 0;
|
||||
define_cnt = 0;
|
||||
|
||||
} else {
|
||||
define_macro(def_name, "1", 0);
|
||||
}
|
||||
def_name[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void def_undefine()
|
||||
@@ -463,12 +578,16 @@ 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()
|
||||
{
|
||||
assert(standby == 0);
|
||||
if(standby) {
|
||||
emit_pathline(istack);
|
||||
fprintf(stderr, "error: malformed `include directive. Extra junk on line?\n");
|
||||
exit(1);
|
||||
}
|
||||
standby = malloc(sizeof(struct include_stack_t));
|
||||
standby->path = strdup(yytext+1);
|
||||
standby->path[strlen(standby->path)-1] = 0;
|
||||
@@ -480,7 +599,9 @@ static void do_include()
|
||||
|
||||
if (standby->path[0] == '/') {
|
||||
standby->file = fopen(standby->path, "r");
|
||||
|
||||
if(depend_file && standby->file) {
|
||||
fprintf(depend_file, "%s\n", istack->path);
|
||||
}
|
||||
} else {
|
||||
unsigned idx = 0;
|
||||
standby->file = 0;
|
||||
@@ -488,14 +609,18 @@ static void do_include()
|
||||
char path[4096];
|
||||
sprintf(path, "%s/%s", include_dir[idx], standby->path);
|
||||
standby->file = fopen(path, "r");
|
||||
if (standby->file)
|
||||
if (standby->file) {
|
||||
if(depend_file) {
|
||||
fprintf(depend_file, "%s\n", path);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (standby->file == 0) {
|
||||
perror(standby->path);
|
||||
fprintf(stderr, "%s:%u: Include file %s not found\n",
|
||||
istack->path, istack->lineno, standby->path);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -507,8 +632,24 @@ 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);
|
||||
}
|
||||
|
||||
/* walk the include stack until we find an entry with a valid pathname,
|
||||
* and print the file and line from that entry for use in an error message.
|
||||
* The istack entries created by def_match() for macro expansions do not
|
||||
* contain pathnames. This finds instead the real file in which the outermost
|
||||
* macro was used.
|
||||
*/
|
||||
static void emit_pathline(struct include_stack_t*isp)
|
||||
{
|
||||
while(isp && (isp->path == NULL)) {
|
||||
isp = isp->next;
|
||||
}
|
||||
assert(isp);
|
||||
fprintf(stderr, "%s:%u: ",
|
||||
isp->path, isp->lineno+1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -560,7 +701,10 @@ 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);
|
||||
if(depend_file) {
|
||||
fprintf(depend_file, "%s\n", istack->path);
|
||||
}
|
||||
|
||||
yyrestart(istack->file);
|
||||
return 0;
|
||||
@@ -573,8 +717,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;
|
||||
}
|
||||
@@ -596,6 +740,9 @@ void reset_lexor(FILE*out, char*paths[])
|
||||
perror(paths[0]);
|
||||
exit(1);
|
||||
}
|
||||
if(depend_file) {
|
||||
fprintf(depend_file, "%s\n", paths[0]);
|
||||
}
|
||||
|
||||
yyout = out;
|
||||
|
||||
|
||||
+146
-10
@@ -16,10 +16,12 @@ const char COPYRIGHT[] =
|
||||
* 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: main.c,v 1.8 2000/12/06 05:15:21 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: main.c,v 1.16 2002/08/12 01:35:02 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,18 +52,81 @@ 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;
|
||||
|
||||
int line_direct_flag = 0;
|
||||
|
||||
unsigned error_count = 0;
|
||||
FILE *depend_file = NULL;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
char *dep_path = NULL;
|
||||
FILE*out;
|
||||
|
||||
/* Define preprocessor keywords that I plan to just pass. */
|
||||
@@ -84,7 +152,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:LM:o:v")) != EOF) switch (opt) {
|
||||
|
||||
case 'D': {
|
||||
char*tmp = strdup(optarg);
|
||||
@@ -99,6 +167,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);
|
||||
@@ -118,6 +194,14 @@ int main(int argc, char*argv[])
|
||||
line_direct_flag = 1;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
if (dep_path) {
|
||||
fprintf(stderr, "duplicate -M flag.\n");
|
||||
} else {
|
||||
dep_path = optarg;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
if (out_path) {
|
||||
fprintf(stderr, "duplicate -o flag.\n");
|
||||
@@ -138,21 +222,35 @@ 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"
|
||||
" -M<fil> - Write dependencies to <fil>\n"
|
||||
" -o<fil> - Send the output to <fil>\n"
|
||||
" -v - Print version information\n",
|
||||
argv[0]);
|
||||
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,20 +261,58 @@ int main(int argc, char*argv[])
|
||||
out = stdout;
|
||||
}
|
||||
|
||||
if (argv[optind] == 0) {
|
||||
if(dep_path) {
|
||||
depend_file = fopen(dep_path, "w");
|
||||
if (depend_file == 0) {
|
||||
perror(dep_path);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if(depend_file) {
|
||||
fclose(depend_file);
|
||||
}
|
||||
|
||||
return error_count;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: main.c,v $
|
||||
* Revision 1.16 2002/08/12 01:35:02 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.15 2002/04/04 05:26:13 steve
|
||||
* Add dependency generation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
|
||||
+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: parse.y,v 1.2 2000/08/20 17:49:05 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.3 2002/01/24 03:57:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
static void yyerror(const char*msg);
|
||||
%}
|
||||
|
||||
|
||||
@@ -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.73 2002/06/06 18:57:18 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
//# define YYSTYPE lexval
|
||||
|
||||
# include <iostream.h>
|
||||
# include <iostream>
|
||||
# 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
|
||||
@@ -73,15 +74,14 @@ static const char* set_file_name(char*text)
|
||||
}
|
||||
|
||||
|
||||
extern void pform_set_timescale(int, int);
|
||||
extern void pform_set_timescale(int, int, const char*file, unsigned line);
|
||||
|
||||
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);
|
||||
@@ -89,12 +89,15 @@ static verinum*make_unsized_dec(const char*txt);
|
||||
static verinum*make_unsized_octal(const char*txt);
|
||||
static verinum*make_unsized_hex(const char*txt);
|
||||
|
||||
static int dec_buf_div2(char *buf);
|
||||
|
||||
static void process_timescale(const char*txt);
|
||||
|
||||
static int comment_enter;
|
||||
%}
|
||||
|
||||
%x CCOMMENT
|
||||
%x PCOMMENT
|
||||
%x LCOMMENT
|
||||
%x CSTRING
|
||||
%s UDPTABLE
|
||||
@@ -110,15 +113,24 @@ W [ \t\b\f\r]+
|
||||
[ \t\b\f\r] { ; }
|
||||
\n { yylloc.first_line += 1; }
|
||||
|
||||
/* C++ style comments start with / / and run to the ene of the
|
||||
current line. These are very easy to handle. */
|
||||
|
||||
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
|
||||
<LCOMMENT>. { yymore(); }
|
||||
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
|
||||
|
||||
|
||||
/* The contents of C-style comments are ignored, like white space. */
|
||||
|
||||
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
|
||||
<CCOMMENT>. { yymore(); }
|
||||
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
|
||||
<CCOMMENT>"*/" { BEGIN(comment_enter); }
|
||||
|
||||
|
||||
"(*" { return K_PSTAR; }
|
||||
"*)" { return K_STARP; }
|
||||
"<<" { return K_LS; }
|
||||
">>" { return K_RS; }
|
||||
"<=" { return K_LE; }
|
||||
@@ -131,11 +143,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 +173,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);
|
||||
\\[^ \t\b\f\r\n]+ {
|
||||
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; }
|
||||
@@ -224,19 +250,38 @@ W [ \t\b\f\r]+
|
||||
return NUMBER; }
|
||||
|
||||
[0-9][0-9_]* {
|
||||
/* Handle the special case of the unsized decimal number. */
|
||||
unsigned long value = 0;
|
||||
for (const char*cp = yytext ; *cp ; cp += 1) {
|
||||
if (*cp != '_')
|
||||
value = 10 * value + (*cp - '0');
|
||||
char buf[4096];
|
||||
|
||||
if (strlen(yytext) >= sizeof(buf)-2){
|
||||
fprintf(stderr, "Ridicilously long decimal constant will be truncated!\n");
|
||||
}
|
||||
|
||||
assert(INTEGER_WIDTH <= (8*sizeof(value)));
|
||||
unsigned nbits = INTEGER_WIDTH;
|
||||
verinum::V*bits = new verinum::V[8 * sizeof value];
|
||||
strncpy(buf, yytext, sizeof(buf)-2);
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < nbits ; idx += 1, value >>= 1) {
|
||||
bits[idx] = (value&1) ? verinum::V1 : verinum::V0;
|
||||
/* Convert the decimal number to a binary value, one digit at
|
||||
a time. Watch out for overflow. */
|
||||
verinum::V*bits = new verinum::V[INTEGER_WIDTH];
|
||||
unsigned idx=0;
|
||||
unsigned nbits=INTEGER_WIDTH;
|
||||
|
||||
while(idx<nbits){
|
||||
int rem = dec_buf_div2(buf);
|
||||
|
||||
bits[idx] = (rem==1) ? verinum::V1 : verinum::V0;
|
||||
++idx;
|
||||
}
|
||||
|
||||
for(; idx<nbits; ++idx){
|
||||
bits[idx] = verinum::V0;
|
||||
}
|
||||
|
||||
/* If we run out of bits to hold the value, but there are
|
||||
still valueable bits in the number, print a warning. */
|
||||
if (strcmp(buf, "0") != 0){
|
||||
cerr << yylloc.text << ":" << yylloc.first_line <<
|
||||
": warning: Numeric decimal constant ``" << yytext <<
|
||||
"'' truncated to " << nbits << " bits." << endl;
|
||||
}
|
||||
|
||||
yylval.number = new verinum(bits, nbits, false);
|
||||
@@ -255,7 +300,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 +310,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 +766,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;
|
||||
@@ -807,13 +852,65 @@ static verinum*make_unsized_hex(const char*txt)
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/* Divide the integer given by the string by 2. Return the remainder bit. */
|
||||
static int dec_buf_div2(char *buf)
|
||||
{
|
||||
int partial;
|
||||
int len = strlen(buf);
|
||||
char *dst_ptr;
|
||||
int pos;
|
||||
|
||||
partial = 0;
|
||||
pos = 0;
|
||||
|
||||
/* dst_ptr overwrites buf, but all characters that are overwritten
|
||||
were already used by the reader. */
|
||||
dst_ptr = buf;
|
||||
|
||||
while(buf[pos] == '0')
|
||||
++pos;
|
||||
|
||||
for(; pos<len; ++pos){
|
||||
if (buf[pos]=='_')
|
||||
continue;
|
||||
|
||||
assert(isdigit(buf[pos]));
|
||||
|
||||
partial= partial*10 + (buf[pos]-'0');
|
||||
|
||||
if (partial >= 2){
|
||||
*dst_ptr = partial/2 + '0';
|
||||
partial = partial & 1;
|
||||
|
||||
++dst_ptr;
|
||||
}
|
||||
else{
|
||||
*dst_ptr = '0';
|
||||
++dst_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
// If result of division was zero string, it should remain that way.
|
||||
// Don't eat the last zero...
|
||||
if (dst_ptr == buf){
|
||||
*dst_ptr = '0';
|
||||
++dst_ptr;
|
||||
}
|
||||
*dst_ptr = 0;
|
||||
|
||||
return partial;
|
||||
}
|
||||
|
||||
/*
|
||||
* Making a decimal number is much easier then the other base numbers
|
||||
* because there are no z or x values to worry about.
|
||||
*/
|
||||
static verinum*make_dec_with_size(unsigned size, bool fixed, const char*ptr)
|
||||
{
|
||||
char buf[4096];
|
||||
bool signed_flag = false;
|
||||
|
||||
if (tolower(*ptr) == 's') {
|
||||
signed_flag = true;
|
||||
ptr += 1;
|
||||
@@ -824,40 +921,36 @@ static verinum*make_dec_with_size(unsigned size, bool fixed, const char*ptr)
|
||||
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
||||
ptr += 1;
|
||||
|
||||
const char*digits = ptr;
|
||||
|
||||
/* Convert the decimal number to a binary value, one digit at
|
||||
a time. Watch out for overflow. */
|
||||
|
||||
unsigned long value = 0;
|
||||
for ( ; *ptr ; ptr += 1)
|
||||
if (isdigit(*ptr)) {
|
||||
unsigned long tmp = value * 10 + (*ptr - '0');
|
||||
if (tmp < value)
|
||||
cerr << yylloc.text << ":" << yylloc.first_line <<
|
||||
": warning: Numeric decimal constant ``"
|
||||
<< digits << "'' is too large." << endl;
|
||||
value *= 10;
|
||||
value += *ptr - '0';
|
||||
} else {
|
||||
assert(*ptr == '_');
|
||||
}
|
||||
|
||||
|
||||
verinum::V*bits = new verinum::V[size];
|
||||
|
||||
for (unsigned idx = 0 ; idx < size ; idx += 1) {
|
||||
bits[idx] = (value&1)? verinum::V1 : verinum::V0;
|
||||
value /= 2;
|
||||
if (strlen(ptr) >= sizeof(buf)-2){
|
||||
fprintf(stderr, "Ridicilously long decimal constant will be truncated!\n");
|
||||
}
|
||||
|
||||
/* If we run out of bits to hold the value, but there are
|
||||
still valueable bits in the number, print a warning. */
|
||||
strncpy(buf, ptr, sizeof(buf)-2);
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
|
||||
if (value != 0)
|
||||
/* Convert the decimal number to a binary value, one digit at
|
||||
a time. Watch out for overflow. */
|
||||
verinum::V*bits = new verinum::V[size];
|
||||
unsigned idx=0;
|
||||
|
||||
while(idx<size){
|
||||
int rem = dec_buf_div2(buf);
|
||||
|
||||
bits[idx] = (rem==1) ? verinum::V1 : verinum::V0;
|
||||
++idx;
|
||||
}
|
||||
|
||||
for(; idx<size; ++idx){
|
||||
bits[idx] = verinum::V0;
|
||||
}
|
||||
|
||||
/* If we run out of bits to hold the value, but there are
|
||||
still valueable bits in the number, print a warning. */
|
||||
if (strcmp(buf, "0") != 0){
|
||||
cerr << yylloc.text << ":" << yylloc.first_line <<
|
||||
": warning: Numeric decimal constant ``" << digits <<
|
||||
": warning: Numeric decimal constant ``" << ptr <<
|
||||
"'' truncated to " << size << " bits." << endl;
|
||||
}
|
||||
|
||||
verinum*out = new verinum(bits, size, fixed);
|
||||
out->has_sign(signed_flag);
|
||||
@@ -985,7 +1078,7 @@ static void process_timescale(const char*txt)
|
||||
return;
|
||||
}
|
||||
|
||||
pform_set_timescale(unit, prec);
|
||||
pform_set_timescale(unit, prec, yylloc.text, yylloc.first_line);
|
||||
}
|
||||
|
||||
int yywrap()
|
||||
@@ -1024,6 +1117,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 +1136,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;
|
||||
|
||||
+2
-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>
|
||||
@@ -81,7 +82,7 @@ rpmos, K_rpmos
|
||||
rtran, K_rtran
|
||||
rtranif0, K_rtranif0
|
||||
rtranif1, K_rtranif1
|
||||
scalered, K_scalered
|
||||
scalared, K_scalared
|
||||
signed, K_signed
|
||||
small, K_small
|
||||
specify, K_specify
|
||||
|
||||
+5
-2
@@ -18,14 +18,17 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: lexor_keyword.h,v 1.1 2000/03/12 17:09:41 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: lexor_keyword.h,v 1.2 2002/08/12 01:34:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
extern int lexor_keyword_code (const char*str, unsigned len);
|
||||
|
||||
/*
|
||||
* $Log: lexor_keyword.h,v $
|
||||
* Revision 1.2 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2000/03/12 17:09:41 steve
|
||||
* Support localparam.
|
||||
*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user