mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-23 14:27:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87e813766a | ||
|
|
e24e77660f | ||
|
|
8ec6d9983d | ||
|
|
ae82eccdc4 | ||
|
|
fa18d9bc01 | ||
|
|
16ec4cb685 | ||
|
|
6f08f92ffc | ||
|
|
0a38499941 | ||
|
|
55f8e5d364 | ||
|
|
b631268f56 | ||
|
|
1a8ffe2a9c | ||
|
|
e4bcc87dc1 | ||
|
|
34111a25cb | ||
|
|
8fd42fbf61 | ||
|
|
129a064e1a | ||
|
|
c7d97f4146 | ||
|
|
1f9a246c6d | ||
|
|
17fd3bae15 | ||
|
|
29aa68302e | ||
|
|
8dcd09797f | ||
|
|
ddd36ecb6c | ||
|
|
67b1eee7ce | ||
|
|
629c6e9a40 | ||
|
|
6ea1337be0 | ||
|
|
b981c81d37 | ||
|
|
210e28e571 | ||
|
|
f6ad90f8d3 | ||
|
|
890f592eec | ||
|
|
f9c1c02f8d | ||
|
|
26f47c26f0 | ||
|
|
c0496ea648 | ||
|
|
498d8fe6ad | ||
|
|
dafc653935 | ||
|
|
401faef5b8 | ||
|
|
22efa9f066 | ||
|
|
583abb7f49 | ||
|
|
fe65ae8db0 | ||
|
|
cc48a6c8d7 | ||
|
|
36471e9f96 | ||
|
|
427d5664ef | ||
|
|
253fdc6232 | ||
|
|
79fdb2b243 | ||
|
|
089bdefad1 | ||
|
|
8ed1a010f7 | ||
|
|
9931e4c013 | ||
|
|
acdb278b97 | ||
|
|
d3a54547aa | ||
|
|
f621448ced | ||
|
|
2229825783 | ||
|
|
fb7ce1d330 | ||
|
|
ff7625cd9c | ||
|
|
8f9738719b | ||
|
|
31914c7fcd | ||
|
|
abaeb1e702 | ||
|
|
513fa72d99 | ||
|
|
65baeaed8f | ||
|
|
fbc731d19e | ||
|
|
5047a3add3 | ||
|
|
d3588b4e23 | ||
|
|
33e5f22cf1 | ||
|
|
af913e7eb1 | ||
|
|
dd995b3409 | ||
|
|
a863b2390c | ||
|
|
c5524b4acf | ||
|
|
d883979fd8 | ||
|
|
37111eb4a8 | ||
|
|
bd1b00ca29 | ||
|
|
0168502bbb | ||
|
|
ea74940be4 | ||
|
|
8856c07d88 | ||
|
|
9e21880cdc | ||
|
|
fe8da0bf14 | ||
|
|
fe02214fcc | ||
|
|
611d2c81b3 | ||
|
|
96443f1338 | ||
|
|
32fb919b00 | ||
|
|
72ec3a2c09 | ||
|
|
a50ec29ad9 | ||
|
|
d9efe3312e | ||
|
|
29b4d5a46e | ||
|
|
f23a5bfa96 | ||
|
|
74ac5dbf58 | ||
|
|
ae88f5cc68 | ||
|
|
760f2182ba | ||
|
|
e6fa72c318 | ||
|
|
8c434ca6fa | ||
|
|
6f810e0dba | ||
|
|
b68f17483e | ||
|
|
606751dbfd | ||
|
|
fc9a90c9e0 | ||
|
|
b21390b228 | ||
|
|
1352eada12 | ||
|
|
243cf94165 | ||
|
|
e789b3a5cf | ||
|
|
bb02da0319 | ||
|
|
0946f40c7b | ||
|
|
80a2b05733 | ||
|
|
6804732b9e | ||
|
|
d6969b719a | ||
|
|
d2ba78559a | ||
|
|
1f54f128c1 | ||
|
|
2c32a81d91 | ||
|
|
cd5b1b111c | ||
|
|
9d4fc92df5 | ||
|
|
45307f6144 | ||
|
|
92c36f152d | ||
|
|
4f74d9df98 | ||
|
|
0137832003 | ||
|
|
189532c5bf | ||
|
|
7d2d87f7c6 | ||
|
|
521f66f040 | ||
|
|
c1c2381261 | ||
|
|
97234cb7ca | ||
|
|
3fd80b09f0 | ||
|
|
2b3acfb344 | ||
|
|
326329d497 | ||
|
|
d958a4a5af | ||
|
|
7d42c50253 | ||
|
|
6d91be5b19 | ||
|
|
d52f41535f | ||
|
|
a623502ece | ||
|
|
d22e9713f7 | ||
|
|
5869d7d879 | ||
|
|
074a6a44e3 | ||
|
|
85ceea7358 | ||
|
|
b2e1db6adb | ||
|
|
05efaa6427 | ||
|
|
cfe2198e5e | ||
|
|
d175eb17f1 | ||
|
|
2de8bafb5c | ||
|
|
8e1c7e2891 | ||
|
|
8ae6240947 | ||
|
|
f77d803aeb | ||
|
|
4b829bf04f | ||
|
|
17a508047b | ||
|
|
b350b14f93 | ||
|
|
ca9da51a79 | ||
|
|
98417cb03a | ||
|
|
f07257067a | ||
|
|
e4d7eda02a | ||
|
|
4d8164945e | ||
|
|
c0954349e4 | ||
|
|
e89b9fc25e | ||
|
|
11a83c352d | ||
|
|
d8d7673d27 | ||
|
|
6f3ddce7c4 | ||
|
|
f5a7ee0736 | ||
|
|
91d84e7dc7 | ||
|
|
5c3b2f4193 | ||
|
|
0ae45e5644 | ||
|
|
296c2a575a | ||
|
|
316422d93b | ||
|
|
2c7d2effd1 | ||
|
|
4fb5556d1c | ||
|
|
2eeea7003e | ||
|
|
d7de70bdeb | ||
|
|
078019ddec | ||
|
|
b4c3e8208f | ||
|
|
2f9a3e90ae | ||
|
|
4f8a7ea84a | ||
|
|
a3da90aa4a | ||
|
|
48029ed8e5 | ||
|
|
94f07d16e3 | ||
|
|
041091cfac | ||
|
|
0af4ea7cbe | ||
|
|
d6f98599f8 | ||
|
|
2ac30824ac | ||
|
|
64b4e2fa01 | ||
|
|
f5a204720d | ||
|
|
21522c90bc | ||
|
|
34b5a31ff4 | ||
|
|
c339dc4bbc | ||
|
|
ed5d3188b3 | ||
|
|
8e379bd634 | ||
|
|
841378426f | ||
|
|
2302693201 | ||
|
|
2a8b960b06 | ||
|
|
0e102a94b2 | ||
|
|
168b3f2743 | ||
|
|
0d71b1cc18 | ||
|
|
ec23bb0367 | ||
|
|
26e2e85ffa | ||
|
|
4af28e2b77 | ||
|
|
69cd007a71 | ||
|
|
cbe1a6a3ca | ||
|
|
1a0d48c346 | ||
|
|
549f226c6e | ||
|
|
e1f712356f | ||
|
|
6593b603ad | ||
|
|
852d10500d | ||
|
|
44ca0fe798 | ||
|
|
35ce5f3e2a | ||
|
|
d6be82f748 | ||
|
|
7e3ea2ffe8 | ||
|
|
b658a3b41f | ||
|
|
d3ceae7ee0 | ||
|
|
0edb5a7547 | ||
|
|
ceb6bf4afd | ||
|
|
0e2c6544b9 | ||
|
|
b4893dc16f | ||
|
|
f49039a3d6 | ||
|
|
3617f0346e | ||
|
|
f20191e6f5 | ||
|
|
182734fd4d | ||
|
|
431eee16e4 | ||
|
|
92cb1d4e2d | ||
|
|
6f34dfc8e5 | ||
|
|
2c7e96caec | ||
|
|
54c7ef72cb | ||
|
|
50800fd3a1 | ||
|
|
fc0695beb6 | ||
|
|
00891db0d2 | ||
|
|
898b0e0365 | ||
|
|
382c4d74fd | ||
|
|
5bcf083662 | ||
|
|
1bd530c144 | ||
|
|
82a85131a8 | ||
|
|
49b65e86fe | ||
|
|
06d6ac4b33 | ||
|
|
2037650080 | ||
|
|
61f3a84557 | ||
|
|
ed70db84ce | ||
|
|
5348ac14a5 | ||
|
|
aab6fefd8a | ||
|
|
1b8e2a17c7 | ||
|
|
33a391cb71 | ||
|
|
bcc08112aa | ||
|
|
80f30be9d0 | ||
|
|
71faebd6df | ||
|
|
53ae1f29c9 | ||
|
|
857b3e15b6 | ||
|
|
019d61f633 | ||
|
|
d37b6599f4 | ||
|
|
68e52ce6b7 | ||
|
|
4c885f65e1 | ||
|
|
f0e114d59f | ||
|
|
aaaa042f73 | ||
|
|
044da54b41 | ||
|
|
a8b86ea3bb | ||
|
|
e98aad1e9b | ||
|
|
1ef91f800f | ||
|
|
a19efe181b | ||
|
|
81bfbd1549 | ||
|
|
dc2898cc73 | ||
|
|
0c9fb766b6 | ||
|
|
10f8c66f4a | ||
|
|
56f70ec702 | ||
|
|
949054e000 | ||
|
|
47b72c3b74 | ||
|
|
a2c036d5ab | ||
|
|
0d17e57656 | ||
|
|
fd94268315 | ||
|
|
36039e13ec | ||
|
|
a702f99c04 | ||
|
|
4493e3f928 | ||
|
|
3727052000 | ||
|
|
39ff233cf1 | ||
|
|
58118bddc5 | ||
|
|
c2ff3d501c | ||
|
|
46d86ad276 | ||
|
|
4dd1308eb0 | ||
|
|
a978bb1e14 | ||
|
|
707af782b3 | ||
|
|
fc5cf55400 | ||
|
|
6a74a090f0 | ||
|
|
c448b75f2c | ||
|
|
aed885ecc5 | ||
|
|
d365c144a8 | ||
|
|
f001d0001a | ||
|
|
decfbff2b1 | ||
|
|
3e45f4302b | ||
|
|
77a0d7f4db | ||
|
|
e8efa6df53 | ||
|
|
276f2d0032 | ||
|
|
13a660b591 | ||
|
|
f4a44df2cc | ||
|
|
5b3ba8c306 | ||
|
|
8defa4bcd0 | ||
|
|
dabdcf0fc9 | ||
|
|
8ff70410ab | ||
|
|
6f46d12e07 | ||
|
|
5f5a6b5396 | ||
|
|
1b911ad87a | ||
|
|
b0b614ae0e | ||
|
|
9c16c34422 | ||
|
|
170e57d662 | ||
|
|
065f342278 | ||
|
|
a721586acb | ||
|
|
50ad415c0d | ||
|
|
4ba2afbbe1 | ||
|
|
d3f89e0d4f | ||
|
|
457cf15b3b | ||
|
|
d0de678d57 | ||
|
|
fa6e4a69a6 | ||
|
|
d434dd7296 | ||
|
|
3158e2caa1 | ||
|
|
e1ce72e245 | ||
|
|
368c27c9e4 | ||
|
|
a4116efd57 | ||
|
|
58f182a159 | ||
|
|
b7861fa6e8 | ||
|
|
1721799050 | ||
|
|
df226c5d13 | ||
|
|
e9bf00dff6 | ||
|
|
c071cc1bbe | ||
|
|
101b373293 | ||
|
|
5cf64dfa70 | ||
|
|
1021e5acc8 | ||
|
|
4f7e7a2296 | ||
|
|
0c73f209de | ||
|
|
0873c52474 | ||
|
|
64d46630e0 | ||
|
|
8ed504b064 | ||
|
|
6161904bf8 | ||
|
|
908955c72c | ||
|
|
bab70ccbed | ||
|
|
2b8fd28a95 | ||
|
|
0e044d6684 | ||
|
|
7efa6be236 | ||
|
|
35951510c5 | ||
|
|
3f108f08ed | ||
|
|
244844c067 | ||
|
|
b416ae047b | ||
|
|
c02b3b8ac6 | ||
|
|
bebcc05aab | ||
|
|
8d49abf967 | ||
|
|
c87223170b | ||
|
|
8e2898e51a | ||
|
|
9c8c541f5d | ||
|
|
3cdf655c79 | ||
|
|
560c5a2584 | ||
|
|
c75f0a930e | ||
|
|
bb3f3c1f46 | ||
|
|
07f345da4d | ||
|
|
fb22bcc96b | ||
|
|
2842a65fd1 | ||
|
|
a652719876 | ||
|
|
16dc3ab4d4 | ||
|
|
cf85c19f7b | ||
|
|
01a6dd61ca | ||
|
|
bf8b085159 | ||
|
|
ee22550047 | ||
|
|
2b07c7a685 | ||
|
|
be73be8c98 | ||
|
|
e2a1b90b12 | ||
|
|
d22d88923d | ||
|
|
2729d6cd2e | ||
|
|
21af0dbe3f | ||
|
|
c4d8ab8509 | ||
|
|
988a0a7048 | ||
|
|
672aa61ae7 | ||
|
|
7235706923 | ||
|
|
a256613fa6 | ||
|
|
5ec7dde52f | ||
|
|
19a1ae8d4f | ||
|
|
14d79a655e | ||
|
|
293976bacc | ||
|
|
4dfdc147c5 | ||
|
|
c946f27d9b | ||
|
|
9fd16575d9 | ||
|
|
b9c0b8aa79 | ||
|
|
65584e6dde | ||
|
|
c39976fbf1 | ||
|
|
4902c222fb | ||
|
|
ad761069c7 | ||
|
|
b69f59f2ec | ||
|
|
3ff2488d4f | ||
|
|
efd7825964 | ||
|
|
70f146924a | ||
|
|
7c19eb51e7 | ||
|
|
6f839aa5df | ||
|
|
dac11c2468 | ||
|
|
5cf2ce6499 | ||
|
|
73453996a9 | ||
|
|
bc489a7761 | ||
|
|
4a8be3db9c | ||
|
|
8232b621f1 | ||
|
|
4cbffc6b77 | ||
|
|
9a16e030b5 | ||
|
|
d353ddb660 | ||
|
|
bc9f286954 | ||
|
|
fde4ff72f6 | ||
|
|
a8d49921ee | ||
|
|
9cae53988a | ||
|
|
559a1fd359 | ||
|
|
5bfdd52391 | ||
|
|
b094ccc3f7 | ||
|
|
b9799cf6ec | ||
|
|
75ad90534b | ||
|
|
3ac79c294a | ||
|
|
e7f3340513 | ||
|
|
60b9121c6c | ||
|
|
e3f300f4c2 | ||
|
|
1c6be44724 | ||
|
|
6bf7556d65 | ||
|
|
c46f978dbb | ||
|
|
9cac88330b | ||
|
|
de1dd2f2b3 | ||
|
|
6c8e1f7834 | ||
|
|
b58705b829 | ||
|
|
7091915b73 | ||
|
|
5513974b78 | ||
|
|
ad78af2f91 | ||
|
|
1b30bac9f3 | ||
|
|
66a579dd67 | ||
|
|
094dd7e4de | ||
|
|
3b91db96cd | ||
|
|
657ac8168e | ||
|
|
a79fee39e9 | ||
|
|
4cc421b3b7 | ||
|
|
290c604c62 | ||
|
|
466ab5c2c7 | ||
|
|
4ba195282d | ||
|
|
cd14ee77ae | ||
|
|
21c7abf090 | ||
|
|
4413dd3c81 | ||
|
|
73f3589ea6 | ||
|
|
9278dad244 | ||
|
|
a0dce80eba | ||
|
|
af5f713c0f | ||
|
|
80cac983c6 | ||
|
|
f5ba93eeb6 | ||
|
|
668781788b | ||
|
|
86729f52ca | ||
|
|
fb8ddbbfde | ||
|
|
2736859d8f | ||
|
|
a59f3b1fa6 | ||
|
|
dd4f765b06 | ||
|
|
f465bca305 | ||
|
|
cb967c10fe | ||
|
|
3607fb584d | ||
|
|
77792dcc2f | ||
|
|
2f7ec71a78 | ||
|
|
42433f4df9 | ||
|
|
aa2e178667 | ||
|
|
015d280c6a | ||
|
|
739a1839ed | ||
|
|
b6fd4f610b | ||
|
|
06e08dbdf0 | ||
|
|
28168e0f57 | ||
|
|
7796c8bcfb | ||
|
|
82be4ab189 | ||
|
|
3a8e2e688d | ||
|
|
037ab9efe9 | ||
|
|
d6a89a40cf | ||
|
|
3bd09d1470 | ||
|
|
d0ade1d082 | ||
|
|
fcb02ee9c2 | ||
|
|
870395e627 | ||
|
|
c701fb615b | ||
|
|
adbe734b6c | ||
|
|
c34e44dad0 | ||
|
|
5a2dd3393f | ||
|
|
ed78c5b677 | ||
|
|
7dd0d255a6 | ||
|
|
48aa0f0075 | ||
|
|
5277124c76 | ||
|
|
f6da64e2ec | ||
|
|
06816e79fe | ||
|
|
a1d899112a | ||
|
|
d548c9a5f8 | ||
|
|
2894cdefc7 | ||
|
|
df271c9fa3 | ||
|
|
99aff5f10b | ||
|
|
e9bf021f6c | ||
|
|
aed8474944 | ||
|
|
af7e196518 | ||
|
|
365cfedd55 | ||
|
|
f884652c19 | ||
|
|
6244dc1194 | ||
|
|
a3f696cd06 | ||
|
|
061fdf5a0d | ||
|
|
fe91ebe77c | ||
|
|
e8a6835d36 | ||
|
|
800e2c6a17 | ||
|
|
29fa9e7321 | ||
|
|
65c7ec00e7 | ||
|
|
d62661257a | ||
|
|
c5cf77dc7e | ||
|
|
20d3a8508e | ||
|
|
f16b69c1e5 | ||
|
|
573e07225d | ||
|
|
236ff2b278 | ||
|
|
b7ef2fcb0a | ||
|
|
becda0e26c | ||
|
|
d8a456bd67 | ||
|
|
8184dfaed8 | ||
|
|
ca488dff4e | ||
|
|
23925b636e | ||
|
|
53da6e9a33 | ||
|
|
0f914bf35a | ||
|
|
f556452403 | ||
|
|
ab1ca54df2 | ||
|
|
bae8507c90 | ||
|
|
313502f360 | ||
|
|
1c5b4881d7 | ||
|
|
53af2949b4 | ||
|
|
789c95b1c1 | ||
|
|
72240c460e | ||
|
|
8e135a1020 | ||
|
|
0fb1fd36ee | ||
|
|
e7c2e06260 | ||
|
|
73997f813c | ||
|
|
75af32bd3c | ||
|
|
4ccbb4f0b2 | ||
|
|
85286cc086 | ||
|
|
04604188df | ||
|
|
f7dc4307bd | ||
|
|
257e1f9516 | ||
|
|
5fe5d9184d | ||
|
|
589eb1d315 | ||
|
|
2fcaac4060 | ||
|
|
4051f7d986 | ||
|
|
02d0719529 | ||
|
|
aaf35ab1a9 | ||
|
|
c5e7e2ec0a | ||
|
|
ff067bb959 | ||
|
|
1d7235b4f1 | ||
|
|
97e0723bd1 | ||
|
|
d4eb4d38bc | ||
|
|
d00e3fc9a9 | ||
|
|
9ec00e1288 | ||
|
|
85d9ebded8 | ||
|
|
d74177634c | ||
|
|
eca4f4fa97 | ||
|
|
6b7b82758a | ||
|
|
355ead0002 | ||
|
|
4fce321900 | ||
|
|
2e6d2f8e98 | ||
|
|
55b5bf9d39 | ||
|
|
1979fca239 | ||
|
|
a0583ef124 | ||
|
|
ee5bb5fcaf | ||
|
|
ca1bbc79a3 | ||
|
|
e74127e1fc | ||
|
|
b48abb2148 | ||
|
|
97f83ffbe3 | ||
|
|
018014368b | ||
|
|
20be0351ae | ||
|
|
68a788221e | ||
|
|
84b3e8e2dc | ||
|
|
e6cdd32c19 | ||
|
|
c23a35a033 | ||
|
|
609b6a7baa | ||
|
|
0609c5f18c | ||
|
|
d51503ffd8 | ||
|
|
7625a6c3e7 | ||
|
|
695718d691 | ||
|
|
e04fb5c083 | ||
|
|
07f64bc603 | ||
|
|
bf3679b7d4 | ||
|
|
ade5bdcafe | ||
|
|
7250337941 | ||
|
|
99ace10774 | ||
|
|
6be34bba4d | ||
|
|
a5b431ad20 | ||
|
|
a121e703f3 | ||
|
|
dfb7c7ba6f | ||
|
|
edeb9d8eca | ||
|
|
14f557e6f4 | ||
|
|
25de448d34 | ||
|
|
cb4e0d4724 | ||
|
|
6a23f16860 | ||
|
|
a4710f375e | ||
|
|
6c5e840617 | ||
|
|
e28636776a | ||
|
|
b86fdd6bbc | ||
|
|
1d1dda5a5d | ||
|
|
3222031970 | ||
|
|
bf6a5d0f50 | ||
|
|
1c3668ea7f | ||
|
|
ead2481793 | ||
|
|
fcaaec0464 | ||
|
|
4d139b58aa | ||
|
|
8c18c9152d | ||
|
|
399dfe5c44 | ||
|
|
9e94afe399 | ||
|
|
6c711ee4d8 | ||
|
|
9735b0e8b3 | ||
|
|
d5c33420ab | ||
|
|
34a14b983b | ||
|
|
d1e2538aba | ||
|
|
8bfc75d1ee | ||
|
|
b1b93f860c | ||
|
|
8f2d679c8a | ||
|
|
83423c978b | ||
|
|
1674d692b7 | ||
|
|
7166598ed0 | ||
|
|
5eb25e44e1 | ||
|
|
59566158c4 | ||
|
|
e11ac0b1d8 | ||
|
|
8939467ac5 | ||
|
|
26d97558c4 | ||
|
|
59bac26f4f | ||
|
|
78dda42493 | ||
|
|
36f36bd2ac | ||
|
|
0193daa436 | ||
|
|
4444079409 | ||
|
|
3947d7dd33 | ||
|
|
7973dad9f5 | ||
|
|
d19e76a193 | ||
|
|
ffedf32476 | ||
|
|
527ddea811 | ||
|
|
65e9b6be12 | ||
|
|
6854660e18 | ||
|
|
6818d996ea | ||
|
|
4907776eaa | ||
|
|
51dd41f81a | ||
|
|
e4ae832153 | ||
|
|
b3a3428b9a | ||
|
|
2abdcfcaa4 | ||
|
|
526b87cae3 | ||
|
|
9383b165a4 | ||
|
|
e827f8f8c1 | ||
|
|
965d928430 | ||
|
|
96936456da | ||
|
|
94647be1f0 | ||
|
|
e45230061e | ||
|
|
180bfc5e72 | ||
|
|
6d40326a2f | ||
|
|
0a630b60dd | ||
|
|
1e4ffc292d | ||
|
|
a579114ae2 | ||
|
|
8dfe16f6d2 | ||
|
|
d1dac0017d | ||
|
|
5e627c9adc | ||
|
|
98ba641e67 | ||
|
|
a70dd79cd8 | ||
|
|
a8ee786036 | ||
|
|
d16e8f7c94 | ||
|
|
4148a2a44c | ||
|
|
5f38591676 | ||
|
|
c10e572091 | ||
|
|
1ab8879100 | ||
|
|
2d498363d7 | ||
|
|
15059bbfdc | ||
|
|
9de786fc44 | ||
|
|
62cffe16f4 | ||
|
|
d3eb53e6b1 | ||
|
|
b631e6e704 | ||
|
|
ba3790dc2b | ||
|
|
f02f5be3cc | ||
|
|
7f67afe9d5 | ||
|
|
d76ad25778 | ||
|
|
21ba781604 | ||
|
|
95c8115fc7 | ||
|
|
49366d1334 | ||
|
|
e2b94947f5 | ||
|
|
efe05a77cb | ||
|
|
8bf434754f | ||
|
|
491df9c327 | ||
|
|
fca2e64808 | ||
|
|
6cd7c1a650 | ||
|
|
3dbc07f34d | ||
|
|
57b8ca191f | ||
|
|
9ee0210cac | ||
|
|
69cfdbdc54 | ||
|
|
76c0fe459c | ||
|
|
9ba1177a4d | ||
|
|
51fd249d8a | ||
|
|
050ec6f325 | ||
|
|
03d7448550 | ||
|
|
b3529d8593 | ||
|
|
112368c7de | ||
|
|
d1f0a0b0d7 | ||
|
|
b043445c80 | ||
|
|
fd371a3958 | ||
|
|
35619771dd | ||
|
|
bdc6cb8723 | ||
|
|
2d63705093 | ||
|
|
b108167441 | ||
|
|
9949040285 | ||
|
|
e8e0cd7cab | ||
|
|
f2d4966634 | ||
|
|
50bf2095df | ||
|
|
2003c5a21e | ||
|
|
bfd393c91c | ||
|
|
37ae777111 | ||
|
|
dd69872266 | ||
|
|
fbfc796647 | ||
|
|
8d3102388b | ||
|
|
ba309e60bb | ||
|
|
5472b27e1f | ||
|
|
e7fa56981a | ||
|
|
55ba131997 | ||
|
|
559f73c135 | ||
|
|
b97f9448e0 | ||
|
|
a7ae8adf9b | ||
|
|
896f1b0de1 | ||
|
|
ca55cadc6c | ||
|
|
324ba713e5 | ||
|
|
69ebd0c49e | ||
|
|
d60112d58b | ||
|
|
5807d6912e | ||
|
|
ec0e35b940 | ||
|
|
c8d67b904a | ||
|
|
c55adddb69 | ||
|
|
8e63f56caf | ||
|
|
9e223b9696 | ||
|
|
dd7472d125 | ||
|
|
0ef1ecab5e | ||
|
|
28719e8584 | ||
|
|
a0ed5e9e29 | ||
|
|
20b7a23bde | ||
|
|
33783385d2 | ||
|
|
914746f6f3 | ||
|
|
c6453a0854 | ||
|
|
413932e406 | ||
|
|
9531920685 | ||
|
|
4456937274 | ||
|
|
efef8fba85 | ||
|
|
177b6ffb6a | ||
|
|
1295058e5d | ||
|
|
b5b02269f1 | ||
|
|
60adfb845d | ||
|
|
a4c5ff0bd3 | ||
|
|
72f9dc5094 | ||
|
|
65f09337f6 | ||
|
|
8d2858c555 | ||
|
|
89acc41437 | ||
|
|
536068bdfb | ||
|
|
2d7380c03b | ||
|
|
27af95d402 | ||
|
|
17c891bc9c | ||
|
|
38ec4b7851 | ||
|
|
6f9ebb1e60 | ||
|
|
0fd5a79760 | ||
|
|
4288f3c6d0 | ||
|
|
d64295ed65 | ||
|
|
2f8a40b159 | ||
|
|
081a6a4088 | ||
|
|
c971448760 | ||
|
|
c275ef9482 | ||
|
|
8188c4c690 | ||
|
|
d482e341ae | ||
|
|
f2b9b8946f | ||
|
|
fa4a873628 | ||
|
|
a436bfc711 | ||
|
|
c2ab27541f | ||
|
|
5160021b48 | ||
|
|
f349449a49 | ||
|
|
de7f87853d | ||
|
|
6a02613fca | ||
|
|
3bb408faf2 | ||
|
|
4987970af4 | ||
|
|
d98720af4d | ||
|
|
793493d3ff | ||
|
|
36785997cb | ||
|
|
923a3ea537 | ||
|
|
8aca824c0f | ||
|
|
e6b25a4e20 | ||
|
|
d98b7ffb2e | ||
|
|
e617e4a98c | ||
|
|
1970e41041 | ||
|
|
e331b182a7 | ||
|
|
11b0cc5bf3 | ||
|
|
5b0c7be6b7 | ||
|
|
59ac435c71 | ||
|
|
57c3e86084 | ||
|
|
f0e0377a20 | ||
|
|
ae3198b505 | ||
|
|
d4525ddc16 | ||
|
|
19e8a92729 | ||
|
|
1bd1d287e4 | ||
|
|
4c8c14ceec | ||
|
|
df968687e4 | ||
|
|
973b4d9bcb | ||
|
|
2a60768ffe | ||
|
|
e56b77a43f | ||
|
|
9967bfcbfd | ||
|
|
2c4358c9ff | ||
|
|
be0b42f210 | ||
|
|
cf33bedc2d | ||
|
|
0b538ceed6 | ||
|
|
8d4c3a8620 | ||
|
|
700d51ff8a | ||
|
|
cceb2bd2c5 | ||
|
|
12033d7bd4 | ||
|
|
c96b0402be | ||
|
|
5068e3ea15 | ||
|
|
435f06bd21 | ||
|
|
534a656be8 | ||
|
|
d10da2121f | ||
|
|
43f28b53a3 | ||
|
|
995cd449c5 | ||
|
|
7fa531c5db | ||
|
|
df08760ef8 | ||
|
|
a7c773262e | ||
|
|
f58b124101 | ||
|
|
8eccb7b9a1 | ||
|
|
bc0ead2842 | ||
|
|
80570c7c78 | ||
|
|
ed831e7c32 | ||
|
|
074dcc934a | ||
|
|
9db45e398e | ||
|
|
4f40eb0a00 | ||
|
|
1dfbe0f7f2 | ||
|
|
c5f7e7837b | ||
|
|
faf33458fd | ||
|
|
0607970eca | ||
|
|
c4e069e505 | ||
|
|
7fd669fcc0 | ||
|
|
fad43d78b0 | ||
|
|
5aadc310f7 | ||
|
|
930e5137ac | ||
|
|
02ec36806c | ||
|
|
e88c3a20a2 | ||
|
|
5ff3bcc7fb | ||
|
|
4236b8a95e | ||
|
|
89fca07dc8 | ||
|
|
4eae8426a9 | ||
|
|
1b8034818c | ||
|
|
a503e2d91f | ||
|
|
65ae69843b | ||
|
|
1c99c629b1 | ||
|
|
edaa7df6d2 | ||
|
|
847448139c | ||
|
|
ee172bdccf | ||
|
|
5496a38499 | ||
|
|
8dab4c6b53 | ||
|
|
3e44a7121d | ||
|
|
d4f3349fe0 | ||
|
|
f2382e209a | ||
|
|
123e4c7f65 | ||
|
|
bb8785962f | ||
|
|
dba4f44598 | ||
|
|
ec9361ae22 | ||
|
|
906e7d9946 | ||
|
|
9628b4d047 | ||
|
|
46bb8c68fa | ||
|
|
a461a76bd5 | ||
|
|
368e2211e3 | ||
|
|
e9f1fd012c | ||
|
|
c34d5699ee | ||
|
|
468ffa4bd0 | ||
|
|
e49856fad4 | ||
|
|
ee81485582 | ||
|
|
8cf7b62933 | ||
|
|
cf1affff32 | ||
|
|
9a232d545d | ||
|
|
fc44f44879 | ||
|
|
ddba06904c | ||
|
|
a89f39f166 | ||
|
|
9b821c0dbd | ||
|
|
52b756a6fa | ||
|
|
7ef45769a7 | ||
|
|
fff6e88245 | ||
|
|
01d22e2005 | ||
|
|
691d31faac | ||
|
|
3190eda414 | ||
|
|
40daff0aed | ||
|
|
f7b3c720af | ||
|
|
2f4ec5a473 | ||
|
|
d21351405a | ||
|
|
1cb589fee0 | ||
|
|
8c30d217d5 | ||
|
|
86e9489530 | ||
|
|
07ece95383 | ||
|
|
2ed433b8c1 | ||
|
|
39b2928ad8 | ||
|
|
becae2cecd | ||
|
|
2231b830db | ||
|
|
2970b3c39b | ||
|
|
daa85f2479 | ||
|
|
2f8181f40a | ||
|
|
d1f0bcf620 | ||
|
|
933f4483b1 | ||
|
|
2e6cfd8c0d | ||
|
|
6abe797963 | ||
|
|
94a71fdee8 | ||
|
|
39df56fdcf | ||
|
|
1f0c274e82 | ||
|
|
693794552c | ||
|
|
da7956a797 | ||
|
|
1de5e6c848 | ||
|
|
ed792c5321 | ||
|
|
31c0a9dcd1 | ||
|
|
1c51e1787c | ||
|
|
178847fc53 | ||
|
|
7e7735ce21 | ||
|
|
537fe0547a | ||
|
|
9093877073 | ||
|
|
6927e0fa1f | ||
|
|
2418ab9063 | ||
|
|
2df976b4c6 | ||
|
|
c4c03e6be3 | ||
|
|
cee34f8a8a | ||
|
|
aa40930278 | ||
|
|
59c5759fdf | ||
|
|
f495c75faf | ||
|
|
fea68f7fe7 | ||
|
|
7521aa83f8 | ||
|
|
c26df174a1 | ||
|
|
b0230cf4d4 | ||
|
|
ca0a9faa90 | ||
|
|
af806ed9c3 | ||
|
|
2272843511 | ||
|
|
fdb5731b8b | ||
|
|
7c1401a2ba | ||
|
|
14150d6fba | ||
|
|
816aba993f | ||
|
|
60b2e89b1b | ||
|
|
64d795c53a | ||
|
|
ec07674d40 | ||
|
|
0a012c5d90 | ||
|
|
cd4b3b0f17 | ||
|
|
3dc73aa292 | ||
|
|
e561819179 | ||
|
|
855c2fe001 | ||
|
|
bc428cfe9b |
@@ -17,9 +17,11 @@ configure
|
||||
Makefile
|
||||
check
|
||||
check.cc
|
||||
check.vvp
|
||||
config.status
|
||||
config.log
|
||||
config.cache
|
||||
autom4te.cache
|
||||
config.h
|
||||
_pli_types.h
|
||||
dosify
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.cc,v 1.5 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: Attrib.cc,v 1.6 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -36,25 +36,8 @@ Attrib::~Attrib()
|
||||
delete[] list_;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void Attrib::copy_attributes(const map<string,verinum>&attr)
|
||||
{
|
||||
assert(list_ == 0);
|
||||
|
||||
nlist_ = attr.size();
|
||||
list_ = new cell_[nlist_];
|
||||
|
||||
map<string,verinum>::const_iterator idx;
|
||||
unsigned jdx;
|
||||
for (idx = attr.begin(), jdx = 0 ; idx != attr.end() ; idx ++, jdx++) {
|
||||
struct cell_*tmp = list_ + jdx;
|
||||
tmp->key = (*idx).first;
|
||||
tmp->val = (*idx).second;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const verinum& Attrib::attribute(const string&key) const
|
||||
const verinum& Attrib::attribute(perm_string key) const
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) {
|
||||
|
||||
@@ -66,7 +49,7 @@ const verinum& Attrib::attribute(const string&key) const
|
||||
return null;
|
||||
}
|
||||
|
||||
void Attrib::attribute(const string&key, const verinum&value)
|
||||
void Attrib::attribute(perm_string key, const verinum&value)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
@@ -108,10 +91,10 @@ unsigned Attrib::attr_cnt() const
|
||||
return nlist_;
|
||||
}
|
||||
|
||||
const char* Attrib::attr_key(unsigned idx) const
|
||||
perm_string Attrib::attr_key(unsigned idx) const
|
||||
{
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].key.c_str();
|
||||
return list_[idx].key;
|
||||
}
|
||||
|
||||
const verinum& Attrib::attr_value(unsigned idx) const
|
||||
@@ -123,6 +106,9 @@ const verinum& Attrib::attr_value(unsigned idx) const
|
||||
|
||||
/*
|
||||
* $Log: Attrib.cc,v $
|
||||
* Revision 1.6 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.5 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.h,v 1.4 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: Attrib.h,v 1.5 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include "StringHeap.h"
|
||||
# include "verinum.h"
|
||||
|
||||
/*
|
||||
@@ -35,20 +35,20 @@ class Attrib {
|
||||
Attrib();
|
||||
~Attrib();
|
||||
|
||||
const verinum&attribute(const string&key) const;
|
||||
void attribute(const string&key, const verinum&value);
|
||||
const verinum&attribute(perm_string key) const;
|
||||
void attribute(perm_string key, const verinum&value);
|
||||
bool has_compat_attributes(const Attrib&that) const;
|
||||
|
||||
|
||||
/* Provide a means of iterating over the entries in the map. */
|
||||
unsigned attr_cnt() const;
|
||||
const char* attr_key(unsigned idx) const;
|
||||
perm_string attr_key(unsigned idx) const;
|
||||
const verinum& attr_value(unsigned idx) const;
|
||||
|
||||
|
||||
private:
|
||||
struct cell_ {
|
||||
string key;
|
||||
perm_string key;
|
||||
verinum val;
|
||||
};
|
||||
|
||||
@@ -62,6 +62,9 @@ class Attrib {
|
||||
|
||||
/*
|
||||
* $Log: Attrib.h,v $
|
||||
* Revision 1.5 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
@@ -104,7 +104,7 @@ module may not be needed as long as the ``-s <name>'' switch is
|
||||
given.
|
||||
|
||||
So when you send a test case, ask yourself "Can poor overworked Steve
|
||||
invoke the error without any Verilog other then what is included?" And
|
||||
invoke the error without any Verilog other than what is included?" And
|
||||
while we are at it, please place a copyright notice in your test
|
||||
program and include a GPL license statement if you can. Your test
|
||||
program may find its way into the test suite, and the notices will
|
||||
@@ -160,8 +160,11 @@ I must insist that any copyright material submitted for inclusion
|
||||
include the GPL license notice as shown in the rest of the source.
|
||||
|
||||
|
||||
$Id: BUGS.txt,v 1.4 2003/02/19 04:36:31 steve Exp $
|
||||
$Id: BUGS.txt,v 1.5 2007/03/22 16:08:14 steve Exp $
|
||||
$Log: BUGS.txt,v $
|
||||
Revision 1.5 2007/03/22 16:08:14 steve
|
||||
Spelling fixes from Larry
|
||||
|
||||
Revision 1.4 2003/02/19 04:36:31 steve
|
||||
Notes on hte bug database.
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: HName.cc,v 1.5 2002/11/02 03:27:52 steve Exp $"
|
||||
#ident "$Id: HName.cc,v 1.8 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -29,235 +29,107 @@
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
hname_t::hname_t()
|
||||
{
|
||||
item_ = 0;
|
||||
count_ = 0;
|
||||
number_ = INT_MIN;
|
||||
}
|
||||
|
||||
hname_t::hname_t(const char*text)
|
||||
hname_t::hname_t(perm_string text)
|
||||
{
|
||||
item_ = strdup(text);
|
||||
count_ = 1;
|
||||
name_ = text;
|
||||
number_ = INT_MIN;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text, int num)
|
||||
{
|
||||
name_ = text;
|
||||
number_ = num;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
name_ = that.name_;
|
||||
number_ = that.number_;
|
||||
}
|
||||
|
||||
hname_t& hname_t::operator = (const hname_t&that)
|
||||
{
|
||||
name_ = that.name_;
|
||||
number_ = that.number_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
hname_t::~hname_t()
|
||||
{
|
||||
switch (count_) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
free(item_);
|
||||
break;
|
||||
default:
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
free(array_[idx]);
|
||||
delete[]array_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned hname_t::component_count() const
|
||||
perm_string hname_t::peek_name(void) const
|
||||
{
|
||||
return count_;
|
||||
return name_;
|
||||
}
|
||||
|
||||
void hname_t::append(const char*text)
|
||||
bool hname_t::has_number() const
|
||||
{
|
||||
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;
|
||||
}
|
||||
return number_ != INT_MIN;
|
||||
}
|
||||
|
||||
void hname_t::prepend(const char*text)
|
||||
int hname_t::peek_number() const
|
||||
{
|
||||
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];
|
||||
}
|
||||
return number_;
|
||||
}
|
||||
|
||||
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)
|
||||
int cmp = strcmp(l.peek_name(), r.peek_name());
|
||||
if (cmp < 0) return true;
|
||||
if (cmp > 0) return false;
|
||||
if (l.has_number() && r.has_number())
|
||||
return l.peek_number() < r.peek_number();
|
||||
else
|
||||
return false;
|
||||
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 (l.peek_name() == r.peek_name()) {
|
||||
if (l.has_number() && r.has_number())
|
||||
return l.peek_number() == r.peek_number();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lc || rc)
|
||||
return false;
|
||||
|
||||
// Must be ==
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator != (const hname_t&l, const hname_t&r)
|
||||
{ return ! (l==r); }
|
||||
|
||||
ostream& operator<< (ostream&out, const hname_t&that)
|
||||
{
|
||||
switch (that.count_) {
|
||||
case 0:
|
||||
if (that.peek_name() == 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;
|
||||
}
|
||||
|
||||
out << that.peek_name();
|
||||
if (that.has_number())
|
||||
out << "[" << that.peek_number() << "]";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: HName.cc,v $
|
||||
* Revision 1.8 2007/06/02 03:42:12 steve
|
||||
* Properly evaluate scope path expressions.
|
||||
*
|
||||
* Revision 1.7 2007/05/16 19:12:33 steve
|
||||
* Fix hname_t use of space for 1 perm_string.
|
||||
*
|
||||
* Revision 1.6 2007/04/26 03:06:21 steve
|
||||
* Rework hname_t to use perm_strings.
|
||||
*
|
||||
* Revision 1.5 2002/11/02 03:27:52 steve
|
||||
* Allow named events to be referenced by
|
||||
* hierarchical names.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __HName_H
|
||||
#define __HName_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001-2007 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,10 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: HName.h,v 1.4 2002/11/02 03:27:51 steve Exp $"
|
||||
#ident "$Id: HName.h,v 1.7 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
# include "StringHeap.h"
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 2
|
||||
using namespace std;
|
||||
@@ -30,59 +31,56 @@ using namespace std;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This class represents a Verilog hierarchical name. A hierarchical
|
||||
* name is an ordered list of simple names.
|
||||
* This class represents a component of a Verilog hierarchical name. A
|
||||
* hierarchical component contains a name string (prepresented here
|
||||
* with a perm_string) and an optional signed number. This signed
|
||||
* number is used if the scope is part of an array, for example an
|
||||
* array of module instances or a loop generated scope.
|
||||
*/
|
||||
|
||||
class hname_t {
|
||||
|
||||
public:
|
||||
hname_t ();
|
||||
explicit hname_t (const char*text);
|
||||
explicit hname_t (perm_string text);
|
||||
explicit hname_t (perm_string text, int num);
|
||||
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);
|
||||
hname_t& operator= (const hname_t&);
|
||||
|
||||
// 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);
|
||||
// Return the string part of the hname_t.
|
||||
perm_string peek_name(void) const;
|
||||
|
||||
// This method removes the tail name from the hierarchy, and
|
||||
// returns a pointer to that tail name. That tail name now
|
||||
// must be removed by the caller.
|
||||
char* remove_tail_name();
|
||||
|
||||
// Return the given component in the hierarchical name. If the
|
||||
// idx is too large, return 0.
|
||||
const char*peek_name(unsigned idx) const;
|
||||
const char*peek_tail_name() const;
|
||||
|
||||
// Return the number of components in the hierarchical
|
||||
// name. If this is a simple name, this will return 1.
|
||||
unsigned component_count() const;
|
||||
|
||||
friend ostream& operator<< (ostream&, const hname_t&);
|
||||
bool has_number() const;
|
||||
int peek_number() const;
|
||||
|
||||
private:
|
||||
union {
|
||||
char**array_;
|
||||
char* item_;
|
||||
};
|
||||
unsigned count_;
|
||||
perm_string name_;
|
||||
// If the number is anything other then INT_MIN, then this is
|
||||
// the numeric part of the name. Otherwise, it is not part of
|
||||
// the name at all.
|
||||
int number_;
|
||||
|
||||
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&);
|
||||
extern bool operator != (const hname_t&, const hname_t&);
|
||||
extern ostream& operator<< (ostream&, const hname_t&);
|
||||
|
||||
/*
|
||||
* $Log: HName.h,v $
|
||||
* Revision 1.7 2007/06/02 03:42:12 steve
|
||||
* Properly evaluate scope path expressions.
|
||||
*
|
||||
* Revision 1.6 2007/05/16 19:12:33 steve
|
||||
* Fix hname_t use of space for 1 perm_string.
|
||||
*
|
||||
* Revision 1.5 2007/04/26 03:06:21 steve
|
||||
* Rework hname_t to use perm_strings.
|
||||
*
|
||||
* Revision 1.4 2002/11/02 03:27:51 steve
|
||||
* Allow named events to be referenced by
|
||||
* hierarchical names.
|
||||
|
||||
+6
-1
@@ -19,11 +19,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: LineInfo.h,v 1.7 2003/01/17 05:49:03 steve Exp $"
|
||||
#ident "$Id: LineInfo.h,v 1.8 2005/06/14 19:13:43 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
* This class holds line information for an internal object.
|
||||
*
|
||||
@@ -52,6 +54,9 @@ class LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: LineInfo.h,v $
|
||||
* Revision 1.8 2005/06/14 19:13:43 steve
|
||||
* gcc3/4 compile errors.
|
||||
*
|
||||
* Revision 1.7 2003/01/17 05:49:03 steve
|
||||
* Use stringstream in place of sprintf.
|
||||
*
|
||||
|
||||
+59
-70
@@ -16,7 +16,7 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.151 2003/08/10 00:39:13 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.181 2007/05/24 04:07:11 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
@@ -25,7 +25,7 @@ SHELL = /bin/sh
|
||||
# by the compiler. It reflects the assigned version number for the
|
||||
# product as a whole. Most components also print the CVS Name: token
|
||||
# in order to get a more automatic version stamp as well.
|
||||
VERSION = 0.7
|
||||
VERSION = 0.9.devel
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -37,12 +37,12 @@ VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = $(prefix)/include
|
||||
includedir = @includedir@
|
||||
mandir = @mandir@
|
||||
|
||||
libdir64 = @libdir64@
|
||||
|
||||
dllib=@DLLIB@
|
||||
rdynamic=@rdynamic@
|
||||
strip_dynamic=@strip_dynamic@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
@@ -50,84 +50,69 @@ INSTALL = @INSTALL@
|
||||
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)
|
||||
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
|
||||
CXXFLAGS = -Wall @CXXFLAGS@
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
# The TARGETS variable lists the target modules that can be build and
|
||||
# installed. Some of them depend on external things, so are only
|
||||
# compiled if the prerequisites are installed.
|
||||
TARGETS = tgt-null
|
||||
ifeq ('@HAVE_IPAL@','yes')
|
||||
TARGETS += tgt-pal
|
||||
endif
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
|
||||
all: dep ivl@EXEEXT@
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp tgt-verilog tgt-stub; \
|
||||
for dir in ivlpp ; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
cd driver ; $(MAKE) VERSION=$(VERSION) $@
|
||||
|
||||
# In the windows world, the installer will need a dosify program to
|
||||
# dosify text files.
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@MING32@,yes)
|
||||
all: dep dosify.exe
|
||||
dosify.exe: dosify.c
|
||||
$(CC) -o dosify.exe dosify.c
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
endif
|
||||
|
||||
else
|
||||
all: dep iverilog-vpi
|
||||
endif
|
||||
|
||||
# This rule rules the compiler in the trivial hello.vl program to make
|
||||
# sure the basics were compiled properly.
|
||||
check: all
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
|
||||
driver/iverilog -Ccheck.conf -ocheck.vvp -tvvp-check -B./ivlpp $(srcdir)/examples/hello.vl
|
||||
test -r check.conf || cp $(srcdir)/check.conf .
|
||||
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
|
||||
clean:
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
|
||||
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
|
||||
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
|
||||
rm -f ivl.exp iverilog-vpi.pdf iverilog-vpi.ps parse.output
|
||||
rm -f syn-rules.output dosify.exe ivl@EXEEXT@ check.vvp
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc*
|
||||
rm -rf dep ivl@EXEEXT@
|
||||
rm -rf dep
|
||||
|
||||
distclean: clean
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
|
||||
for dir in vpi ivlpp tgt-verilog tgt-pal driver driver-vpi; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
rm -f Makefile config.status config.log config.cache config.h
|
||||
rm -f _pli_types.h
|
||||
|
||||
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
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o
|
||||
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.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_lval.o elab_net.o elab_pexpr.o elab_scope.o \
|
||||
elab_sig.o emit.o eval.o eval_attrib.o \
|
||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||
load_module.o netlist.o netmisc.o net_assign.o \
|
||||
net_design.o net_event.o net_expr.o net_force.o net_func.o \
|
||||
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
|
||||
net_proc.o net_scope.o net_udp.o net_variable.o pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_dump.o \
|
||||
set_width.o sync.o \
|
||||
net_proc.o net_scope.o net_udp.o pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_dump.o pform_types.o \
|
||||
set_width.o symbol_search.o sync.o sys_funcs.o \
|
||||
verinum.o verireal.o target.o targets.o \
|
||||
Attrib.o HName.o LineInfo.o Module.o PData.o PDelays.o PEvent.o \
|
||||
PExpr.o PGate.o \
|
||||
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
|
||||
PExpr.o PGate.o PGenerate.o PSpec.o \
|
||||
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
|
||||
$(FF) $(TT)
|
||||
|
||||
@@ -141,22 +126,29 @@ ifeq (@WIN32@,yes)
|
||||
# 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@
|
||||
$(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@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||
else
|
||||
ivl@EXEEXT@: $O
|
||||
$(CXX) $(CXXFLAGS) $(rdynamic) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
endif
|
||||
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
else
|
||||
all: dep iverilog-vpi
|
||||
|
||||
iverilog-vpi: iverilog-vpi.sh
|
||||
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
||||
-e 's;@INCLUDEDIR@;@includedir@;' -e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||
-e 's;@IVCC@;$(CC);' \
|
||||
-e 's;@IVCXX@;$(CXX);' \
|
||||
-e 's;@IVCFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@INCLUDEDIR@;@includedir@;' \
|
||||
-e 's;@LIBDIR64@;@libdir64@;' \
|
||||
-e 's;@VPIDIR1@;@vpidir1@;' -e 's;@VPIDIR2@;@vpidir2@;' \
|
||||
-e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||
chmod +x $@
|
||||
endif
|
||||
|
||||
@@ -164,7 +156,7 @@ dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.cc
|
||||
$(CXX) -Wall @ident_support@ $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
|
||||
@@ -172,11 +164,9 @@ lexor.o: lexor.cc parse.h
|
||||
|
||||
parse.o: parse.cc
|
||||
|
||||
parse.cc: $(srcdir)/parse.y
|
||||
parse.cc parse.h: $(srcdir)/parse.y
|
||||
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
|
||||
|
||||
parse.h: parse.cc
|
||||
mv parse.cc.h parse.h || mv parse.hh parse.h
|
||||
mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
|
||||
|
||||
syn-rules.cc: $(srcdir)/syn-rules.y
|
||||
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
|
||||
@@ -195,7 +185,7 @@ iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
|
||||
iverilog-vpi.pdf: iverilog-vpi.ps
|
||||
ps2pdf iverilog-vpi.ps iverilog-vpi.pdf
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@MING32@,yes)
|
||||
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf $(mandir)/man1/iverilog-vpi.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
all: dep iverilog-vpi.pdf
|
||||
@@ -204,15 +194,16 @@ INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
endif
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@MINGW32@,yes)
|
||||
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
|
||||
else
|
||||
WIN32_INSTALL = $(bindir)/iverilog-vpi
|
||||
endif
|
||||
|
||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
|
||||
XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf
|
||||
|
||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC)
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp driver; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
|
||||
@@ -221,19 +212,18 @@ $(bindir)/iverilog-vpi: ./iverilog-vpi
|
||||
|
||||
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
|
||||
$(STRIP) $(strip_dynamic) $(libdir)/ivl/ivl@EXEEXT@
|
||||
|
||||
# Install iverilog.conf whenever ivl.exe is installed. This
|
||||
# forces iverilog.conf to be treated similarly, in spite of
|
||||
# dates in the source bundle.
|
||||
$(libdir)/ivl/iverilog.conf: $(libdir)/ivl/ivl@EXEEXT@
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog.conf $(libdir)/ivl/iverilog.conf
|
||||
$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf
|
||||
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(libdir)/ivl/xnf-s.conf
|
||||
|
||||
$(libdir)/ivl/xnf.conf: $(srcdir)/xnf.conf
|
||||
$(INSTALL_DATA) $(srcdir)/xnf.conf $(libdir)/ivl/xnf.conf
|
||||
|
||||
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(includedir)/ivl_target.h
|
||||
|
||||
$(includedir)/_pli_types.h: $(srcdir)/_pli_types.h
|
||||
$(INSTALL_DATA) $(srcdir)/_pli_types.h $(includedir)/_pli_types.h
|
||||
$(includedir)/_pli_types.h: _pli_types.h
|
||||
$(INSTALL_DATA) $< $(includedir)/_pli_types.h
|
||||
|
||||
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(includedir)/vpi_user.h
|
||||
@@ -252,7 +242,7 @@ $(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
|
||||
|
||||
# In windows installations, put a few examples and the quick_start
|
||||
# into the destination directory.
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@MINGW32@,yes)
|
||||
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
|
||||
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
|
||||
mv tmp.vl $(prefix)/hello.vl
|
||||
@@ -276,17 +266,16 @@ installdirs: mkinstalldirs
|
||||
|
||||
uninstall:
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp driver; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
for f in iverilog.conf ivl; \
|
||||
for f in xnf.conf xnf-s.conf ivl@EXEEXT@; \
|
||||
do rm -f $(libdir)/ivl/$$f; done
|
||||
-rmdir $(libdir)/ivl
|
||||
for f in verilog iverilog-vpi gverilog@EXEEXT@; \
|
||||
do rm -f $(bindir)/$$f; done
|
||||
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
|
||||
do rm -f $(includedir)/$$f; done
|
||||
rm -f $(mandir)/man1/iverilog-vpi.1
|
||||
rm -f $(mandir)/man1/iverilog-vpi.1 $(prefix)/iverilog-vpi.pdf
|
||||
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.cc,v 1.21 2003/04/02 03:00:14 steve Exp $"
|
||||
#ident "$Id: Module.cc,v 1.27 2007/05/24 04:07:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -28,9 +28,11 @@
|
||||
# include <assert.h>
|
||||
|
||||
/* n is a permallocated string. */
|
||||
Module::Module(const char*n)
|
||||
Module::Module(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
library_flag = false;
|
||||
default_nettype = NetNet::NONE;
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
@@ -42,12 +44,12 @@ void Module::add_gate(PGate*gate)
|
||||
gates_.push_back(gate);
|
||||
}
|
||||
|
||||
void Module::add_task(const string&name, PTask*task)
|
||||
void Module::add_task(perm_string name, PTask*task)
|
||||
{
|
||||
tasks_[name] = task;
|
||||
}
|
||||
|
||||
void Module::add_function(const string &name, PFunction *func)
|
||||
void Module::add_function(perm_string name, PFunction *func)
|
||||
{
|
||||
funcs_[name] = func;
|
||||
}
|
||||
@@ -75,7 +77,7 @@ unsigned Module::port_count() const
|
||||
/*
|
||||
* Return the array of PEIdent object that are at this port of the
|
||||
* module. If the port is internally unconnected, return an empty
|
||||
* array.
|
||||
* array.
|
||||
*/
|
||||
const svector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
{
|
||||
@@ -88,7 +90,7 @@ const svector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
return zero;
|
||||
}
|
||||
|
||||
unsigned Module::find_port(const string&name) const
|
||||
unsigned Module::find_port(const char*name) const
|
||||
{
|
||||
assert(name != "");
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
@@ -109,16 +111,16 @@ unsigned Module::find_port(const string&name) const
|
||||
}
|
||||
|
||||
|
||||
PWire* Module::get_wire(const hname_t&name) const
|
||||
PWire* Module::get_wire(const pform_name_t&name) const
|
||||
{
|
||||
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
|
||||
map<pform_name_t,PWire*>::const_iterator obj = wires_.find(name);
|
||||
if (obj == wires_.end())
|
||||
return 0;
|
||||
else
|
||||
return (*obj).second;
|
||||
}
|
||||
|
||||
PGate* Module::get_gate(const string&name)
|
||||
PGate* Module::get_gate(perm_string name)
|
||||
{
|
||||
for (list<PGate*>::iterator cur = gates_.begin()
|
||||
; cur != gates_.end()
|
||||
@@ -131,11 +133,6 @@ PGate* Module::get_gate(const string&name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const map<hname_t,PWire*>& Module::get_wires() const
|
||||
{
|
||||
return wires_;
|
||||
}
|
||||
|
||||
const list<PGate*>& Module::get_gates() const
|
||||
{
|
||||
return gates_;
|
||||
@@ -149,6 +146,25 @@ const list<PProcess*>& Module::get_behaviors() const
|
||||
|
||||
/*
|
||||
* $Log: Module.cc,v $
|
||||
* Revision 1.27 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.26 2007/04/19 02:52:53 steve
|
||||
* Add support for -v flag in command file.
|
||||
*
|
||||
* Revision 1.25 2004/10/04 01:10:51 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.24 2004/06/13 04:56:53 steve
|
||||
* Add support for the default_nettype directive.
|
||||
*
|
||||
* Revision 1.23 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.22 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.21 2003/04/02 03:00:14 steve
|
||||
* Cope with empty module ports while binding by name.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __Module_H
|
||||
#define __Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,21 +19,24 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.h,v 1.32 2003/06/20 00:53:19 steve Exp $"
|
||||
#ident "$Id: Module.h,v 1.43 2007/05/24 04:07:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "HName.h"
|
||||
# include "named.h"
|
||||
# include "LineInfo.h"
|
||||
# include <string>
|
||||
class PData;
|
||||
# include "netlist.h"
|
||||
# include "pform_types.h"
|
||||
class PEvent;
|
||||
class PExpr;
|
||||
class PEIdent;
|
||||
class PGate;
|
||||
class PGenerate;
|
||||
class PSpecPath;
|
||||
class PTask;
|
||||
class PFunction;
|
||||
class PWire;
|
||||
@@ -56,16 +59,23 @@ class Module : public LineInfo {
|
||||
the port. */
|
||||
public:
|
||||
struct port_t {
|
||||
string name;
|
||||
perm_string name;
|
||||
svector<PEIdent*> expr;
|
||||
};
|
||||
|
||||
public:
|
||||
/* The name passed here is the module name, not the instance
|
||||
name. This make must be a permallocated string. */
|
||||
explicit Module(const char*name);
|
||||
explicit Module(perm_string name);
|
||||
~Module();
|
||||
|
||||
/* Initially false. This is set to true if the module has been
|
||||
declared as a library module. This makes the module
|
||||
ineligible for being chosen as an implicit root. It has no
|
||||
other effect. */
|
||||
bool library_flag;
|
||||
|
||||
NetNet::Type default_nettype;
|
||||
|
||||
/* The module has parameters that are evaluated when the
|
||||
module is elaborated. During parsing, I put the parameters
|
||||
@@ -76,20 +86,20 @@ class Module : public LineInfo {
|
||||
PExpr*lsb;
|
||||
bool signed_flag;
|
||||
};
|
||||
map<string,param_expr_t>parameters;
|
||||
map<string,param_expr_t>localparams;
|
||||
map<perm_string,param_expr_t>parameters;
|
||||
map<perm_string,param_expr_t>localparams;
|
||||
|
||||
|
||||
/* specparams are simpler then other params, in that they have
|
||||
no type information. They are merely constant
|
||||
expressions. */
|
||||
map<string,PExpr*>specparams;
|
||||
map<perm_string,PExpr*>specparams;
|
||||
|
||||
/* The module also has defparam assignments which don't create
|
||||
new parameters within the module, but may be used to set
|
||||
values within this module (when instantiated) or in other
|
||||
instantiated modules. */
|
||||
map<hname_t,PExpr*>defparms;
|
||||
map<pform_name_t,PExpr*>defparms;
|
||||
|
||||
/* Parameters may be overridden at instantiation time;
|
||||
the overrides do not contain explicit parameter names,
|
||||
@@ -97,25 +107,32 @@ class Module : public LineInfo {
|
||||
appear in the instantiated module. Therefore a
|
||||
list of names in module-order is needed to pass from
|
||||
a parameter-index to its name. */
|
||||
list<string> param_names;
|
||||
list<perm_string> param_names;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
svector<port_t*> ports;
|
||||
|
||||
/* Keep a table of named events declared in the module. */
|
||||
map<string,PEvent*>events;
|
||||
map<perm_string,PEvent*>events;
|
||||
|
||||
/* Keep a table of datum variables declared in the module. */
|
||||
map<hname_t,PData*>datum;
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
/* These are the timescale for this module. The default is
|
||||
set by the `timescale directive. */
|
||||
int time_unit, time_precision;
|
||||
|
||||
const char*mod_name() const { return name_; }
|
||||
/* The module has a list of genvars that may be used in
|
||||
various generate schemes. */
|
||||
list<perm_string> genvars;
|
||||
|
||||
/* the module has a list of generate schemes that appear in
|
||||
the module definition. These are used at elaboration time. */
|
||||
list<PGenerate*> generate_schemes;
|
||||
|
||||
list<PSpecPath*> specify_paths;
|
||||
|
||||
perm_string mod_name() const { return name_; }
|
||||
|
||||
void add_gate(PGate*gate);
|
||||
|
||||
@@ -125,37 +142,37 @@ class Module : public LineInfo {
|
||||
PWire* add_wire(PWire*wire);
|
||||
|
||||
void add_behavior(PProcess*behave);
|
||||
void add_task(const string&name, PTask*def);
|
||||
void add_function(const string&name, PFunction*def);
|
||||
void add_task(perm_string name, PTask*def);
|
||||
void add_function(perm_string name, PFunction*def);
|
||||
|
||||
unsigned port_count() const;
|
||||
const svector<PEIdent*>& get_port(unsigned idx) const;
|
||||
unsigned find_port(const string&) const;
|
||||
unsigned find_port(const char*name) const;
|
||||
|
||||
// Find a wire by name. This is used for connecting gates to
|
||||
// existing wires, etc.
|
||||
PWire* get_wire(const hname_t&name) const;
|
||||
PGate* get_gate(const string&name);
|
||||
PWire* get_wire(const pform_name_t&name) const;
|
||||
PGate* get_gate(perm_string name);
|
||||
|
||||
const map<hname_t,PWire*>& get_wires() const;
|
||||
const list<PGate*>& get_gates() const;
|
||||
const list<PProcess*>& get_behaviors() const;
|
||||
|
||||
void dump(ostream&out) const;
|
||||
bool elaborate(Design*, NetScope*scope) const;
|
||||
|
||||
bool elaborate_scope(Design*, NetScope*scope) const;
|
||||
typedef map<perm_string,NetExpr*> replace_t;
|
||||
bool elaborate_scope(Design*, NetScope*scope, const replace_t&rep) const;
|
||||
|
||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
const char* name_;
|
||||
perm_string name_;
|
||||
|
||||
map<hname_t,PWire*> wires_;
|
||||
map<pform_name_t,PWire*> wires_;
|
||||
list<PGate*> gates_;
|
||||
list<PProcess*> behaviors_;
|
||||
map<string,PTask*> tasks_;
|
||||
map<string,PFunction*> funcs_;
|
||||
map<perm_string,PTask*> tasks_;
|
||||
map<perm_string,PFunction*> funcs_;
|
||||
|
||||
private: // Not implemented
|
||||
Module(const Module&);
|
||||
@@ -165,30 +182,23 @@ class Module : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: Module.h,v $
|
||||
* Revision 1.32 2003/06/20 00:53:19 steve
|
||||
* Module attributes from the parser
|
||||
* through to elaborated form.
|
||||
* Revision 1.43 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.31 2003/06/13 19:10:45 steve
|
||||
* Properly manage real variables in subscopes.
|
||||
* Revision 1.42 2007/04/19 02:52:53 steve
|
||||
* Add support for -v flag in command file.
|
||||
*
|
||||
* Revision 1.30 2003/03/06 04:37:12 steve
|
||||
* lex_strings.add module names earlier.
|
||||
* Revision 1.41 2006/09/23 04:57:19 steve
|
||||
* Basic support for specify timing.
|
||||
*
|
||||
* Revision 1.29 2003/02/27 06:45:11 steve
|
||||
* specparams as far as pform.
|
||||
* Revision 1.40 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.28 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
* Revision 1.39 2006/03/30 01:49:07 steve
|
||||
* Fix instance arrays indexed by overridden parameters.
|
||||
*
|
||||
* 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.38 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
#ifndef __PData_H
|
||||
#define __PData_H
|
||||
/*
|
||||
* Copyright (c) 2003 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PData.h,v 1.1 2003/01/26 21:15:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "HName.h"
|
||||
# include "netlist.h"
|
||||
# include "LineInfo.h"
|
||||
|
||||
/*
|
||||
* The PData object represents declaration of atomic datum such as
|
||||
* real and realtime variables. These are variables that cannot be bit
|
||||
* or part selected, but can be used in expressions.
|
||||
*/
|
||||
|
||||
class PData : public LineInfo {
|
||||
|
||||
public:
|
||||
PData(const hname_t&hname);
|
||||
~PData();
|
||||
|
||||
// Return a hierarchical name.
|
||||
const hname_t&name() const;
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
private:
|
||||
hname_t hname_;
|
||||
|
||||
private:
|
||||
PData(const PData&);
|
||||
PData& operator= (const PData&);
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PData.h,v $
|
||||
* Revision 1.1 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+52
-15
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PDelays.cc,v 1.11 2003/06/21 01:21:42 steve Exp $"
|
||||
#ident "$Id: PDelays.cc,v 1.15 2006/07/08 21:48:46 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -62,11 +62,10 @@ void PDelays::set_delays(const svector<PExpr*>*del, bool df)
|
||||
delete_flag_ = df;
|
||||
}
|
||||
|
||||
static unsigned long calculate_val(Design*des, NetScope*scope,
|
||||
const PExpr*expr)
|
||||
static NetExpr*calculate_val(Design*des, NetScope*scope, const PExpr*expr)
|
||||
{
|
||||
|
||||
NetExpr*dex = expr->elaborate_expr(des, scope);
|
||||
NetExpr*dex = expr->elaborate_expr(des, scope, -1, false);
|
||||
if (NetExpr*tmp = dex->eval_tree()) {
|
||||
delete dex;
|
||||
dex = tmp;
|
||||
@@ -85,7 +84,9 @@ static unsigned long calculate_val(Design*des, NetScope*scope,
|
||||
delay = 0;
|
||||
|
||||
delete tmp;
|
||||
return delay;
|
||||
NetEConst*tmp2 = new NetEConst(verinum(delay));
|
||||
tmp2->set_line(*expr);
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,35 +97,57 @@ static unsigned long calculate_val(Design*des, NetScope*scope,
|
||||
des->scale_to_precision(fn.as_ulong(), scope);
|
||||
|
||||
delete tmp;
|
||||
return delay;
|
||||
NetEConst*tmp2 = new NetEConst(verinum(delay));
|
||||
tmp2->set_line(*expr);
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
/* Oops, cannot evaluate down to a constant. Error message. */
|
||||
delete dex;
|
||||
/* Oops, cannot evaluate down to a constant. */
|
||||
return dex;
|
||||
}
|
||||
|
||||
cerr << expr->get_line() << ": sorry: non-constant "
|
||||
<< "delays not supported here: " << *expr << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
static NetExpr* make_delay_nets(Design*des, NetExpr*expr)
|
||||
{
|
||||
if (dynamic_cast<NetESignal*> (expr))
|
||||
return expr;
|
||||
|
||||
if (dynamic_cast<NetEConst*> (expr))
|
||||
return expr;
|
||||
|
||||
NetNet*sig = expr->synthesize(des);
|
||||
if (sig == 0) {
|
||||
cerr << expr->get_line() << ": error: Expression " << *expr
|
||||
<< " is not suitable for delay expression." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
expr = new NetESignal(sig);
|
||||
return expr;
|
||||
}
|
||||
|
||||
void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
NetExpr*&decay_time,
|
||||
bool as_nets_flag) const
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
|
||||
if (delay_[0]) {
|
||||
rise_time = calculate_val(des, scope, delay_[0]);
|
||||
if (as_nets_flag)
|
||||
rise_time = make_delay_nets(des, rise_time);
|
||||
|
||||
if (delay_[1]) {
|
||||
fall_time = calculate_val(des, scope, delay_[1]);
|
||||
if (as_nets_flag)
|
||||
fall_time = make_delay_nets(des, fall_time);
|
||||
|
||||
if (delay_[2]) {
|
||||
decay_time = calculate_val(des, scope, delay_[2]);
|
||||
if (as_nets_flag)
|
||||
decay_time = make_delay_nets(des, decay_time);
|
||||
|
||||
} else {
|
||||
if (rise_time < fall_time)
|
||||
@@ -146,6 +169,20 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
|
||||
/*
|
||||
* $Log: PDelays.cc,v $
|
||||
* Revision 1.15 2006/07/08 21:48:46 steve
|
||||
* Handle real valued literals in net contexts.
|
||||
*
|
||||
* Revision 1.14 2006/06/02 04:48:49 steve
|
||||
* Make elaborate_expr methods aware of the width that the context
|
||||
* requires of it. In the process, fix sizing of the width of unary
|
||||
* minus is context determined sizes.
|
||||
*
|
||||
* Revision 1.13 2006/01/03 05:22:14 steve
|
||||
* Handle complex net node delays.
|
||||
*
|
||||
* Revision 1.12 2006/01/02 05:33:19 steve
|
||||
* Node delays can be more general expressions in structural contexts.
|
||||
*
|
||||
* Revision 1.11 2003/06/21 01:21:42 steve
|
||||
* Harmless fixup of warnings.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PDelays.h,v 1.7 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: PDelays.h,v 1.9 2006/01/03 05:22:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
@@ -34,6 +34,7 @@ using namespace std;
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class NetExpr;
|
||||
class PExpr;
|
||||
|
||||
/*
|
||||
@@ -53,9 +54,10 @@ class PDelays {
|
||||
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
|
||||
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const;
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
NetExpr*&decay_time,
|
||||
bool as_nets_flag =false) const;
|
||||
|
||||
void dump_delays(ostream&out) const;
|
||||
|
||||
@@ -72,6 +74,12 @@ ostream& operator << (ostream&o, const PDelays&);
|
||||
|
||||
/*
|
||||
* $Log: PDelays.h,v $
|
||||
* Revision 1.9 2006/01/03 05:22:14 steve
|
||||
* Handle complex net node delays.
|
||||
*
|
||||
* Revision 1.8 2006/01/02 05:33:19 steve
|
||||
* Node delays can be more general expressions in structural contexts.
|
||||
*
|
||||
* Revision 1.7 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,14 +17,14 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.cc,v 1.4 2003/03/01 06:25:30 steve Exp $"
|
||||
#ident "$Id: PEvent.cc,v 1.5 2004/02/19 06:57:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PEvent.h"
|
||||
|
||||
PEvent::PEvent(const char*n)
|
||||
PEvent::PEvent(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
}
|
||||
@@ -33,13 +33,16 @@ PEvent::~PEvent()
|
||||
{
|
||||
}
|
||||
|
||||
const char* PEvent::name() const
|
||||
perm_string PEvent::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PEvent.cc,v $
|
||||
* Revision 1.5 2004/02/19 06:57:10 steve
|
||||
* Memory and Event names use perm_string.
|
||||
*
|
||||
* Revision 1.4 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PEvent_H
|
||||
#define __PEvent_H
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,10 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.h,v 1.8 2003/03/01 06:25:30 steve Exp $"
|
||||
#ident "$Id: PEvent.h,v 1.9 2004/02/19 06:57:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
|
||||
class Design;
|
||||
@@ -36,16 +37,17 @@ class NetScope;
|
||||
class PEvent : public LineInfo {
|
||||
|
||||
public:
|
||||
// The name is a perm-allocated string.
|
||||
explicit PEvent(const char*name);
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
// of the event, without any scope.
|
||||
explicit PEvent(perm_string name);
|
||||
~PEvent();
|
||||
|
||||
const char* name() const;
|
||||
perm_string name() const;
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
const char* name_;
|
||||
perm_string name_;
|
||||
|
||||
private: // not implemented
|
||||
PEvent(const PEvent&);
|
||||
@@ -54,6 +56,9 @@ class PEvent : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PEvent.h,v $
|
||||
* Revision 1.9 2004/02/19 06:57:10 steve
|
||||
* Memory and Event names use perm_string.
|
||||
*
|
||||
* Revision 1.8 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.cc,v 1.33 2003/01/27 05:09:17 steve Exp $"
|
||||
#ident "$Id: PExpr.cc,v 1.39 2007/05/24 04:07:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -53,6 +53,14 @@ NetNet* PExpr::elaborate_lnet(Design*des, NetScope*, bool) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_bi_net(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_line() << ": error: "
|
||||
<< "expression not valid as argument to inout port: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
|
||||
: op_(op), left_(l), right_(r)
|
||||
{
|
||||
@@ -67,13 +75,44 @@ bool PEBinary::is_constant(Module*mod) const
|
||||
return left_->is_constant(mod) && right_->is_constant(mod);
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
|
||||
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBComp::~PEBComp()
|
||||
{
|
||||
}
|
||||
|
||||
PEBShift::PEBShift(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBShift::~PEBShift()
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms)
|
||||
: path_(n), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const hname_t&n)
|
||||
: path_(n)
|
||||
static pform_name_t pn_from_ps(perm_string n)
|
||||
{
|
||||
name_component_t tmp_name (n);
|
||||
pform_name_t tmp;
|
||||
tmp.push_back(tmp_name);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n, const svector<PExpr*>&parms)
|
||||
: path_(pn_from_ps(n)), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n)
|
||||
: path_(pn_from_ps(n))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -139,35 +178,40 @@ bool PEFNumber::is_constant(Module*) const
|
||||
return true;
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(const hname_t&s)
|
||||
: path_(s), msb_(0), lsb_(0), idx_(0)
|
||||
PEIdent::PEIdent(const pform_name_t&that)
|
||||
: path_(that)
|
||||
{
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(perm_string s)
|
||||
{
|
||||
path_.push_back(name_component_t(s));
|
||||
}
|
||||
|
||||
PEIdent::~PEIdent()
|
||||
{
|
||||
}
|
||||
|
||||
const hname_t& PEIdent::path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
/*
|
||||
* An identifier can be in a constant expression if (and only if) it is
|
||||
* a parameter.
|
||||
*
|
||||
* NOTE: This test does not work if the name is hierarchical!
|
||||
*/
|
||||
bool PEIdent::is_constant(Module*mod) const
|
||||
{
|
||||
if (mod == 0) return false;
|
||||
|
||||
{ map<string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->parameters.find(path_.peek_name(0));
|
||||
/* */
|
||||
perm_string tmp = path_.back().name;
|
||||
|
||||
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->parameters.find(tmp);
|
||||
if (cur != mod->parameters.end()) return true;
|
||||
}
|
||||
|
||||
{ map<string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->localparams.find(path_.peek_name(0));
|
||||
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->localparams.find(tmp);
|
||||
if (cur != mod->localparams.end()) return true;
|
||||
}
|
||||
|
||||
@@ -256,6 +300,25 @@ bool PEUnary::is_constant(Module*m) const
|
||||
|
||||
/*
|
||||
* $Log: PExpr.cc,v $
|
||||
* Revision 1.39 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.38 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.37 2005/10/04 04:09:25 steve
|
||||
* Add support for indexed select attached to parameters.
|
||||
*
|
||||
* Revision 1.36 2005/08/06 17:58:16 steve
|
||||
* Implement bi-directional part selects.
|
||||
*
|
||||
* Revision 1.35 2004/10/04 01:10:51 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.34 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.33 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
|
||||
@@ -19,13 +19,15 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.h,v 1.65 2003/02/08 19:49:21 steve Exp $"
|
||||
#ident "$Id: PExpr.h,v 1.90 2007/06/04 19:14:06 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include "netlist.h"
|
||||
# include "verinum.h"
|
||||
# include "LineInfo.h"
|
||||
# include "pform_types.h"
|
||||
|
||||
class Design;
|
||||
class Module;
|
||||
@@ -50,11 +52,38 @@ class PExpr : public LineInfo {
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
// Procedural elaboration of the expression. Set the
|
||||
// bare_memory_ok flag if the result is allowed to be a
|
||||
// NetEMemory without an index.
|
||||
// This method tests the width that the expression wants to
|
||||
// be. It is used by elaboration of assignments to figure out
|
||||
// the width of the expression.
|
||||
//
|
||||
// The "min" is the width of the local context, so it the
|
||||
// minimum width that this function should return. Initially
|
||||
// this is the same as the lval width.
|
||||
//
|
||||
// The "lval" is the width of the destination where this
|
||||
// result is going to go. This can be used to constrain the
|
||||
// amount that an expression can reasonably expand. For
|
||||
// example, there is no point expanding an addition to beyond
|
||||
// the lval. This extra bit of information allows the
|
||||
// expression to optimize itself a bit. If the lval==0, then
|
||||
// the subexpression should not make l-value related
|
||||
// optimizations.
|
||||
//
|
||||
// The unsigned_flag is set to true if the expression is
|
||||
// unsized and therefore expandable. This happens if a
|
||||
// sub-expression is an unsized literal. Some expressions make
|
||||
// special use of that.
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
bool&unsized_flag) const;
|
||||
|
||||
// Procedural elaboration of the expression. The expr_width is
|
||||
// the width of the context of the expression (i.e. the
|
||||
// l-value width of an assignment) or -1 if the expression is
|
||||
// self-determinted. The sys_task_arg flag is true if
|
||||
// expressions are allowed to be incomplete.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
bool sys_task_arg =false) const;
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
|
||||
// Elaborate expressions that are the r-value of parameter
|
||||
// assignments. This elaboration follows the restrictions of
|
||||
@@ -66,30 +95,37 @@ class PExpr : public LineInfo {
|
||||
// continuous assign or other wholly structural context.
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0 =Link::STRONG,
|
||||
Link::strength_t drive1 =Link::STRONG)
|
||||
const;
|
||||
|
||||
// This method elaborates the expression as NetNet objects. It
|
||||
// only allows regs suitable for procedural continuous assignments.
|
||||
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
|
||||
|
||||
// This method elaborates the expression as gates, but
|
||||
// restricted for use as l-values of continuous assignments.
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool implicit_net_ok =false) const;
|
||||
|
||||
// This is similar to elaborate_lnet, except that the
|
||||
// expression is evaluated to be bi-directional. This is
|
||||
// useful for arguments to inout ports of module instances and
|
||||
// ports of tran primitives.
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
||||
|
||||
// Expressions that can be in the l-value of procedural
|
||||
// assignments can be elaborated with this method.
|
||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
// assignments can be elaborated with this method. If the
|
||||
// is_force flag is true, then the set of valid l-value types
|
||||
// is slightly modified to accomodate the Verilog force
|
||||
// statement
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_force) const;
|
||||
|
||||
// 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 NetScope*sc) const;
|
||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
|
||||
// This method returns true if that expression is the same as
|
||||
// this expression. This method is used for comparing
|
||||
@@ -115,27 +151,31 @@ class PEConcat : public PExpr {
|
||||
PEConcat(const svector<PExpr*>&p, PExpr*r =0);
|
||||
~PEConcat();
|
||||
|
||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
// Concatenated Regs can be on the left of procedural
|
||||
// continuous assignments.
|
||||
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
|
||||
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool implicit_net_ok =false) const;
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_force) const;
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
private:
|
||||
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
bool implicit_net_ok,
|
||||
bool bidirectional_flag) const;
|
||||
private:
|
||||
svector<PExpr*>parms_;
|
||||
PExpr*repeat_;
|
||||
@@ -160,7 +200,7 @@ class PEEvent : public PExpr {
|
||||
|
||||
edge_t type() const;
|
||||
PExpr* expr() const;
|
||||
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
private:
|
||||
@@ -182,15 +222,23 @@ 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 NetScope*sc) const;
|
||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
|
||||
/* A PEFNumber is a constant, so this returns true. */
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
private:
|
||||
@@ -200,32 +248,41 @@ class PEFNumber : public PExpr {
|
||||
class PEIdent : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEIdent(const hname_t&s);
|
||||
explicit PEIdent(perm_string);
|
||||
explicit PEIdent(const pform_name_t&);
|
||||
~PEIdent();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
// Add another name to the string of heirarchy that is the
|
||||
// current identifier.
|
||||
void append_name(perm_string);
|
||||
|
||||
// Regs can be on the left of procedural continuous assignments
|
||||
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&) const;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
bool&unsized_flag) const;
|
||||
|
||||
// Identifiers are allowed (with restrictions) is assign l-values.
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool implicit_net_ok =false) const;
|
||||
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
||||
|
||||
// Identifiers are also allowed as procedural assignment l-values.
|
||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_force) const;
|
||||
|
||||
// Structural r-values are OK.
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
|
||||
// Elaborate the PEIdent as a port to a module. This method
|
||||
@@ -233,39 +290,86 @@ 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 NetScope*sc) const;
|
||||
verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
|
||||
const hname_t& path() const;
|
||||
const pform_name_t& path() const { return path_; }
|
||||
|
||||
private:
|
||||
hname_t path_;
|
||||
pform_name_t path_;
|
||||
|
||||
private:
|
||||
// Common functions to calculate parts of part/bit selects.
|
||||
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb) const;
|
||||
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
|
||||
|
||||
private:
|
||||
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
|
||||
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
|
||||
bool elaborate_lval_net_idx_up_(Design*, NetScope*, NetAssign_*) const;
|
||||
bool elaborate_lval_net_idx_do_(Design*, NetScope*, NetAssign_*) const;
|
||||
|
||||
private:
|
||||
NetExpr*elaborate_expr_param(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb) const;
|
||||
NetExpr*elaborate_expr_net(Design*des,
|
||||
NetScope*scope,
|
||||
NetNet*net,
|
||||
NetScope*found,
|
||||
bool sys_task_arg) const;
|
||||
NetExpr*elaborate_expr_net_word_(Design*des,
|
||||
NetScope*scope,
|
||||
NetNet*net,
|
||||
NetScope*found,
|
||||
bool sys_task_arg) const;
|
||||
NetExpr*elaborate_expr_net_part_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found) const;
|
||||
NetExpr*elaborate_expr_net_idx_up_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found) const;
|
||||
NetExpr*elaborate_expr_net_idx_do_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found) const;
|
||||
NetExpr*elaborate_expr_net_bit_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found) const;
|
||||
|
||||
public:
|
||||
// Use these to support bit- and part-select operators.
|
||||
PExpr*msb_;
|
||||
PExpr*lsb_;
|
||||
|
||||
// If this is a reference to a memory, this is the index
|
||||
// expression.
|
||||
PExpr*idx_;
|
||||
|
||||
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_array_(Design*des, NetScope*scope,
|
||||
NetNet*sig, unsigned lwidth,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
|
||||
NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope,
|
||||
NetNet*sig,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
|
||||
private:
|
||||
NetAssign_* elaborate_mem_lval_(Design*des, NetScope*scope,
|
||||
NetMemory*mem) const;
|
||||
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
bool implicit_net_ok,
|
||||
bool bidirectional_flag) const;
|
||||
|
||||
NetNet*make_implicit_net_(Design*des, NetScope*scope) const;
|
||||
|
||||
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
unsigned&midx, unsigned&lidx) const;
|
||||
NetNet*process_select_(Design*des, NetScope*scope, NetNet*sig) const;
|
||||
|
||||
};
|
||||
|
||||
@@ -278,19 +382,25 @@ class PENumber : public PExpr {
|
||||
const verinum& value() const;
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
bool&unsized_flag) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
int expr_width, bool) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_force) const;
|
||||
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
|
||||
virtual bool is_the_same(const PExpr*that) const;
|
||||
virtual bool is_constant(Module*) const;
|
||||
@@ -314,17 +424,22 @@ class PEString : public PExpr {
|
||||
|
||||
string value() const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
bool&unsized_flag) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
int expr_width, bool) const;
|
||||
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
verinum* PEString::eval_const(const Design*, const NetScope*) const;
|
||||
verinum* eval_const(Design*, NetScope*) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
@@ -339,17 +454,18 @@ class PEUnary : public PExpr {
|
||||
~PEUnary();
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
@@ -367,65 +483,100 @@ class PEBinary : public PExpr {
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
bool&unsized_flag) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEBinary*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
|
||||
private:
|
||||
protected:
|
||||
char op_;
|
||||
PExpr*left_;
|
||||
PExpr*right_;
|
||||
|
||||
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
|
||||
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
|
||||
NetEBinary*elaborate_eval_expr_base_(Design*, NetExpr*lp, NetExpr*rp, int use_wid) const;
|
||||
|
||||
private:
|
||||
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay) const;
|
||||
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay) const;
|
||||
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay) const;
|
||||
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay) const;
|
||||
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay) const;
|
||||
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay) const;
|
||||
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay) const;
|
||||
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* Here are a few specilized classes for handling specific binary
|
||||
* operators.
|
||||
*/
|
||||
class PEBComp : public PEBinary {
|
||||
|
||||
public:
|
||||
explicit PEBComp(char op, PExpr*l, PExpr*r);
|
||||
~PEBComp();
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
bool&flag) const;
|
||||
|
||||
NetEBinary* elaborate_expr(Design*des, NetScope*scope,
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
};
|
||||
|
||||
class PEBShift : public PEBinary {
|
||||
|
||||
public:
|
||||
explicit PEBShift(char op, PExpr*l, PExpr*r);
|
||||
~PEBShift();
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval, bool&flag) const;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -441,17 +592,21 @@ class PETernary : public PExpr {
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
unsigned min, unsigned lval,
|
||||
bool&unsized_flag) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetETernary*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
@@ -466,32 +621,134 @@ class PETernary : public PExpr {
|
||||
*/
|
||||
class PECallFunction : public PExpr {
|
||||
public:
|
||||
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
|
||||
explicit PECallFunction(const hname_t&n);
|
||||
explicit PECallFunction(const pform_name_t&n, const svector<PExpr *> &parms);
|
||||
// Call of system function (name is not heirarchical)
|
||||
explicit PECallFunction(perm_string n, const svector<PExpr *> &parms);
|
||||
explicit PECallFunction(perm_string n);
|
||||
~PECallFunction();
|
||||
|
||||
virtual void dump(ostream &) const;
|
||||
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
bool sys_task_arg =false) const;
|
||||
int expr_wid, bool sys_task_arg) const;
|
||||
|
||||
private:
|
||||
hname_t path_;
|
||||
pform_name_t path_;
|
||||
svector<PExpr *> parms_;
|
||||
|
||||
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
||||
|
||||
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
|
||||
NetNet* elaborate_net_sfunc_(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
const NetExpr* rise,
|
||||
const NetExpr* fall,
|
||||
const NetExpr* decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* Revision 1.90 2007/06/04 19:14:06 steve
|
||||
* Build errors in picky GCC compilers.
|
||||
*
|
||||
* Revision 1.89 2007/06/04 02:19:07 steve
|
||||
* Handle bit/part select of array words in nets.
|
||||
*
|
||||
* Revision 1.88 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.87 2007/01/16 05:44:14 steve
|
||||
* Major rework of array handling. Memories are replaced with the
|
||||
* more general concept of arrays. The NetMemory and NetEMemory
|
||||
* classes are removed from the ivl core program, and the IVL_LPM_RAM
|
||||
* lpm type is removed from the ivl_target API.
|
||||
*
|
||||
* Revision 1.86 2006/11/10 04:54:26 steve
|
||||
* Add test_width methods for PETernary and PEString.
|
||||
*
|
||||
* Revision 1.85 2006/11/04 06:19:24 steve
|
||||
* Remove last bits of relax_width methods, and use test_width
|
||||
* to calculate the width of an r-value expression that may
|
||||
* contain unsized numbers.
|
||||
*
|
||||
* Revision 1.84 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.83 2006/06/18 04:15:50 steve
|
||||
* Add support for system functions in continuous assignments.
|
||||
*
|
||||
* Revision 1.82 2006/06/02 04:48:49 steve
|
||||
* Make elaborate_expr methods aware of the width that the context
|
||||
* requires of it. In the process, fix sizing of the width of unary
|
||||
* minus is context determined sizes.
|
||||
*
|
||||
* Revision 1.81 2006/04/28 04:28:35 steve
|
||||
* Allow concatenations as arguments to inout ports.
|
||||
*
|
||||
* Revision 1.80 2006/04/16 00:54:04 steve
|
||||
* Cleanup lval part select handling.
|
||||
*
|
||||
* Revision 1.79 2006/04/16 00:15:43 steve
|
||||
* Fix part selects in l-values.
|
||||
*
|
||||
* Revision 1.78 2006/03/25 02:36:26 steve
|
||||
* Get rid of excess PESTring:: prefix within class declaration.
|
||||
*
|
||||
* Revision 1.77 2006/02/02 02:43:57 steve
|
||||
* Allow part selects of memory words in l-values.
|
||||
*
|
||||
* Revision 1.76 2006/01/02 05:33:19 steve
|
||||
* Node delays can be more general expressions in structural contexts.
|
||||
*
|
||||
* Revision 1.75 2005/12/07 04:04:23 steve
|
||||
* Allow constant concat expressions.
|
||||
*
|
||||
* Revision 1.74 2005/11/27 17:01:56 steve
|
||||
* Fix for stubborn compiler.
|
||||
*
|
||||
* Revision 1.73 2005/11/27 05:56:20 steve
|
||||
* Handle bit select of parameter with ranges.
|
||||
*
|
||||
* Revision 1.72 2005/11/10 13:28:11 steve
|
||||
* Reorganize signal part select handling, and add support for
|
||||
* indexed part selects.
|
||||
*
|
||||
* Expand expression constant propagation to eliminate extra
|
||||
* sums in certain cases.
|
||||
*
|
||||
* Revision 1.71 2005/10/04 04:09:25 steve
|
||||
* Add support for indexed select attached to parameters.
|
||||
*
|
||||
* Revision 1.70 2005/08/06 17:58:16 steve
|
||||
* Implement bi-directional part selects.
|
||||
*
|
||||
* Revision 1.69 2005/07/07 16:22:49 steve
|
||||
* Generalize signals to carry types.
|
||||
*
|
||||
* Revision 1.68 2005/01/09 20:16:00 steve
|
||||
* Use PartSelect/PV and VP to handle part selects through ports.
|
||||
*
|
||||
* Revision 1.67 2004/12/29 23:55:43 steve
|
||||
* Unify elaboration of l-values for all proceedural assignments,
|
||||
* including assing, cassign and force.
|
||||
*
|
||||
* Generate NetConcat devices for gate outputs that feed into a
|
||||
* vector results. Use this to hande gate arrays. Also let gate
|
||||
* arrays handle vectors of gates when the outputs allow for it.
|
||||
*
|
||||
* Revision 1.66 2004/10/04 01:10:51 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.65 2003/02/08 19:49:21 steve
|
||||
* Calculate delay statement delays using elaborated
|
||||
* expressions instead of pre-elaborated expression
|
||||
|
||||
+11
-6
@@ -17,16 +17,17 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PFunction.cc,v 1.6 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: PFunction.cc,v 1.7 2004/05/31 23:34:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
#include "PTask.h"
|
||||
|
||||
PFunction::PFunction()
|
||||
: out_(0), ports_(0), statement_(0)
|
||||
PFunction::PFunction(perm_string name)
|
||||
: name_(name), ports_(0), statement_(0)
|
||||
{
|
||||
return_type_.type = PTF_NONE;
|
||||
}
|
||||
|
||||
PFunction::~PFunction()
|
||||
@@ -46,14 +47,18 @@ void PFunction::set_statement(Statement*s)
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
void PFunction::set_output(PWire*o)
|
||||
void PFunction::set_return(PTaskFuncArg t)
|
||||
{
|
||||
assert(out_ == 0);
|
||||
out_ = o;
|
||||
return_type_ = t;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PFunction.cc,v $
|
||||
* Revision 1.7 2004/05/31 23:34:36 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.cc,v 1.15 2003/03/06 04:37:12 steve Exp $"
|
||||
#ident "$Id: PGate.cc,v 1.18 2006/01/03 05:22:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -27,7 +27,7 @@
|
||||
# include "verinum.h"
|
||||
# include <assert.h>
|
||||
|
||||
PGate::PGate(const string&name,
|
||||
PGate::PGate(perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
const svector<PExpr*>*del)
|
||||
: name_(name), pins_(pins)
|
||||
@@ -37,7 +37,7 @@ PGate::PGate(const string&name,
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(const string&name,
|
||||
PGate::PGate(perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: name_(name), pins_(pins)
|
||||
@@ -47,7 +47,7 @@ PGate::PGate(const string&name,
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(const string&name, svector<PExpr*>*pins)
|
||||
PGate::PGate(perm_string name, svector<PExpr*>*pins)
|
||||
: name_(name), pins_(pins)
|
||||
{
|
||||
str0_ = STRONG;
|
||||
@@ -90,22 +90,79 @@ 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, NetScope*scope,
|
||||
NetExpr*&rise_expr,
|
||||
NetExpr*&fall_expr,
|
||||
NetExpr*&decay_expr,
|
||||
bool as_net_flag) const
|
||||
{
|
||||
delay_.eval_delays(des, scope,
|
||||
rise_expr, fall_expr, decay_expr,
|
||||
as_net_flag);
|
||||
}
|
||||
|
||||
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, scope, rise_time, fall_time, decay_time);
|
||||
NetExpr*rise_expr, *fall_expr, *decay_expr;
|
||||
delay_.eval_delays(des, scope, rise_expr, fall_expr, decay_expr);
|
||||
|
||||
if (rise_expr == 0) {
|
||||
rise_time = 0;
|
||||
fall_time = 0;
|
||||
decay_time = 0;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*> (rise_expr)) {
|
||||
rise_time = tmp->value().as_ulong();
|
||||
|
||||
} else {
|
||||
cerr << get_line() << ": error: Delay expressions must be "
|
||||
<< "constant here." << endl;
|
||||
cerr << get_line() << ": : Cannot calculate "
|
||||
<< *rise_expr << endl;
|
||||
des->errors += 1;
|
||||
rise_time = 0;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*> (fall_expr)) {
|
||||
fall_time = tmp->value().as_ulong();
|
||||
|
||||
} else {
|
||||
if (fall_expr != rise_expr) {
|
||||
cerr << get_line() << ": error: Delay expressions must be "
|
||||
<< "constant here." << endl;
|
||||
cerr << get_line() << ": : Cannot calculate "
|
||||
<< *rise_expr << endl;
|
||||
}
|
||||
des->errors += 1;
|
||||
fall_time = 0;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*> (decay_expr)) {
|
||||
decay_time = tmp->value().as_ulong();
|
||||
|
||||
} else {
|
||||
cerr << get_line() << ": error: Delay expressions must be "
|
||||
<< "constant here." << endl;
|
||||
cerr << get_line() << ": : Cannot calculate "
|
||||
<< *rise_expr << endl;
|
||||
des->errors += 1;
|
||||
decay_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins)
|
||||
: PGate("", pins)
|
||||
: PGate(perm_string(), pins)
|
||||
{
|
||||
assert(pins->count() == 2);
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels)
|
||||
: PGate("", pins, dels)
|
||||
: PGate(perm_string(), pins, dels)
|
||||
{
|
||||
assert(pins->count() == 2);
|
||||
}
|
||||
@@ -114,14 +171,14 @@ PGAssign::~PGAssign()
|
||||
{
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, const string&name,
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
svector<PExpr*>*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, const string&name,
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
@@ -142,14 +199,14 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
PGModule::PGModule(const char*type, const string&name, svector<PExpr*>*pins)
|
||||
PGModule::PGModule(perm_string type, perm_string name, svector<PExpr*>*pins)
|
||||
: PGate(name, pins), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::PGModule(const char*type, const string&name,
|
||||
PGModule::PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins)
|
||||
: PGate(name, 0), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
@@ -184,13 +241,22 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
const char* PGModule::get_type()
|
||||
perm_string PGModule::get_type()
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PGate.cc,v $
|
||||
* Revision 1.18 2006/01/03 05:22:14 steve
|
||||
* Handle complex net node delays.
|
||||
*
|
||||
* Revision 1.17 2006/01/02 05:33:19 steve
|
||||
* Node delays can be more general expressions in structural contexts.
|
||||
*
|
||||
* Revision 1.16 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.15 2003/03/06 04:37:12 steve
|
||||
* lex_strings.add module names earlier.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PGate_H
|
||||
#define __PGate_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,10 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.h,v 1.25 2003/03/06 04:37:12 steve Exp $"
|
||||
#ident "$Id: PGate.h,v 1.32 2006/04/10 00:37:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "named.h"
|
||||
# include "LineInfo.h"
|
||||
# include "PDelays.h"
|
||||
@@ -49,27 +50,39 @@ class Module;
|
||||
* strength of the 1 drive.
|
||||
*/
|
||||
class PGate : public LineInfo {
|
||||
|
||||
|
||||
public:
|
||||
enum strength_t { HIGHZ, WEAK, PULL, STRONG, SUPPLY };
|
||||
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins,
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins,
|
||||
const svector<PExpr*>*del);
|
||||
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins,
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins);
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins);
|
||||
|
||||
virtual ~PGate();
|
||||
|
||||
const string& get_name() const { return name_; }
|
||||
perm_string get_name() const { return name_; }
|
||||
|
||||
// This method evaluates the delays all the way to an
|
||||
// integer. If the delay is non-constant, then set the times
|
||||
// to 0, print an error message and mark an error to the
|
||||
// design.
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const;
|
||||
|
||||
// This evaluates the delays as far as possible, but returns
|
||||
// an expression, and do not signal errors.
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
NetExpr*&decay_time,
|
||||
bool as_net_flag =false) const;
|
||||
|
||||
unsigned pin_count() const { return pins_? pins_->count() : 0; }
|
||||
const PExpr*pin(unsigned idx) const { return (*pins_)[idx]; }
|
||||
|
||||
@@ -79,21 +92,21 @@ class PGate : public LineInfo {
|
||||
void strength0(strength_t);
|
||||
void strength1(strength_t);
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
protected:
|
||||
const svector<PExpr*>* get_pins() const { return pins_; }
|
||||
const svector<PExpr*>& get_pins() const { return *pins_; }
|
||||
|
||||
void dump_pins(ostream&out) const;
|
||||
void dump_delays(ostream&out) const;
|
||||
|
||||
private:
|
||||
const string name_;
|
||||
perm_string name_;
|
||||
PDelays delay_;
|
||||
svector<PExpr*>*pins_;
|
||||
|
||||
@@ -115,7 +128,7 @@ class PGAssign : public PGate {
|
||||
explicit PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels);
|
||||
~PGAssign();
|
||||
|
||||
void dump(ostream&out) const;
|
||||
void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
@@ -141,10 +154,10 @@ class PGBuiltin : public PGate {
|
||||
TRANIF1, RTRANIF0, RTRANIF1 };
|
||||
|
||||
public:
|
||||
explicit PGBuiltin(Type t, const string&name,
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
svector<PExpr*>*del);
|
||||
explicit PGBuiltin(Type t, const string&name,
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
~PGBuiltin();
|
||||
@@ -152,7 +165,7 @@ class PGBuiltin : public PGate {
|
||||
Type type() const { return type_; }
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
@@ -171,17 +184,16 @@ class PGBuiltin : public PGate {
|
||||
class PGModule : public PGate {
|
||||
|
||||
public:
|
||||
// NOTE: The type parameter to all the constructors is assumed
|
||||
// to have been permallocated.
|
||||
// The name is the *instance* name of the gate.
|
||||
|
||||
// If the binding of ports is by position, this constructor
|
||||
// builds everything all at once.
|
||||
explicit PGModule(const char*type, const string&name,
|
||||
explicit PGModule(perm_string type, perm_string name,
|
||||
svector<PExpr*>*pins);
|
||||
|
||||
// If the binding of ports is by name, this constructor takes
|
||||
// the bindings and stores them for later elaboration.
|
||||
explicit PGModule(const char*type, const string&name,
|
||||
explicit PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins);
|
||||
|
||||
|
||||
@@ -196,17 +208,17 @@ class PGModule : public PGate {
|
||||
// method to pass the range to the pform.
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void dump(ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
// This returns the module name of this module. It is a
|
||||
// permallocated string.
|
||||
const char* get_type();
|
||||
perm_string get_type();
|
||||
|
||||
private:
|
||||
const char* type_;
|
||||
perm_string type_;
|
||||
svector<PExpr*>*overrides_;
|
||||
named<PExpr*>*pins_;
|
||||
unsigned npins_;
|
||||
@@ -227,6 +239,27 @@ class PGModule : public PGate {
|
||||
|
||||
/*
|
||||
* $Log: PGate.h,v $
|
||||
* Revision 1.32 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.31 2006/01/03 05:22:14 steve
|
||||
* Handle complex net node delays.
|
||||
*
|
||||
* Revision 1.30 2006/01/02 05:33:19 steve
|
||||
* Node delays can be more general expressions in structural contexts.
|
||||
*
|
||||
* Revision 1.29 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.28 2004/03/08 00:47:44 steve
|
||||
* primitive ports can bind bi name.
|
||||
*
|
||||
* Revision 1.27 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.26 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.25 2003/03/06 04:37:12 steve
|
||||
* lex_strings.add module names earlier.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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: PGenerate.cc,v 1.4 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PGenerate.h"
|
||||
# include "PWire.h"
|
||||
|
||||
PGenerate::PGenerate(unsigned id)
|
||||
: id_number(id)
|
||||
{
|
||||
parent = 0;
|
||||
}
|
||||
|
||||
PGenerate::~PGenerate()
|
||||
{
|
||||
}
|
||||
|
||||
PWire* PGenerate::add_wire(PWire*wire)
|
||||
{
|
||||
PWire*&ep = wires[wire->path()];
|
||||
if (ep) return ep;
|
||||
|
||||
assert(ep == 0);
|
||||
ep = wire;
|
||||
return wire;
|
||||
}
|
||||
|
||||
PWire* PGenerate::get_wire(const pform_name_t&name) const
|
||||
{
|
||||
map<pform_name_t,PWire*>::const_iterator obj = wires.find(name);
|
||||
if (obj == wires.end())
|
||||
return 0;
|
||||
else
|
||||
return (*obj).second;
|
||||
}
|
||||
|
||||
void PGenerate::add_gate(PGate*gate)
|
||||
{
|
||||
gates.push_back(gate);
|
||||
}
|
||||
|
||||
void PGenerate::add_behavior(PProcess*proc)
|
||||
{
|
||||
behaviors.push_back(proc);
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
#ifndef __PGenerate_H
|
||||
#define __PGenerate_H
|
||||
/*
|
||||
* Copyright (c) 2006 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: PGenerate.h,v 1.4 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include "HName.h"
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "pform_types.h"
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class PExpr;
|
||||
class PProcess;
|
||||
class PGate;
|
||||
class PWire;
|
||||
|
||||
/*
|
||||
* This represents a generate scheme.
|
||||
*/
|
||||
class PGenerate : public LineInfo {
|
||||
|
||||
public:
|
||||
PGenerate(unsigned id_number);
|
||||
~PGenerate();
|
||||
|
||||
// Generate schemes have an ID number, for when the scope is
|
||||
// implicit.
|
||||
const unsigned id_number;
|
||||
perm_string scope_name;
|
||||
|
||||
enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT};
|
||||
scheme_t scheme_type;
|
||||
|
||||
// generate loops have an index variable and three
|
||||
// expressions: for (index = <init>; <test>; index=<step>)
|
||||
perm_string loop_index;
|
||||
PExpr*loop_init;
|
||||
PExpr*loop_test;
|
||||
PExpr*loop_step;
|
||||
|
||||
map<pform_name_t,PWire*>wires;
|
||||
PWire* add_wire(PWire*);
|
||||
PWire* get_wire(const pform_name_t&name) const;
|
||||
|
||||
list<PGate*> gates;
|
||||
void add_gate(PGate*);
|
||||
|
||||
list<PProcess*> behaviors;
|
||||
void add_behavior(PProcess*behave);
|
||||
|
||||
list<PGenerate*> generates;
|
||||
PGenerate*parent;
|
||||
|
||||
// This method is called by the elaboration of a module to
|
||||
// generate scopes. the container is the scope that is to
|
||||
// contain the generated scope.
|
||||
bool generate_scope(Design*des, NetScope*container);
|
||||
|
||||
bool elaborate_sig(Design*des) const;
|
||||
bool elaborate(Design*des) const;
|
||||
|
||||
void dump(ostream&out, unsigned indent) const;
|
||||
|
||||
private:
|
||||
bool generate_scope_loop_(Design*des, NetScope*container);
|
||||
|
||||
// These are the scopes created by generate_scope.
|
||||
list<NetScope*>scope_list_;
|
||||
// internal function called on each scope generated by this scheme.
|
||||
bool elaborate_sig_(Design*des, NetScope*scope) const;
|
||||
bool elaborate_(Design*des, NetScope*scope) const;
|
||||
|
||||
private: // not implemented
|
||||
PGenerate(const PGenerate&);
|
||||
PGenerate& operator= (const PGenerate&);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2006 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: PSpec.cc,v 1.2 2007/02/12 01:52:21 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PSpec.h"
|
||||
|
||||
PSpecPath::PSpecPath(unsigned src_cnt, unsigned dst_cnt)
|
||||
: conditional(false), condition(0), edge(0),
|
||||
src(src_cnt), dst(dst_cnt),
|
||||
data_source_expression(0)
|
||||
{
|
||||
}
|
||||
|
||||
PSpecPath::~PSpecPath()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef __PSpec_H
|
||||
#define __PSpec_H
|
||||
/*
|
||||
* Copyright (c) 2006 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: PSpec.h,v 1.3 2007/04/13 02:34:35 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <vector>
|
||||
|
||||
class PExpr;
|
||||
|
||||
/*
|
||||
* The PSpecPath is the parse of a specify path, which is in its most
|
||||
* general form <path> = <delays>. The <delays> are collected into the
|
||||
* "delays" vector in all cases, and the variety is in the other
|
||||
* members.
|
||||
*
|
||||
* All paths also have a list of source names in the src vector, and a
|
||||
* list of destination names in the dst vector. These pairs are the
|
||||
* actual paths.
|
||||
*
|
||||
* If the path is a simple path, then:
|
||||
* condition == nil
|
||||
* edge == 0
|
||||
* data_source_expression == nil
|
||||
*
|
||||
* If the path is conditional, then conditional == true and condition
|
||||
* is the condition expression. If the condition expression is nil,
|
||||
* then this is an ifnone conditional path.
|
||||
*
|
||||
* If data_source_expression != nil, then the path is edge sensitive
|
||||
* and the edge might not be 0.
|
||||
*/
|
||||
class PSpecPath : public LineInfo {
|
||||
|
||||
public:
|
||||
PSpecPath(unsigned src_cnt, unsigned dst_cnt);
|
||||
~PSpecPath();
|
||||
|
||||
void elaborate(class Design*des, class NetScope*scope) const;
|
||||
|
||||
void dump(std::ostream&out, unsigned ind) const;
|
||||
|
||||
public:
|
||||
// Condition expression, if present.
|
||||
bool conditional;
|
||||
class PExpr* condition;
|
||||
// Edge specification (-1==negedge, 0 = no edge, 1==posedge)
|
||||
int edge;
|
||||
// Ordered set of source nodes of a path
|
||||
std::vector<perm_string> src;
|
||||
// Ordered set of destination nodes of a path
|
||||
std::vector<perm_string> dst;
|
||||
// Data source expression
|
||||
class PExpr* data_source_expression;
|
||||
|
||||
std::vector<class PExpr*>delays;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -19,16 +19,33 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PTask.h,v 1.12 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: PTask.h,v 1.14 2007/03/06 05:22:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
class Design;
|
||||
class NetScope;
|
||||
class PWire;
|
||||
class Statement;
|
||||
class PExpr;
|
||||
|
||||
enum PTaskFuncEnum {
|
||||
PTF_NONE,
|
||||
PTF_REG,
|
||||
PTF_REG_S,
|
||||
PTF_INTEGER,
|
||||
PTF_REAL,
|
||||
PTF_REALTIME,
|
||||
PTF_TIME
|
||||
};
|
||||
|
||||
struct PTaskFuncArg {
|
||||
PTaskFuncEnum type;
|
||||
svector<PExpr*>*range;
|
||||
};
|
||||
|
||||
/*
|
||||
* The PTask holds the parsed definitions of a task.
|
||||
@@ -69,16 +86,18 @@ class PTask : public LineInfo {
|
||||
* The function is similar to a task (in this context) but there is a
|
||||
* single output port and a set of input ports. The output port is the
|
||||
* function return value.
|
||||
*
|
||||
* The output value is not elaborated until elaborate_sig.
|
||||
*/
|
||||
class PFunction : public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PFunction();
|
||||
explicit PFunction(perm_string name);
|
||||
~PFunction();
|
||||
|
||||
void set_ports(svector<PWire *>*p);
|
||||
void set_statement(Statement *s);
|
||||
void set_output(PWire*);
|
||||
void set_return(PTaskFuncArg t);
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -91,13 +110,22 @@ class PFunction : public LineInfo {
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
PWire*out_;
|
||||
perm_string name_;
|
||||
PTaskFuncArg return_type_;
|
||||
svector<PWire *> *ports_;
|
||||
Statement *statement_;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PTask.h,v $
|
||||
* Revision 1.14 2007/03/06 05:22:49 steve
|
||||
* Support signed function return values.
|
||||
*
|
||||
* Revision 1.13 2004/05/31 23:34:36 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.12 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2003-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,18 +17,35 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.cc,v 1.1 2003/07/15 05:07:13 steve Exp $"
|
||||
#ident "$Id: PUdp.cc,v 1.3 2004/03/08 00:47:44 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PUdp.h"
|
||||
|
||||
PUdp::PUdp(const string&n, unsigned nports)
|
||||
PUdp::PUdp(perm_string n, unsigned nports)
|
||||
: ports(nports), sequential(false), initial(verinum::Vx), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned PUdp::find_port(const char*name)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
|
||||
if (ports[idx] == name)
|
||||
return idx;
|
||||
}
|
||||
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PUdp.cc,v $
|
||||
* Revision 1.3 2004/03/08 00:47:44 steve
|
||||
* primitive ports can bind bi name.
|
||||
*
|
||||
* Revision 1.2 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.1 2003/07/15 05:07:13 steve
|
||||
* Move PUdp constructor into compiled file.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PUdp_H
|
||||
#define __PUdp_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,10 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.h,v 1.10 2003/07/15 05:07:13 steve Exp $"
|
||||
#ident "$Id: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <map>
|
||||
# include "StringHeap.h"
|
||||
# include "svector.h"
|
||||
# include "verinum.h"
|
||||
|
||||
@@ -52,9 +53,11 @@ class PExpr;
|
||||
class PUdp {
|
||||
|
||||
public:
|
||||
explicit PUdp(const string&n, unsigned nports);
|
||||
explicit PUdp(perm_string n, unsigned nports);
|
||||
|
||||
svector<string>ports;
|
||||
unsigned find_port(const char*name);
|
||||
|
||||
bool sequential;
|
||||
|
||||
svector<string>tinput;
|
||||
@@ -67,7 +70,7 @@ class PUdp {
|
||||
|
||||
void dump(ostream&out) const;
|
||||
|
||||
const string name_;
|
||||
perm_string name_;
|
||||
private:
|
||||
|
||||
private: // Not implemented
|
||||
@@ -77,6 +80,12 @@ class PUdp {
|
||||
|
||||
/*
|
||||
* $Log: PUdp.h,v $
|
||||
* Revision 1.12 2004/03/08 00:47:44 steve
|
||||
* primitive ports can bind bi name.
|
||||
*
|
||||
* Revision 1.11 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.10 2003/07/15 05:07:13 steve
|
||||
* Move PUdp constructor into compiled file.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2007 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
|
||||
@@ -17,26 +17,19 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PWire.cc,v 1.10 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: PWire.cc,v 1.14 2007/05/24 04:07:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
|
||||
: hname_(n), type_(t), port_type_(pt), signed_(false), 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),
|
||||
PWire::PWire(const pform_name_t&n,
|
||||
NetNet::Type t,
|
||||
NetNet::PortType pt,
|
||||
ivl_variable_type_t dt)
|
||||
: hname_(n), type_(t), port_type_(pt), data_type_(dt),
|
||||
signed_(false), isint_(false),
|
||||
lidx_(0), ridx_(0)
|
||||
{
|
||||
if (t == NetNet::INTEGER) {
|
||||
@@ -51,7 +44,7 @@ NetNet::Type PWire::get_wire_type() const
|
||||
return type_;
|
||||
}
|
||||
|
||||
const hname_t& PWire::path() const
|
||||
const pform_name_t& PWire::path() const
|
||||
{
|
||||
return hname_;
|
||||
}
|
||||
@@ -108,6 +101,19 @@ bool PWire::set_port_type(NetNet::PortType pt)
|
||||
}
|
||||
}
|
||||
|
||||
bool PWire::set_data_type(ivl_variable_type_t dt)
|
||||
{
|
||||
if (data_type_ != IVL_VT_NO_TYPE)
|
||||
if (data_type_ != dt)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
assert(data_type_ == IVL_VT_NO_TYPE);
|
||||
data_type_ = dt;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PWire::set_signed(bool flag)
|
||||
{
|
||||
signed_ = flag;
|
||||
@@ -133,13 +139,28 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||
{
|
||||
assert(lidx_ == 0);
|
||||
assert(ridx_ == 0);
|
||||
assert(type_ == NetNet::REG);
|
||||
lidx_ = ldx;
|
||||
ridx_ = rdx;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PWire.cc,v $
|
||||
* Revision 1.14 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.13 2007/04/26 03:06:21 steve
|
||||
* Rework hname_t to use perm_strings.
|
||||
*
|
||||
* Revision 1.12 2007/01/16 05:44:14 steve
|
||||
* Major rework of array handling. Memories are replaced with the
|
||||
* more general concept of arrays. The NetMemory and NetEMemory
|
||||
* classes are removed from the ivl core program, and the IVL_LPM_RAM
|
||||
* lpm type is removed from the ivl_target API.
|
||||
*
|
||||
* Revision 1.11 2005/07/07 16:22:49 steve
|
||||
* Generalize signals to carry types.
|
||||
*
|
||||
* Revision 1.10 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PWire_H
|
||||
#define __PWire_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2007 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,13 +19,14 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PWire.h,v 1.16 2003/01/30 16:23:07 steve Exp $"
|
||||
#ident "$Id: PWire.h,v 1.21 2007/05/24 04:07:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
# include "LineInfo.h"
|
||||
# include <map>
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
|
||||
#ifdef HAVE_IOSFWD
|
||||
# include <iosfwd>
|
||||
@@ -42,18 +43,21 @@ class Design;
|
||||
* 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.
|
||||
* is the name of the wire within a module, so does not include the
|
||||
* current scope or any instances. Modules contain all the wires, so
|
||||
* from that perspective, sub-scopes within the module are a part of
|
||||
* the wire name.
|
||||
*/
|
||||
class PWire : public LineInfo {
|
||||
|
||||
public:
|
||||
PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt);
|
||||
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
|
||||
PWire(const pform_name_t&hname,
|
||||
NetNet::Type t,
|
||||
NetNet::PortType pt,
|
||||
ivl_variable_type_t dt);
|
||||
|
||||
// Return a hierarchical name.
|
||||
const hname_t&path() const;
|
||||
const pform_name_t&path() const;
|
||||
|
||||
NetNet::Type get_wire_type() const;
|
||||
bool set_wire_type(NetNet::Type);
|
||||
@@ -65,21 +69,25 @@ class PWire : public LineInfo {
|
||||
bool get_signed() const;
|
||||
bool get_isint() const;
|
||||
|
||||
bool set_data_type(ivl_variable_type_t dt);
|
||||
ivl_variable_type_t get_data_type() const;
|
||||
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
// Write myself to the specified stream.
|
||||
void dump(ostream&out) const;
|
||||
void dump(ostream&out, unsigned ind=4) const;
|
||||
|
||||
void elaborate_sig(Design*, NetScope*scope) const;
|
||||
NetNet* elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
hname_t hname_;
|
||||
pform_name_t hname_;
|
||||
NetNet::Type type_;
|
||||
NetNet::PortType port_type_;
|
||||
ivl_variable_type_t data_type_;
|
||||
bool signed_;
|
||||
bool isint_; // original type of integer
|
||||
|
||||
@@ -100,6 +108,22 @@ class PWire : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PWire.h,v $
|
||||
* Revision 1.21 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.20 2007/04/26 03:06:22 steve
|
||||
* Rework hname_t to use perm_strings.
|
||||
*
|
||||
* Revision 1.19 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.18 2005/07/07 16:22:49 steve
|
||||
* Generalize signals to carry types.
|
||||
*
|
||||
* Revision 1.17 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.16 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
@@ -127,40 +151,5 @@ class PWire : public LineInfo {
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Revision 1.8 2000/05/02 16:27:38 steve
|
||||
* Move signal elaboration to a seperate pass.
|
||||
*
|
||||
* Revision 1.7 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.6 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
* Revision 1.5 1999/06/17 05:34:42 steve
|
||||
* Clean up interface of the PWire class,
|
||||
* Properly match wire ranges.
|
||||
*
|
||||
* Revision 1.4 1999/06/02 15:38:46 steve
|
||||
* Line information with nets.
|
||||
*
|
||||
* Revision 1.3 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.2 1998/11/23 00:20:22 steve
|
||||
* NetAssign handles lvalues as pin links
|
||||
* instead of a signal pointer,
|
||||
* Wire attributes added,
|
||||
* Ability to parse UDP descriptions added,
|
||||
* XNF generates EXT records for signals with
|
||||
* the PAD attribute.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:55 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@ execute even the most trivial design. For the purposes of simulation,
|
||||
we use as our example *the* most trivial simulation:
|
||||
|
||||
module main;
|
||||
|
||||
initial
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hello, World");
|
||||
$finish ;
|
||||
|
||||
+77
-65
@@ -1,5 +1,5 @@
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
September 17, 2000
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
Copyright 2000-2004 Stephen Williams
|
||||
|
||||
|
||||
1.0 What is ICARUS Verilog?
|
||||
@@ -9,7 +9,7 @@ described in the IEEE-1364 standard. Of course, it's not quite there
|
||||
yet. It does currently handle a mix of structural and behavioral
|
||||
constructs. For a view of the current state of Icarus Verilog, see its
|
||||
home page at <http://www.icarus.com/eda/verilog>.
|
||||
|
||||
|
||||
Icarus Verilog is not aimed at being a simulator in the traditional
|
||||
sense, but a compiler that generates code employed by back-end
|
||||
tools. These back-end tools currently include a simulator engine
|
||||
@@ -67,6 +67,14 @@ on a UNIX-like system:
|
||||
- termcap
|
||||
The readline library in turn uses termcap.
|
||||
|
||||
If you are building from CVS, you will also need software to generate
|
||||
the configure scripts.
|
||||
|
||||
- autoconf 2.53
|
||||
This generates configure scripts from configure.in. The 2.53
|
||||
or later versions are known to work, autoconf 2.13 is
|
||||
reported to *not* work.
|
||||
|
||||
2.2 Compilation
|
||||
|
||||
Unpack the tar-ball and cd into the verilog-######### directory
|
||||
@@ -94,6 +102,28 @@ configure script that modify its behavior:
|
||||
common to use --prefix=/opt. You can configure for a non-root
|
||||
install with --prefix=$HOME.
|
||||
|
||||
--enable-vvp32 (experimental)
|
||||
If compiling on AMD64 systems, this enables the
|
||||
compilation of 32bit compatible vvp (vvp32) and the vpi
|
||||
modules that match.
|
||||
|
||||
2.2.1 Special AMD64 Instructions
|
||||
|
||||
(The Icarus Verilog RPM for x86_64 is build using these instructions.)
|
||||
|
||||
If you are building for Linux/AMD64 (a.k.a x86_64) then to get the
|
||||
most out of your install, first make sure you have both 64bit and
|
||||
32bit development libraries installed. Then configure with this
|
||||
somewhat more complicated command:
|
||||
|
||||
./configure libdir64='$(prefix)/lib64' vpidir1=vpi64 vpidir2=. --enable-vvp32
|
||||
|
||||
This reflects the convention on AMD64 systems that 64bit libraries go
|
||||
into lib64 directories. The "--enable-vvp32" also turns on 32bit
|
||||
compatibility files. A 32bit version of vvp (vvp32) will be created,
|
||||
as well as 32bit versions of the development libraries and bundled VPI
|
||||
libraries.
|
||||
|
||||
2.3 (Optional) Testing
|
||||
|
||||
To run a simple test before installation, execute
|
||||
@@ -266,8 +296,8 @@ Example: Compiling "hello.vl"
|
||||
|
||||
------------------------ hello.vl ----------------------------
|
||||
module main();
|
||||
|
||||
initial
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hi there");
|
||||
$finish ;
|
||||
@@ -277,7 +307,7 @@ endmodule
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
Ensure 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:
|
||||
@@ -304,8 +334,8 @@ Verilog web page for the current state of support for Verilog, and in
|
||||
particular, browse the bug report database for reported unsupported
|
||||
constructs.
|
||||
|
||||
- System functions are supported, but the compiler presumes that
|
||||
they return 32 bits. This is the typical case.
|
||||
- System functions are supported, but the return value is a little
|
||||
tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page.
|
||||
|
||||
- Specify blocks are parsed but ignored in general.
|
||||
|
||||
@@ -314,9 +344,6 @@ constructs.
|
||||
- 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;"
|
||||
@@ -324,10 +351,6 @@ constructs.
|
||||
- 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.
|
||||
|
||||
@@ -336,7 +359,13 @@ constructs.
|
||||
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.
|
||||
language that are defined. See the "extensions.txt" documentation for
|
||||
more details.
|
||||
|
||||
$is_signed(<expr>)
|
||||
This system function returns 1 if the expression contained is
|
||||
signed, or 0 otherwise. This is mostly of use for compiler
|
||||
regression tests.
|
||||
|
||||
$sizeof(<expr>)
|
||||
$bits(<expr>)
|
||||
@@ -361,6 +390,14 @@ language that are defined.
|
||||
general possible to predict what the simulation precision will
|
||||
turn out to be.
|
||||
|
||||
$mti_random()
|
||||
$mti_dist_uniform
|
||||
These functions are similar to the IEEE1364 standard $random
|
||||
functions, but they use the Mersenne Twister (MT19937)
|
||||
algorithm. This is considered an excellent random number
|
||||
generator, but does not generate the same sequence as the
|
||||
standardized $random.
|
||||
|
||||
Builtin system functions
|
||||
|
||||
Certain of the system functions have well defined meanings, so
|
||||
@@ -423,6 +460,30 @@ language that are defined.
|
||||
where one wants to iterate over all the objects in a scope
|
||||
without iterating over all the contained types explicitly.
|
||||
|
||||
time 0 race resolution.
|
||||
|
||||
Combinational logic is routinely modeled using always
|
||||
blocks. However, this can lead to race conditions if the
|
||||
inputs to the combinational block are initialized in initial
|
||||
statements. Icarus Verilog slightly modifies time 0 scheduling
|
||||
by arranging for always statements with ANYEDGE sensitivity
|
||||
lists to be scheduled before any other threads. This causes
|
||||
combinational always blocks to be triggered when the values in
|
||||
the sensitivity list are initialized by initial threads.
|
||||
|
||||
Nets with Types
|
||||
|
||||
Icarus Verilog support an extension syntax that allows nets
|
||||
and regs to be explicitly typed. The currently supported types
|
||||
are logic, bool and real. This implies that "logic" and "bool"
|
||||
are new keywords. Typical syntax is:
|
||||
|
||||
wire real foo = 1.0;
|
||||
reg logic bar, bat;
|
||||
|
||||
... and so forth. The syntax can be turned off by using the
|
||||
-g2 flag to iverilog, and turned on explicitly with the -g2x
|
||||
flag to iverilog.
|
||||
|
||||
6.0 CREDITS
|
||||
|
||||
@@ -433,52 +494,3 @@ Verilog guidance, and especially testing from many people. Testers in
|
||||
particular include a larger community of people interested in a GPL
|
||||
Verilog for Linux.
|
||||
|
||||
|
||||
6.1 PORT MAINTAINERS
|
||||
|
||||
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
|
||||
removed from the list) send e-mail to me.
|
||||
|
||||
FreeBSD/{Intel,alpha}
|
||||
Ying-Chieh Liao <[email protected]>
|
||||
|
||||
Linux/{alpha,Intel} (RPMS)
|
||||
Stephen Williams <[email protected]>
|
||||
|
||||
Linux/* (.debs)
|
||||
Hamish Moffatt <[email protected]>
|
||||
|
||||
Macintosh -- MacO/S
|
||||
Yasuhisa Kato <[email protected]>
|
||||
|
||||
Mac O/S X
|
||||
Timothy J. Wood <[email protected]>
|
||||
|
||||
NetBSD/*
|
||||
Dan McMahill <[email protected]>
|
||||
|
||||
Solaris/SPARC packages (.pkg)
|
||||
Dan McMahill <[email protected]>
|
||||
|
||||
Cygwin32/*
|
||||
Venkat Iyer <[email protected]>
|
||||
|
||||
Mingw32
|
||||
Venkat Iyer <[email protected]>
|
||||
|
||||
(+) These are not the only systems where Icarus Verilog has been run,
|
||||
just the systems where precompiled binaries are publicly available.
|
||||
|
||||
|
||||
6.2 TEST SUITE MANAGER
|
||||
|
||||
Steve Wilson <[email protected]> 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.
|
||||
|
||||
|
||||
+19
-6
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.cc,v 1.28 2002/08/12 01:34:58 steve Exp $"
|
||||
#ident "$Id: Statement.cc,v 1.30 2007/05/24 04:07:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -86,7 +86,7 @@ PAssignNB::~PAssignNB()
|
||||
{
|
||||
}
|
||||
|
||||
PBlock::PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st)
|
||||
PBlock::PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st)
|
||||
: name_(n), bl_type_(t), list_(st)
|
||||
{
|
||||
}
|
||||
@@ -107,16 +107,22 @@ PBlock::~PBlock()
|
||||
delete list_[idx];
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
|
||||
PCallTask::PCallTask(const pform_name_t&n, const svector<PExpr*>&p)
|
||||
: path_(n), parms_(p)
|
||||
{
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(perm_string n, const svector<PExpr*>&p)
|
||||
: parms_(p)
|
||||
{
|
||||
path_.push_back(name_component_t(n));
|
||||
}
|
||||
|
||||
PCallTask::~PCallTask()
|
||||
{
|
||||
}
|
||||
|
||||
const hname_t& PCallTask::path() const
|
||||
const pform_name_t& PCallTask::path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
@@ -178,7 +184,7 @@ PDelayStatement::~PDelayStatement()
|
||||
{
|
||||
}
|
||||
|
||||
PDisable::PDisable(const hname_t&sc)
|
||||
PDisable::PDisable(const pform_name_t&sc)
|
||||
: scope_(sc)
|
||||
{
|
||||
}
|
||||
@@ -273,7 +279,7 @@ PRepeat::~PRepeat()
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PTrigger::PTrigger(const hname_t&e)
|
||||
PTrigger::PTrigger(const pform_name_t&e)
|
||||
: event_(e)
|
||||
{
|
||||
}
|
||||
@@ -295,6 +301,13 @@ PWhile::~PWhile()
|
||||
|
||||
/*
|
||||
* $Log: Statement.cc,v $
|
||||
* Revision 1.30 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.29 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.28 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
+39
-12
@@ -19,11 +19,12 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.h,v 1.38 2003/05/19 02:50:58 steve Exp $"
|
||||
#ident "$Id: Statement.h,v 1.44 2007/05/24 04:07:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
# include "HName.h"
|
||||
@@ -35,6 +36,7 @@ class Design;
|
||||
class NetAssign_;
|
||||
class NetCAssign;
|
||||
class NetDeassign;
|
||||
class NetForce;
|
||||
class NetScope;
|
||||
|
||||
/*
|
||||
@@ -53,10 +55,12 @@ class PProcess : public LineInfo {
|
||||
|
||||
virtual ~PProcess();
|
||||
|
||||
bool elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
Type type() const { return type_; }
|
||||
Statement*statement() { return statement_; }
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -148,7 +152,7 @@ class PBlock : public Statement {
|
||||
public:
|
||||
enum BL_TYPE { BL_SEQ, BL_PAR };
|
||||
|
||||
explicit PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(BL_TYPE t);
|
||||
~PBlock();
|
||||
@@ -161,7 +165,7 @@ class PBlock : public Statement {
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
perm_string name_;
|
||||
const BL_TYPE bl_type_;
|
||||
svector<Statement*>list_;
|
||||
};
|
||||
@@ -169,10 +173,11 @@ class PBlock : public Statement {
|
||||
class PCallTask : public Statement {
|
||||
|
||||
public:
|
||||
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
|
||||
explicit PCallTask(const pform_name_t&n, const svector<PExpr*>&parms);
|
||||
explicit PCallTask(perm_string n, const svector<PExpr*>&parms);
|
||||
~PCallTask();
|
||||
|
||||
const hname_t& path() const;
|
||||
const pform_name_t& path() const;
|
||||
|
||||
unsigned nparms() const { return parms_.count(); }
|
||||
|
||||
@@ -193,7 +198,7 @@ class PCallTask : public Statement {
|
||||
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
||||
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
|
||||
|
||||
hname_t path_;
|
||||
pform_name_t path_;
|
||||
svector<PExpr*> parms_;
|
||||
};
|
||||
|
||||
@@ -292,14 +297,14 @@ class PDelayStatement : public Statement {
|
||||
class PDisable : public Statement {
|
||||
|
||||
public:
|
||||
explicit PDisable(const hname_t&sc);
|
||||
explicit PDisable(const pform_name_t&sc);
|
||||
~PDisable();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
hname_t scope_;
|
||||
pform_name_t scope_;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -344,7 +349,7 @@ class PForce : public Statement {
|
||||
explicit PForce(PExpr*l, PExpr*r);
|
||||
~PForce();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual NetForce* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -392,6 +397,7 @@ class PNoop : public Statement {
|
||||
|
||||
public:
|
||||
PNoop() { }
|
||||
~PNoop() { }
|
||||
};
|
||||
|
||||
class PRepeat : public Statement {
|
||||
@@ -428,14 +434,14 @@ class PRelease : public Statement {
|
||||
class PTrigger : public Statement {
|
||||
|
||||
public:
|
||||
explicit PTrigger(const hname_t&ev);
|
||||
explicit PTrigger(const pform_name_t&ev);
|
||||
~PTrigger();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
hname_t event_;
|
||||
pform_name_t event_;
|
||||
};
|
||||
|
||||
class PWhile : public Statement {
|
||||
@@ -455,6 +461,27 @@ class PWhile : public Statement {
|
||||
|
||||
/*
|
||||
* $Log: Statement.h,v $
|
||||
* Revision 1.44 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.43 2007/03/05 05:59:10 steve
|
||||
* Handle processes within generate loops.
|
||||
*
|
||||
* Revision 1.42 2005/12/05 21:21:18 steve
|
||||
* Fixes for stubborn compilers.
|
||||
*
|
||||
* Revision 1.41 2004/12/11 02:31:25 steve
|
||||
* Rework of internals to carry vectors through nexus instead
|
||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
||||
* down this path.
|
||||
*
|
||||
* Revision 1.40 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.39 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.38 2003/05/19 02:50:58 steve
|
||||
* Implement the wait statement behaviorally instead of as nets.
|
||||
*
|
||||
|
||||
+63
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2003 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2002-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: StringHeap.cc,v 1.5 2003/03/01 06:25:30 steve Exp $"
|
||||
#ident "$Id: StringHeap.cc,v 1.6 2004/02/18 17:11:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "StringHeap.h"
|
||||
@@ -64,6 +64,11 @@ const char* StringHeap::add(const char*text)
|
||||
return res;
|
||||
}
|
||||
|
||||
perm_string StringHeap::make(const char*text)
|
||||
{
|
||||
return perm_string(add(text));
|
||||
}
|
||||
|
||||
|
||||
StringHeapLex::StringHeapLex()
|
||||
{
|
||||
@@ -121,8 +126,64 @@ const char* StringHeapLex::add(const char*text)
|
||||
return res;
|
||||
}
|
||||
|
||||
perm_string StringHeapLex::make(const char*text)
|
||||
{
|
||||
return perm_string(add(text));
|
||||
}
|
||||
|
||||
perm_string StringHeapLex::make(const string&text)
|
||||
{
|
||||
return perm_string(add(text.c_str()));
|
||||
}
|
||||
|
||||
bool operator == (perm_string a, const char*b)
|
||||
{
|
||||
if (a.str() == b)
|
||||
return true;
|
||||
|
||||
if (! (a.str() && b))
|
||||
return false;
|
||||
|
||||
if (strcmp(a.str(), b) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator == (perm_string a, perm_string b)
|
||||
{
|
||||
return a == b.str();
|
||||
}
|
||||
|
||||
bool operator != (perm_string a, const char*b)
|
||||
{
|
||||
return ! (a == b);
|
||||
}
|
||||
|
||||
bool operator != (perm_string a, perm_string b)
|
||||
{
|
||||
return ! (a == b);
|
||||
}
|
||||
|
||||
bool operator < (perm_string a, perm_string b)
|
||||
{
|
||||
if (b.str() && !a.str())
|
||||
return true;
|
||||
|
||||
if (b.str() == a.str())
|
||||
return false;
|
||||
|
||||
if (strcmp(a.str(), b.str()) < 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: StringHeap.cc,v $
|
||||
* Revision 1.6 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.5 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
|
||||
+52
-2
@@ -1,7 +1,7 @@
|
||||
#ifndef __StringHeap_H
|
||||
#define __StringHeap_H
|
||||
/*
|
||||
* Copyright (c) 2002-2003 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2002-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,9 +19,50 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: StringHeap.h,v 1.4 2003/03/01 06:25:30 steve Exp $"
|
||||
#ident "$Id: StringHeap.h,v 1.6 2005/06/14 19:13:43 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class perm_string {
|
||||
|
||||
public:
|
||||
perm_string() : text_(0) { }
|
||||
perm_string(const perm_string&that) : text_(that.text_) { }
|
||||
~perm_string() { }
|
||||
|
||||
perm_string& operator = (const perm_string&that)
|
||||
{ text_ = that.text_; return *this; }
|
||||
|
||||
const char*str() const { return text_; }
|
||||
operator const char* () const { return str(); }
|
||||
|
||||
// This is an escape for making perm_string objects out of
|
||||
// literals. For example, per_string::literal("Label"); Please
|
||||
// do *not* cheat and pass arbitrary const char* items here.
|
||||
static perm_string literal(const char*t) { return perm_string(t); }
|
||||
|
||||
private:
|
||||
friend class StringHeap;
|
||||
friend class StringHeapLex;
|
||||
perm_string(const char*t) : text_(t) { };
|
||||
|
||||
private:
|
||||
const char*text_;
|
||||
};
|
||||
|
||||
extern bool operator == (perm_string a, perm_string b);
|
||||
extern bool operator == (perm_string a, const char* b);
|
||||
extern bool operator != (perm_string a, perm_string b);
|
||||
extern bool operator != (perm_string a, const char* b);
|
||||
extern bool operator > (perm_string a, perm_string b);
|
||||
extern bool operator < (perm_string a, perm_string b);
|
||||
extern bool operator >= (perm_string a, perm_string b);
|
||||
extern bool operator <= (perm_string a, perm_string b);
|
||||
|
||||
/*
|
||||
* The string heap is a way to permanently allocate strings
|
||||
* efficiently. They only take up the space of the string characters
|
||||
@@ -34,6 +75,7 @@ class StringHeap {
|
||||
~StringHeap();
|
||||
|
||||
const char*add(const char*);
|
||||
perm_string make(const char*);
|
||||
|
||||
private:
|
||||
enum { HEAPCELL = 0x10000 };
|
||||
@@ -60,6 +102,8 @@ class StringHeapLex : private StringHeap {
|
||||
~StringHeapLex();
|
||||
|
||||
const char*add(const char*);
|
||||
perm_string make(const char*);
|
||||
perm_string make(const string&);
|
||||
|
||||
unsigned add_count() const;
|
||||
unsigned add_hit_count() const;
|
||||
@@ -78,6 +122,12 @@ class StringHeapLex : private StringHeap {
|
||||
|
||||
/*
|
||||
* $Log: StringHeap.h,v $
|
||||
* Revision 1.6 2005/06/14 19:13:43 steve
|
||||
* gcc3/4 compile errors.
|
||||
*
|
||||
* Revision 1.5 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.4 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
#ifndef PLI_TYPES
|
||||
#define PLI_TYPES
|
||||
/*
|
||||
* Copyright (c) 2003 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: _pli_types.h.in,v 1.8 2007/06/05 21:32:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
# undef HAVE_INTTYPES_H
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
|
||||
/*
|
||||
* If the host environment has the stdint.h header file,
|
||||
* then use that to size our PLI types.
|
||||
*/
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
# define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
|
||||
# include <inttypes.h>
|
||||
typedef uint64_t PLI_UINT64;
|
||||
typedef int64_t PLI_INT64;
|
||||
typedef uint32_t PLI_UINT32;
|
||||
typedef int32_t PLI_INT32;
|
||||
|
||||
typedef signed short PLI_INT16;
|
||||
typedef unsigned short PLI_UINT16;
|
||||
typedef char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
|
||||
# define PLI_UINT64_FMT PRIu64
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* If we do not have the c99 stdint.h header file, then use
|
||||
* configure detection to guess the pli types ourselves.
|
||||
*/
|
||||
|
||||
# define SIZEOF_UNSIGNED_LONG_LONG 8
|
||||
# define SIZEOF_UNSIGNED_LONG 8
|
||||
# define SIZEOF_UNSIGNED 4
|
||||
|
||||
#if SIZEOF_UNSIGNED >= 8
|
||||
typedef unsigned PLI_UINT64;
|
||||
typedef int PLI_INT64;
|
||||
# define PLI_UINT64_FMT "u"
|
||||
#else
|
||||
# if SIZEOF_UNSIGNED_LONG >= 8
|
||||
typedef unsigned long PLI_UINT64;
|
||||
typedef long PLI_INT64;
|
||||
# define PLI_UINT64_FMT "lu"
|
||||
# else
|
||||
# if SIZEOF_UNSIGNED_LONG_LONG > SIZEOF_UNSIGNED_LONG
|
||||
typedef unsigned long long PLI_UINT64;
|
||||
typedef long long PLI_INT64;
|
||||
# define PLI_UINT64_FMT "llu"
|
||||
# else
|
||||
typedef unsigned long PLI_UINT64;
|
||||
typedef long PLI_INT64;
|
||||
# define PLI_UINT64_FMT "lu"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef signed int PLI_INT32;
|
||||
typedef unsigned int PLI_UINT32;
|
||||
typedef signed short PLI_INT16;
|
||||
typedef unsigned short PLI_UINT16;
|
||||
typedef char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* $Log: _pli_types.h.in,v $
|
||||
* Revision 1.8 2007/06/05 21:32:30 steve
|
||||
* More standard PLI_BYTE8.
|
||||
*
|
||||
* Revision 1.7 2003/11/12 02:38:44 steve
|
||||
* Clean up manual definitions of PLI_UINT64_FMT.
|
||||
*
|
||||
* Revision 1.6 2003/11/08 20:06:21 steve
|
||||
* Spelling fixes in comments.
|
||||
*
|
||||
* Revision 1.5 2003/10/29 03:28:27 steve
|
||||
* Add the PLU_UINT64_FMT string for formatting output.
|
||||
*
|
||||
* Revision 1.4 2003/10/29 03:23:12 steve
|
||||
* Portably handle time format of VCD prints.
|
||||
*
|
||||
* Revision 1.3 2003/10/02 21:30:06 steve
|
||||
* Use configured TIME_FMT in vcd dump printf.
|
||||
*
|
||||
* Revision 1.2 2003/10/02 19:33:44 steve
|
||||
* Put libraries in libdir64.
|
||||
*
|
||||
* Revision 1.1 2003/09/30 01:33:13 steve
|
||||
* Add PLI_UINT64 to _pli_types.h.
|
||||
*
|
||||
* Revision 1.2 2003/05/26 04:39:16 steve
|
||||
* Typo type name.
|
||||
*
|
||||
* Revision 1.1 2003/02/17 06:39:47 steve
|
||||
* Add at least minimal implementations for several
|
||||
* acc_ functions. Add support for standard ACC
|
||||
* string handling.
|
||||
*
|
||||
* Add the _pli_types.h header file to carry the
|
||||
* IEEE1364-2001 standard PLI type declarations.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+18
-1
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: acc_user.h,v 1.18 2003/06/13 19:23:41 steve Exp $"
|
||||
#ident "$Id: acc_user.h,v 1.20 2003/12/17 15:45:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -195,11 +195,16 @@ extern void acc_close(void);
|
||||
* codes that are accepted.
|
||||
*/
|
||||
extern int acc_configure(PLI_INT32 config_param, const char*value);
|
||||
#define accEnableArgs 6
|
||||
#define accDevelopmentVersion 11
|
||||
|
||||
extern int acc_fetch_argc(void);
|
||||
extern char**acc_fetch_argv(void);
|
||||
|
||||
extern PLI_INT32 acc_fetch_direction(handle obj);
|
||||
/* XXXX FIXME: Values returned by acc_fetch_direction */
|
||||
# define accInout 2
|
||||
|
||||
extern char* acc_fetch_fullname(handle obj);
|
||||
|
||||
extern int acc_fetch_location(p_location loc, handle obj);
|
||||
@@ -232,9 +237,11 @@ extern char* acc_fetch_type_str(PLI_INT32 type);
|
||||
extern char* acc_fetch_value(handle obj, const char*fmt, s_acc_value*value);
|
||||
|
||||
extern handle acc_handle_by_name(const char*name, handle scope);
|
||||
extern handle acc_handle_hiconn(handle port_ref_handle);
|
||||
extern handle acc_handle_object(const char*name);
|
||||
extern handle acc_handle_parent(handle obj);
|
||||
extern handle acc_handle_scope(handle obj);
|
||||
extern handle acc_handle_simulated_net(handle net);
|
||||
|
||||
extern handle acc_handle_tfarg(int n);
|
||||
extern handle acc_handle_tfinst(void);
|
||||
@@ -242,6 +249,8 @@ extern handle acc_handle_tfinst(void);
|
||||
extern PLI_INT32 acc_compare_handles(handle, handle);
|
||||
|
||||
extern handle acc_next(PLI_INT32 *, handle, handle);
|
||||
extern handle acc_next_bit(handle ref, handle bit);
|
||||
extern handle acc_next_port(handle ref, handle bit);
|
||||
extern handle acc_next_scope(handle, handle);
|
||||
extern handle acc_next_topmod(handle prev_topmod);
|
||||
|
||||
@@ -250,6 +259,8 @@ extern int acc_object_of_type(handle object, PLI_INT32 type);
|
||||
|
||||
extern char*acc_product_version(void);
|
||||
|
||||
extern char*acc_set_scope(handle ref, ...);
|
||||
|
||||
extern int acc_set_value(handle obj, p_setval_value value,
|
||||
p_setval_delay delay);
|
||||
|
||||
@@ -264,6 +275,12 @@ EXTERN_C_END
|
||||
|
||||
/*
|
||||
* $Log: acc_user.h,v $
|
||||
* Revision 1.20 2003/12/17 15:45:07 steve
|
||||
* Add acc_set_scope function.
|
||||
*
|
||||
* Revision 1.19 2003/10/10 02:57:45 steve
|
||||
* Some PLI1 stubs.
|
||||
*
|
||||
* Revision 1.18 2003/06/13 19:23:41 steve
|
||||
* Add a bunch more PLI1 routines.
|
||||
*
|
||||
|
||||
Vendored
+207
@@ -0,0 +1,207 @@
|
||||
# AX_CPP_IDENT
|
||||
# ------------
|
||||
# Check if the C compiler supports #ident
|
||||
# Define and substitute ident_support if so.
|
||||
#
|
||||
# It would be simpler and more consistent with the rest of the autoconf
|
||||
# structure to AC_DEFINE(HAVE_CPP_IDENT) instead of
|
||||
# ident_support='-DHAVE_CVS_IDENT=1' and AC_SUBST(ident_support), but that
|
||||
# change would require all C files in the icarus top level directory to
|
||||
# put #include <config.h> before the #ifdef HAVE_CVS_IDENT (and change
|
||||
# HAVE_CVS_IDENT to HAVE_CPP_IDENT). That would also remove all special
|
||||
# ident_support handling from the Makefile. Manyana.
|
||||
#
|
||||
AC_DEFUN([AX_CPP_IDENT],
|
||||
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
|
||||
[AC_TRY_COMPILE([
|
||||
#ident "$Id: aclocal.m4,v 1.7 2007/05/16 23:59:12 steve Exp $"
|
||||
],[while (0) {}],
|
||||
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
|
||||
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
|
||||
if test $ax_cv_cpp_ident = yes; then
|
||||
ident_support='-DHAVE_CVS_IDENT=1'
|
||||
fi
|
||||
AC_SUBST(ident_support)
|
||||
])# AC_CPP_IDENT
|
||||
|
||||
|
||||
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
|
||||
# ------------------------------
|
||||
# Sub-macro for AX_C_UNDERSCORES_LEADING and AX_C_UNDERSCORES_TRAILING.
|
||||
# Unwarranted assumptions:
|
||||
# - the object file produced by AC_COMPILE_IFELSE is called "conftest.$ac_objext"
|
||||
# - the nm(1) utility is available, and its name is "nm".
|
||||
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF],
|
||||
[AC_COMPILE_IFELSE([void underscore(void){}],
|
||||
[AS_IF([nm conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
|
||||
[AC_MSG_ERROR([underscore test crashed])]
|
||||
)])
|
||||
|
||||
|
||||
# AX_C_UNDERSCORES_LEADING
|
||||
# ---------------------------------
|
||||
# Check if symbol names in object files produced by C compiler have
|
||||
# leading underscores. Define NEED_LU if so.
|
||||
AC_DEFUN([AX_C_UNDERSCORES_LEADING],
|
||||
[AC_CACHE_CHECK([for leading underscores], ax_cv_c_underscores_leading,
|
||||
[_AX_C_UNDERSCORES_MATCH_IF([_underscore],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
|
||||
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
|
||||
AC_DEFINE([NEED_LU], [1], [Symbol names in object files produced by C compiler have leading underscores.])
|
||||
fi
|
||||
])# AX_C_UNDERSCORES_LEADING
|
||||
|
||||
|
||||
# AX_C_UNDERSCORES_TRAILING
|
||||
# ---------------------------------
|
||||
# Check if symbol names in object files produced by C compiler have
|
||||
# trailing underscores. Define NEED_TU if so.
|
||||
AC_DEFUN([AX_C_UNDERSCORES_TRAILING],
|
||||
[AC_CACHE_CHECK([for trailing underscores], ax_cv_c_underscores_trailing,
|
||||
[_AX_C_UNDERSCORES_MATCH_IF([underscore_],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_trailing, yes)],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_trailing, no)])])
|
||||
if test $ax_cv_c_underscores_trailing = yes; then
|
||||
AC_DEFINE([NEED_TU], [1], [Symbol names in object files produced by C compiler have trailing underscores.])
|
||||
fi
|
||||
])# AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
# AX_WIN32
|
||||
# --------
|
||||
# Combined check for several flavors of Microsoft Windows so
|
||||
# their "issues" can be dealt with
|
||||
AC_DEFUN([AX_WIN32],
|
||||
[AC_CYGWIN
|
||||
AC_MINGW32
|
||||
WIN32=no
|
||||
AC_MSG_CHECKING([for Microsoft Windows])
|
||||
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
|
||||
then
|
||||
WIN32=yes
|
||||
fi
|
||||
AC_SUBST(MINGW32)
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
])# AX_WIN32
|
||||
|
||||
# AX_LD_EXTRALIBS
|
||||
# ---------------
|
||||
# mingw needs to link with libiberty.a, but cygwin alone can't tolerate it
|
||||
AC_DEFUN([AX_LD_EXTRALIBS],
|
||||
[AC_MSG_CHECKING([for extra libs needed])
|
||||
EXTRALIBS=
|
||||
case "${host}" in
|
||||
*-*-cygwin* )
|
||||
if test "$MINGW32" = "yes"; then
|
||||
EXTRALIBS="-liberty"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXTRALIBS)
|
||||
AC_MSG_RESULT($EXTRALIBS)
|
||||
])# AX_LD_EXTRALIBS
|
||||
|
||||
# AX_LD_SHAREDLIB_OPTS
|
||||
# --------------------
|
||||
# linker options when building a shared library
|
||||
AC_DEFUN([AX_LD_SHAREDLIB_OPTS],
|
||||
[AC_MSG_CHECKING([for shared library link flag])
|
||||
shared=-shared
|
||||
case "${host}" in
|
||||
*-*-cygwin*)
|
||||
shared="-shared -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
shared="-b"
|
||||
;;
|
||||
|
||||
*-*-darwin1.[0123])
|
||||
shared="-bundle -undefined suppress"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
shared="-bundle -undefined suppress -flat_namespace"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(shared)
|
||||
AC_MSG_RESULT($shared)
|
||||
])# AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
# AX_C_PICFLAG
|
||||
# ------------
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
AC_DEFUN([AX_C_PICFLAG],
|
||||
[AC_MSG_CHECKING([for flag to make position independent code])
|
||||
PICFLAG=-fPIC
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
PICFLAG=
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
PICFLAG=+z
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(PICFLAG)
|
||||
AC_MSG_RESULT($PICFLAG)
|
||||
])# AX_C_PICFLAG
|
||||
|
||||
# AX_LD_RDYNAMIC
|
||||
# --------------
|
||||
# The -rdynamic flag is used by iverilog when compiling the target,
|
||||
# to know how to export symbols of the main program to loadable modules
|
||||
# that are brought in by -ldl
|
||||
AC_DEFUN([AX_LD_RDYNAMIC],
|
||||
[AC_MSG_CHECKING([for -rdynamic compiler flag])
|
||||
rdynamic=-rdynamic
|
||||
case "${host}" in
|
||||
|
||||
*-*-netbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-openbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-cygwin*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
rdynamic="-Wl,-all_load"
|
||||
strip_dynamic="-SX"
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(rdynamic)
|
||||
AC_MSG_RESULT($rdynamic)
|
||||
AC_SUBST(strip_dynamic)
|
||||
# since we didn't tell them we're "checking", no good place to tell the answer
|
||||
# AC_MSG_RESULT($strip_dynamic)
|
||||
])# AX_LD_RDYNAMIC
|
||||
|
||||
# AX_CPP_PRECOMP
|
||||
# --------------
|
||||
AC_DEFUN([AX_CPP_PRECOMP],
|
||||
[# Darwin requires -no-cpp-precomp
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
|
||||
CFLAGS="-no-cpp-precomp $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
])# AX_CPP_PRECOMP
|
||||
@@ -17,7 +17,7 @@
|
||||
* 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 $"
|
||||
#ident "$Id: async.cc,v 1.7 2004/01/18 23:26:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -36,11 +36,22 @@ bool NetCondit::is_asynchronous()
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* NetEvWait statements come from statements of the form @(...) in the
|
||||
* Verilog source. These event waits are considered asynchronous if
|
||||
* all of the events in the list are ANYEDGE, and all the inputs to
|
||||
* the statement are included in the sensitivity list. If any of the
|
||||
* events are posedge or negedge, the statement is synchronous
|
||||
* (i.e. an edge-triggered flip-flop) and if any of the inputs are
|
||||
* unaccounted for in the sensitivity list then the statement is a
|
||||
* latch.
|
||||
*/
|
||||
bool NetEvWait::is_asynchronous()
|
||||
{
|
||||
/* The "sense" set contains the set of Nexa that are in the
|
||||
sensitivity list. We also presume here that the list is
|
||||
only LEVEL sensitive. */
|
||||
sensitivity list. We also require that the events are all
|
||||
level sensitive, but the nex_async_ method takes care of
|
||||
that test. */
|
||||
NexusSet*sense = new NexusSet;
|
||||
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
|
||||
NexusSet*tmp = event(idx)->nex_async_();
|
||||
@@ -63,6 +74,9 @@ bool NetEvWait::is_asynchronous()
|
||||
|
||||
delete sense;
|
||||
delete inputs;
|
||||
|
||||
/* If it passes all the other tests, then this statement is
|
||||
asynchronous. */
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,6 +95,15 @@ bool NetProcTop::is_asynchronous()
|
||||
|
||||
/*
|
||||
* $Log: async.cc,v $
|
||||
* Revision 1.7 2004/01/18 23:26:54 steve
|
||||
* The is_combinational function really need not recurse.
|
||||
*
|
||||
* Revision 1.6 2003/12/20 00:33:39 steve
|
||||
* More thorough check that NetEvWait is asynchronous.
|
||||
*
|
||||
* Revision 1.5 2003/09/04 20:28:05 steve
|
||||
* Support time0 resolution of combinational threads.
|
||||
*
|
||||
* Revision 1.4 2002/08/18 22:07:16 steve
|
||||
* Detect temporaries in sequential block synthesis.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
|
||||
ATTRIBUTE NAMING CONVENTIONS
|
||||
|
||||
Attributes that are specific to Icarus Verilog, and are intended to be
|
||||
of use to programmers, start with the prefix "ivl_".
|
||||
|
||||
Attributes with the "_ivl_" prefix are set aside for internal
|
||||
use. They may be generated internally by the compiler. They need not
|
||||
be documented here.
|
||||
|
||||
ATTRIBUTES TO CONTROL SYNTHESIS
|
||||
|
||||
The following is a summary of Verilog attributes that Icarus Verilog
|
||||
@@ -62,3 +71,15 @@ warning.)
|
||||
* Other Attributes
|
||||
|
||||
[ none defined yet ]
|
||||
|
||||
|
||||
MISC
|
||||
|
||||
(* _ivl_schedule_push *)
|
||||
|
||||
If this attribute is attached to a thread object (always or
|
||||
initial statement) then the vvp code generator will generate code
|
||||
that causes the scheduler to push this thread at compile time. The
|
||||
compiler may internally add this attribute to always statements if
|
||||
it detects that it is combinational. This helps resolve time-0
|
||||
races.
|
||||
|
||||
+3
-3
@@ -7,12 +7,12 @@
|
||||
# to just run this script to autoconf wherever needed.
|
||||
#
|
||||
echo "Autoconf in root..."
|
||||
autoconf
|
||||
autoconf -f
|
||||
|
||||
for dir in vpip vvp tgt-vvp tgt-fpga libveriuser cadpli
|
||||
for dir in vpip vpi vvp tgt-vvp tgt-fpga tgt-stub libveriuser cadpli
|
||||
do
|
||||
echo "Autoconf in $dir..."
|
||||
( cd ./$dir ; autoconf )
|
||||
( cd ./$dir ; autoconf -f --include=.. )
|
||||
done
|
||||
|
||||
echo "Precompiling lexor_keyword.gperf"
|
||||
|
||||
+35
-20
@@ -16,7 +16,7 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.4 2003/02/27 22:13:22 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.13 2007/02/06 05:07:31 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
@@ -33,20 +33,30 @@ bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = $(prefix)/include
|
||||
|
||||
strip_dynamic=@strip_dynamic@
|
||||
vpidir = @libdir@/ivl/@vpidir1@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
STRIP = @STRIP@
|
||||
|
||||
all: dep cadpli.vpl
|
||||
SHARED = @shared@
|
||||
|
||||
all:
|
||||
|
||||
ifeq (@enable_vvp32@,yes)
|
||||
vpidir32 = $(libdir)/ivl/@vpidir2@
|
||||
ALL32 = all32
|
||||
INSTALL32 = install32
|
||||
UNINSTALL32 = uninstall32
|
||||
include $(srcdir)/enable_vvp32.mk
|
||||
endif
|
||||
|
||||
all: dep cadpli.vpl $(ALL32)
|
||||
|
||||
# No specific check operations.
|
||||
check: all
|
||||
@@ -55,35 +65,40 @@ dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -Wall -I$(srcdir) -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $<
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $<
|
||||
mv $*.d dep
|
||||
|
||||
O = cadpli.o
|
||||
|
||||
SYSTEM_VPI_LDFLAGS = @whole_archive@ ../libveriuser/libveriuser.a @no_whole_archive@ -L../vvp -lvpi
|
||||
ifeq (@WIN32@,yes)
|
||||
SYSTEM_VPI_LDFLAGS += -liberty
|
||||
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
|
||||
ifeq (@MING32@,yes)
|
||||
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
|
||||
endif
|
||||
|
||||
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.a
|
||||
$(CC) @shared@ -o $@ $O $(SYSTEM_VPI_LDFLAGS)
|
||||
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
|
||||
$(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -rf *.o dep cadpli.vpl
|
||||
rm -rf *.o dep cadpli.vpl bin32
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.status config.log config.cache
|
||||
|
||||
install: all installdirs $(libdir)/ivl/cadpli.vpl
|
||||
install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32)
|
||||
|
||||
$(libdir)/ivl/cadpli.vpl: ./cadpli.vpl
|
||||
$(INSTALL_PROGRAM) ./cadpli.vpl $(libdir)/ivl/cadpli.vpl
|
||||
$(vpidir)/cadpli.vpl: ./cadpli.vpl
|
||||
$(INSTALL_PROGRAM) ./cadpli.vpl $(vpidir)/cadpli.vpl
|
||||
|
||||
installdirs: ../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs $(libdir)/ivl
|
||||
$(srcdir)/../mkinstalldirs $(vpidir)
|
||||
|
||||
uninstall:
|
||||
rm -f $(libdir)/ivl/cadpli.vpl
|
||||
uninstall: $(UNINSTALL32)
|
||||
rm -f $(vpidir)/cadpli.vpl
|
||||
|
||||
uninstall32:
|
||||
|
||||
ifeq (@enable_vvp32@,yes)
|
||||
include $(srcdir)/enable_vvp32.mk
|
||||
endif
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
|
||||
+13
-2
@@ -16,7 +16,9 @@
|
||||
* 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: cadpli.c,v 1.4 2003/04/30 01:28:06 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cadpli.c,v 1.7 2004/09/10 00:15:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <vpi_user.h>
|
||||
# include <veriuser.h>
|
||||
@@ -35,7 +37,7 @@ static void thunker_register(void)
|
||||
struct t_vpi_vlog_info vlog_info;
|
||||
void*mod;
|
||||
void*boot;
|
||||
void*tf;
|
||||
struct t_tfcell*tf;
|
||||
int idx;
|
||||
|
||||
vpi_get_vlog_info(&vlog_info);
|
||||
@@ -89,6 +91,15 @@ void (*vlog_startup_routines[])() = {
|
||||
|
||||
/*
|
||||
* $Log: cadpli.c,v $
|
||||
* Revision 1.7 2004/09/10 00:15:45 steve
|
||||
* Remove bad casts.
|
||||
*
|
||||
* Revision 1.6 2004/09/05 21:19:51 steve
|
||||
* Better type safety.
|
||||
*
|
||||
* Revision 1.5 2003/08/26 16:26:02 steve
|
||||
* ifdef idents correctly.
|
||||
*
|
||||
* Revision 1.4 2003/04/30 01:28:06 steve
|
||||
* Remove veriusertfs stuf.
|
||||
*
|
||||
|
||||
+27
-173
@@ -4,13 +4,18 @@ AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_MINGW32
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||
AX_WIN32
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# vvp32 is by default disabled
|
||||
#enable_vvp32=no
|
||||
AC_SUBST(enable_vvp32)
|
||||
|
||||
AC_CHECK_HEADERS(malloc.h)
|
||||
|
||||
AC_CHECK_SIZEOF(unsigned long long)
|
||||
@@ -30,193 +35,42 @@ AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
|
||||
fi
|
||||
AC_SUBST(DLLIB)
|
||||
|
||||
AX_CPP_PRECOMP
|
||||
|
||||
# Darwin requires -no-cpp-precomp
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
|
||||
CFLAGS="-no-cpp-precomp $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
# Compiler option for position independent code, needed when making shared objects.
|
||||
AX_C_PICFLAG
|
||||
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
# Linker option used when compiling the target
|
||||
AX_LD_RDYNAMIC
|
||||
|
||||
AC_MSG_CHECKING("for flag to make position independent code")
|
||||
PICFLAG=-fPIC
|
||||
case "${host}" in
|
||||
# linker options when building a shared library
|
||||
AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
*-*-cygwin*)
|
||||
PICFLAG=
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
PICFLAG=+z
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(PICFLAG)
|
||||
AC_MSG_RESULT($PICFLAG)
|
||||
|
||||
# The -rdynamic flag is used by iverilog when compiling the target,
|
||||
# to know how to export symbols of the main program to loadable modules
|
||||
# that are brought in by -ldl. VPI support requires this.
|
||||
AC_MSG_CHECKING("for -rdynamic compiler flag")
|
||||
|
||||
rdynamic=-rdynamic
|
||||
whole_archive=-Wl,-whole-archive
|
||||
no_whole_archive=-Wl,-no-whole-archive
|
||||
case "${host}" in
|
||||
|
||||
*-*-netbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-openbsd*)
|
||||
whole_archive=""
|
||||
no_whole_archive=""
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-cygwin*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
rdynamic="-Wl,-all_load"
|
||||
whole_archive=""
|
||||
no_whole_archive=""
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(rdynamic)
|
||||
AC_SUBST(whole_archive)
|
||||
AC_SUBST(no_whole_archive)
|
||||
AC_MSG_RESULT($rdynamic)
|
||||
|
||||
AC_MSG_CHECKING("for -whole-archive compiler flags")
|
||||
AC_MSG_RESULT($whole_archive $no_whole_archive)
|
||||
|
||||
AC_MSG_CHECKING("for shared library link flag")
|
||||
shared=-shared
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
shared="-shared -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
shared="-b"
|
||||
;;
|
||||
|
||||
*-*-darwin1.[0123])
|
||||
shared="-bundle -undefined suppress"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
shared="-bundle -undefined suppress -flat_namespace"
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(shared)
|
||||
AC_MSG_RESULT($shared)
|
||||
|
||||
AC_MSG_CHECKING("for extra libs needed")
|
||||
EXTRALIBS=
|
||||
case "${host}" in
|
||||
*-*-cygwin*)
|
||||
EXTRALIBS="-liberty"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXTRALIBS)
|
||||
AC_MSG_RESULT($EXTRALIBS)
|
||||
AX_LD_EXTRALIBS
|
||||
|
||||
#######################
|
||||
## test for underscores. The vpi module loader in vvm needs to know this
|
||||
## in order to know the name of the start symbol for the .vpi module.
|
||||
#######################
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_MINGW32
|
||||
|
||||
|
||||
WIN32=no
|
||||
AC_MSG_CHECKING("Checking for windows")
|
||||
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
|
||||
then
|
||||
WIN32=yes
|
||||
fi
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
|
||||
AC_MSG_CHECKING("for leading and/or trailing underscores")
|
||||
cat << EOF > underscore.c
|
||||
void underscore(void){}
|
||||
EOF
|
||||
$CC -shared -c underscore.c > /dev/null 2>&1
|
||||
|
||||
CC_LEADING_UNDERSCORE=no
|
||||
CC_TRAILING_UNDERSCORE=no
|
||||
|
||||
output=`nm underscore.o|grep _underscore 2>&1`
|
||||
if test ! -z "$output" -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
|
||||
CC_LEADING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_LU)
|
||||
fi
|
||||
|
||||
|
||||
|
||||
output=`nm underscore.o|grep underscore_ 2>&1`
|
||||
if test ! -z "$output"; then
|
||||
CC_TRAILING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_TU)
|
||||
fi
|
||||
|
||||
if test "$CC_LEADING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WLU)
|
||||
fi
|
||||
if test "$CC_TRAILING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WTU)
|
||||
fi
|
||||
|
||||
rm underscore.c underscore.o
|
||||
|
||||
AC_MSG_RESULT("$CC_LEADING_UNDERSCORE $CC_TRAILING_UNDERSCORE")
|
||||
AX_C_UNDERSCORES_LEADING
|
||||
AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
AX_CPP_IDENT
|
||||
|
||||
# where to put vpi subdirectories
|
||||
AC_MSG_CHECKING(for VPI subdirectories)
|
||||
if test x${vpidir1} = x
|
||||
then
|
||||
vpidir1="."
|
||||
fi
|
||||
|
||||
AC_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_SUBST(vpidir1)
|
||||
AC_SUBST(vpidir2)
|
||||
AC_MSG_RESULT(${vpidir1} ${vpidir2})
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# This source code is free software; you can redistribute it
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: enable_vvp32.mk,v 1.1 2003/10/09 01:07:20 steve Exp $"
|
||||
#
|
||||
|
||||
all32: bin32 bin32/cadpli.vpl
|
||||
|
||||
bin32:
|
||||
mkdir bin32
|
||||
|
||||
bin32/%.o: %.c
|
||||
$(CC) -m32 -Wall -I$(srcdir) -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $@
|
||||
|
||||
bin32/cadpli.vpl: $(addprefix bin32/,$O) ../vvp/bin32/libvpi.a ../libveriuser/bin32/libveriuser.o
|
||||
$(CC) $(SHARED) -m32 -o $@ $(addprefix bin32/,$O) ../libveriuser/bin32/libveriuser.o ../vvp/bin32/libvpi.a
|
||||
|
||||
install32: all32 $(vpidir32)/cadpli.vpl
|
||||
|
||||
$(vpidir32)/cadpli.vpl: bin32/cadpli.vpl
|
||||
$(INSTALL_PROGRAM) bin32/cadpli.vpl $(vpidir32)/cadpli.vpl
|
||||
|
||||
uninstall32:
|
||||
rm -f $(vpidir32)/cadpli.vpl
|
||||
+16
-4
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.1 2003/02/17 00:01:25 steve Exp $"
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.3 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
@@ -48,14 +48,14 @@ inline const char *dlerror(void)
|
||||
{
|
||||
static char msg[256];
|
||||
unsigned long err = GetLastError();
|
||||
FormatMessage(
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &msg,
|
||||
sizeof(msg) - 1,
|
||||
NULL
|
||||
NULL
|
||||
);
|
||||
return msg;
|
||||
}
|
||||
@@ -65,7 +65,13 @@ inline ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return dlopen(name,RTLD_LAZY); }
|
||||
|
||||
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{ return dlsym(dll, nm); }
|
||||
{
|
||||
void*sym = dlsym(dll, nm);
|
||||
/* Not found? try without the leading _ */
|
||||
if (sym == 0 && nm[0] == '_')
|
||||
sym = dlsym(dll, nm+1);
|
||||
return sym;
|
||||
}
|
||||
|
||||
inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ dlclose(dll); }
|
||||
@@ -90,6 +96,12 @@ inline const char*dlerror(void)
|
||||
|
||||
/*
|
||||
* $Log: ivl_dlfcn.h,v $
|
||||
* Revision 1.3 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.2 2003/12/12 05:43:08 steve
|
||||
* Some systems dlsym requires leading _ or not on whim.
|
||||
*
|
||||
* Revision 1.1 2003/02/17 00:01:25 steve
|
||||
* Use a variant of ivl_dlfcn to do dynamic loading
|
||||
* from within the cadpli module.
|
||||
|
||||
+4
-9
@@ -1,9 +1,4 @@
|
||||
|
||||
# The make check target uses this to check the compilation of the
|
||||
# compiler.
|
||||
|
||||
[-tvvm-check]
|
||||
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o.cc -- -
|
||||
|
||||
[-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 -- -
|
||||
functor:cprop
|
||||
functor:nodangle
|
||||
-t:dll
|
||||
flag:DLL=tgt-vvp/vvp.tgt
|
||||
|
||||
+115
-41
@@ -1,7 +1,7 @@
|
||||
#ifndef __compiler_H
|
||||
#define __compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2004 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,10 +19,12 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: compiler.h,v 1.16 2003/03/01 06:25:30 steve Exp $"
|
||||
#ident "$Id: compiler.h,v 1.33 2007/04/19 02:52:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "netlist.h"
|
||||
# include "StringHeap.h"
|
||||
|
||||
/*
|
||||
@@ -30,11 +32,8 @@
|
||||
*/
|
||||
|
||||
|
||||
/* The INTEGER_WIDTH is the default width of integer variables, and
|
||||
the presumed width of unsigned literal numbers. */
|
||||
#ifndef INTEGER_WIDTH
|
||||
# define INTEGER_WIDTH 32
|
||||
#endif
|
||||
/* The integer_width is the width of integer variables. */
|
||||
extern unsigned integer_width;
|
||||
|
||||
/* The TIME_WIDTH is the width of time variables. */
|
||||
#ifndef TIME_WIDTH
|
||||
@@ -62,8 +61,8 @@
|
||||
|
||||
/*
|
||||
* These are flags to enable various sorts of warnings. By default all
|
||||
* the warnings are of, the -W<list> parameter arranges for each to be
|
||||
* enabled.
|
||||
* the warnings are off, the -W<list> parameter arranges for each to be
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
/* Implicit definitions of wires. */
|
||||
@@ -79,63 +78,138 @@ extern bool warn_portbinding;
|
||||
/* This is true if verbose output is requested. */
|
||||
extern bool verbose_flag;
|
||||
|
||||
extern bool debug_scopes;
|
||||
extern bool debug_eval_tree;
|
||||
extern bool debug_elaborate;
|
||||
extern bool debug_synth2;
|
||||
|
||||
/* Path to a directory useful for finding subcomponents. */
|
||||
extern const char*basedir;
|
||||
|
||||
/* This is an ordered list of library suffixes to search. */
|
||||
extern list<const char*>library_suff;
|
||||
extern int build_library_index(const char*path, bool key_case_sensitive);
|
||||
|
||||
/* This is the generation of Verilog that the compiler is asked to
|
||||
support. */
|
||||
support. Then there are also more detailed controls for more
|
||||
specific language features. */
|
||||
enum generation_t {
|
||||
GN_VER1995 = 1,
|
||||
GN_VER2001 = 2,
|
||||
GN_SYSVER30 = 3,
|
||||
GN_VER2001X = 3,
|
||||
GN_DEFAULT = 3
|
||||
};
|
||||
|
||||
extern generation_t generation_flag;
|
||||
|
||||
extern bool gn_cadence_types_flag;
|
||||
|
||||
/* These functions test that specific features are enabled. */
|
||||
inline bool gn_cadence_types_enabled()
|
||||
{ return gn_cadence_types_flag && generation_flag==GN_VER2001X; }
|
||||
|
||||
/* If this flag is true, then elaborate specify blocks. If this flag
|
||||
is false, then skip elaboration of specify behavior. */
|
||||
extern bool gn_specify_blocks_flag;
|
||||
|
||||
/* This is the string to use to invoke the preprocessor. */
|
||||
extern char*ivlpp_string;
|
||||
|
||||
extern map<perm_string,unsigned> missing_modules;
|
||||
|
||||
/* Files that are library files are in this map. The lexor compares
|
||||
file names as it processes `line directives, and if the file name
|
||||
matches an entry in this table, it will turn on the
|
||||
library_active_flag so that modules know that they are in a
|
||||
library. */
|
||||
extern map<string,bool> library_file_map;
|
||||
|
||||
/*
|
||||
* the lex_strings are perm_strings made up of tokens from the source
|
||||
* file. Identifiers are so likely to be used many times that it makes
|
||||
* much sense to use a StringHeapLex to hold them.
|
||||
*/
|
||||
extern StringHeapLex lex_strings;
|
||||
extern StringHeap misc_strings;
|
||||
|
||||
/*
|
||||
* system task/function listings.
|
||||
*/
|
||||
/*
|
||||
* This table describes all the return values of various system
|
||||
* functions. This table is used to elaborate expressions that are
|
||||
* system function calls.
|
||||
*/
|
||||
struct sfunc_return_type {
|
||||
const char* name;
|
||||
ivl_variable_type_t type;
|
||||
unsigned wid;
|
||||
int signed_flag;
|
||||
};
|
||||
|
||||
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
|
||||
extern int load_sys_func_table(const char*path);
|
||||
|
||||
/*
|
||||
* $Log: compiler.h,v $
|
||||
* Revision 1.33 2007/04/19 02:52:53 steve
|
||||
* Add support for -v flag in command file.
|
||||
*
|
||||
* Revision 1.32 2007/03/07 04:24:59 steve
|
||||
* Make integer width controllable.
|
||||
*
|
||||
* Revision 1.31 2006/09/28 04:35:18 steve
|
||||
* Support selective control of specify and xtypes features.
|
||||
*
|
||||
* Revision 1.30 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
* Revision 1.29 2005/07/07 16:22:49 steve
|
||||
* Generalize signals to carry types.
|
||||
*
|
||||
* Revision 1.28 2005/06/28 04:25:55 steve
|
||||
* Remove reference to SystemVerilog.
|
||||
*
|
||||
* Revision 1.27 2005/04/24 23:44:01 steve
|
||||
* Update DFF support to new data flow.
|
||||
*
|
||||
* Revision 1.26 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.25 2004/09/25 01:58:44 steve
|
||||
* Add a debug_elaborate flag
|
||||
*
|
||||
* Revision 1.24 2004/09/10 23:51:42 steve
|
||||
* Fix the evaluation of constant ternary expressions.
|
||||
*
|
||||
* Revision 1.23 2004/09/05 17:44:41 steve
|
||||
* Add support for module instance arrays.
|
||||
*
|
||||
* Revision 1.22 2004/03/10 04:51:24 steve
|
||||
* Add support for system function table files.
|
||||
*
|
||||
* Revision 1.21 2004/03/09 04:29:42 steve
|
||||
* Separate out the lookup_sys_func table, for eventual
|
||||
* support for function type tables.
|
||||
*
|
||||
* Remove ipal compile flags.
|
||||
*
|
||||
* Revision 1.20 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.19 2003/11/13 05:55:33 steve
|
||||
* Move the DLL= flag to target config files.
|
||||
*
|
||||
* Revision 1.18 2003/11/08 20:06:21 steve
|
||||
* Spelling fixes in comments.
|
||||
*
|
||||
* Revision 1.17 2003/09/25 00:25:14 steve
|
||||
* Summary list of missing modules.
|
||||
*
|
||||
* Revision 1.16 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*
|
||||
* Revision 1.15 2003/02/22 04:12:49 steve
|
||||
* Add the portbind warning.
|
||||
*
|
||||
* Revision 1.14 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.13 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.12 2002/05/28 20:40:37 steve
|
||||
* ivl indexes the search path for libraries, and
|
||||
* supports case insensitive module-to-file lookup.
|
||||
*
|
||||
* Revision 1.11 2002/05/28 00:50:39 steve
|
||||
* Add the ivl -C flag for bulk configuration
|
||||
* from the driver, and use that to run library
|
||||
* modules through the preprocessor.
|
||||
*
|
||||
* Revision 1.10 2002/05/24 01:13:00 steve
|
||||
* Support language generation flag -g.
|
||||
*
|
||||
* Revision 1.9 2002/04/22 00:53:39 steve
|
||||
* Do not allow implicit wires in sensitivity lists.
|
||||
*
|
||||
* Revision 1.8 2002/04/15 00:04:22 steve
|
||||
* Timescale warnings.
|
||||
*
|
||||
* Revision 1.7 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
*/
|
||||
#endif
|
||||
|
||||
+17
-3
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: config.h.in,v 1.9 2003/07/03 16:29:55 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: config.h.in,v 1.12 2007/02/02 04:33:00 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@@ -31,12 +31,13 @@
|
||||
#endif
|
||||
|
||||
# undef NEED_LU
|
||||
# undef NEED_TU
|
||||
# undef NEED_TU
|
||||
# undef WLU
|
||||
# undef WTU
|
||||
# undef HAVE_TIMES
|
||||
# undef HAVE_IOSFWD
|
||||
# undef HAVE_GETOPT_H
|
||||
# undef HAVE_INTTYPES_H
|
||||
# undef HAVE_LIBIBERTY_H
|
||||
# undef HAVE_MALLOC_H
|
||||
# undef HAVE_DLFCN_H
|
||||
@@ -48,8 +49,21 @@
|
||||
# undef HAVE_SYS_WAIT_H
|
||||
# undef WORDS_BIGENDIAN
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* $Log: config.h.in,v $
|
||||
* Revision 1.12 2007/02/02 04:33:00 steve
|
||||
* Use inttypes.h instead of stdint.h for portability.
|
||||
*
|
||||
* Revision 1.11 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.10 2003/08/26 16:26:01 steve
|
||||
* ifdef idents correctly.
|
||||
*
|
||||
* Revision 1.9 2003/07/03 16:29:55 steve
|
||||
* spemm WORDS_BIGENDIAN correctly.
|
||||
*
|
||||
|
||||
+54
-174
@@ -1,7 +1,9 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(netlist.h)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADER(_pli_types.h)
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
@@ -9,9 +11,13 @@ AC_CHECK_TOOL(STRIP, strip, true)
|
||||
AC_CHECK_PROGS(XGPERF,gperf,none)
|
||||
if test "$XGPERF" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable gperf found. ***"
|
||||
echo " Please install the 'gperf' package."
|
||||
exit 1
|
||||
echo ""
|
||||
echo "*** Warning: No suitable gperf found. ***"
|
||||
echo " The gperf package is essential for building ivl from"
|
||||
echo " CVS sources, or modifying the parse engine of ivl itself."
|
||||
echo " You can get away without it when simply building from"
|
||||
echo " snapshots or major releases."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(LEX,flex,none)
|
||||
@@ -30,28 +36,24 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_MINGW32
|
||||
|
||||
WIN32=no
|
||||
AC_MSG_CHECKING("Checking for windows")
|
||||
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
|
||||
then
|
||||
WIN32=yes
|
||||
fi
|
||||
|
||||
AC_SUBST(MINGW32)
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||
AX_WIN32
|
||||
|
||||
# vvp32 is by default disabled
|
||||
#enable_vvp32=no
|
||||
AC_SUBST(enable_vvp32)
|
||||
|
||||
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
AC_CHECK_HEADERS(getopt.h malloc.h libiberty.h iosfwd sys/wait.h)
|
||||
AC_CHECK_HEADERS(getopt.h malloc.h inttypes.h libiberty.h iosfwd sys/wait.h)
|
||||
|
||||
AC_CHECK_LIB(z, gzwrite)
|
||||
AC_CHECK_LIB(z, gzwrite, HAVE_LIBZ=yes, HAVE_LIBZ=no)
|
||||
AC_SUBST(HAVE_LIBZ)
|
||||
if test "$WIN32" = "yes"; then
|
||||
AC_CHECK_LIB(bz2, main)
|
||||
else
|
||||
@@ -64,21 +66,11 @@ AC_TRY_LINK(
|
||||
#include <sys/times.h>
|
||||
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
|
||||
do_times=yes
|
||||
AC_DEFINE(HAVE_TIMES,1),
|
||||
AC_DEFINE([HAVE_TIMES], [1], [The times system call is available in the host operating system.]),
|
||||
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)
|
||||
|
||||
# --
|
||||
# Look for a dl library to use. First look for the standard dlopen
|
||||
# functions, and failing that look for the HP specific shl_load function.
|
||||
@@ -97,171 +89,59 @@ AC_PROG_INSTALL
|
||||
AC_LANG_C
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
# $host
|
||||
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
AX_LD_EXTRALIBS
|
||||
|
||||
AC_MSG_CHECKING("for flag to make position independent code")
|
||||
PICFLAG=-fPIC
|
||||
case "${host}" in
|
||||
# Compiler option for position independent code, needed when making shared objects.
|
||||
# CFLAGS inherited by cadpli/Makefile?
|
||||
AX_C_PICFLAG
|
||||
|
||||
*-*-cygwin*)
|
||||
PICFLAG=
|
||||
;;
|
||||
# may modify CPPFLAGS and CFLAGS
|
||||
AX_CPP_PRECOMP
|
||||
|
||||
*-*-hpux*)
|
||||
PICFLAG=+z
|
||||
;;
|
||||
# Linker option used when compiling the target
|
||||
AX_LD_RDYNAMIC
|
||||
|
||||
esac
|
||||
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 $CPPFLAGS"
|
||||
CFLAGS="-no-cpp-precomp $CFLAGS"
|
||||
;;
|
||||
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
|
||||
AC_MSG_CHECKING("for -rdynamic compiler flag")
|
||||
|
||||
rdynamic=-rdynamic
|
||||
case "${host}" in
|
||||
|
||||
*-*-netbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-cygwin*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
rdynamic="-Wl,-all_load"
|
||||
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="-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)
|
||||
# linker options when building a shared library
|
||||
AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
#######################
|
||||
## 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_MSG_CHECKING("for leading and/or trailing underscores")
|
||||
cat << EOF > underscore.c
|
||||
void underscore(void){}
|
||||
EOF
|
||||
|
||||
$CC $shared -c underscore.c > /dev/null 2>&1
|
||||
|
||||
CC_LEADING_UNDERSCORE=no
|
||||
CC_TRAILING_UNDERSCORE=no
|
||||
|
||||
output=`nm underscore.o|grep _underscore 2>&1`
|
||||
if test ! -z "$output" -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
|
||||
CC_LEADING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_LU)
|
||||
fi
|
||||
|
||||
output=`nm underscore.o|grep underscore_ 2>&1`
|
||||
if test ! -z "$output"; then
|
||||
CC_TRAILING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_TU)
|
||||
fi
|
||||
|
||||
if test "$CC_LEADING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WLU)
|
||||
fi
|
||||
if test "$CC_TRAILING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WTU)
|
||||
fi
|
||||
|
||||
rm underscore.c underscore.o
|
||||
|
||||
AC_MSG_RESULT("$CC_LEADING_UNDERSCORE $CC_TRAILING_UNDERSCORE")
|
||||
AX_C_UNDERSCORES_LEADING
|
||||
AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
AC_MSG_CHECKING("for ident support in C compiler")
|
||||
ident_support='-DHAVE_CVS_IDENT=1'
|
||||
case "${host}" in
|
||||
AX_CPP_IDENT
|
||||
|
||||
*-*-cygwin*)
|
||||
ident_support=
|
||||
;;
|
||||
# If not otherwise specified, set the libdir64 variable
|
||||
# to the same as libdir.
|
||||
AC_MSG_CHECKING(for libdir64 path)
|
||||
if test x${libdir64} = x
|
||||
then
|
||||
libdir64="${libdir}"
|
||||
fi
|
||||
AC_SUBST(libdir64)
|
||||
AC_MSG_RESULT(${libdir64})
|
||||
|
||||
*-*-darwin*)
|
||||
ident_support=
|
||||
;;
|
||||
# where to put vpi subdirectories
|
||||
AC_MSG_CHECKING(for VPI subdirectories)
|
||||
if test x${vpidir1} = x
|
||||
then
|
||||
vpidir1="."
|
||||
fi
|
||||
|
||||
*-*-machten*)
|
||||
ident_support=
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(vpidir1)
|
||||
AC_SUBST(vpidir2)
|
||||
AC_MSG_RESULT(${vpidir1} ${vpidir2})
|
||||
|
||||
AC_SUBST(ident_support)
|
||||
AC_MSG_RESULT($ident_support)
|
||||
# XXX disable tgt-fpga for the moment
|
||||
AC_CONFIG_SUBDIRS(vvp vpi tgt-stub tgt-null tgt-vvp libveriuser cadpli)
|
||||
|
||||
|
||||
AC_CONFIG_SUBDIRS(vvp tgt-vvp tgt-fpga libveriuser cadpli)
|
||||
|
||||
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2005 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
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cprop.cc,v 1.44 2003/04/25 05:06:32 steve Exp $"
|
||||
#ident "$Id: cprop.cc,v 1.56 2007/03/07 00:38:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -55,86 +55,6 @@ 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") != verinum("ADD"))
|
||||
return;
|
||||
|
||||
// If the low bit on the A side is 0, then eliminate it from
|
||||
// the adder, and pass the B side directly to the
|
||||
// result. Don't reduce the adder smaller then a 1-bit
|
||||
// adder. These will be eliminated later.
|
||||
while ((obj->width() > 1)
|
||||
&& obj->pin_DataA(0).nexus()->drivers_constant()
|
||||
&& (obj->pin_DataA(0).nexus()->driven_value() == verinum::V0)) {
|
||||
|
||||
NetAddSub*tmp = 0;
|
||||
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
|
||||
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
|
||||
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
|
||||
//connect(tmp->pin_Clock(), obj->pin_Clock());
|
||||
//connect(tmp->pin_Cin(), obj->pin_Cin());
|
||||
connect(tmp->pin_Cout(), obj->pin_Cout());
|
||||
//connect(tmp->pin_Overflow(), obj->pin_Overflow());
|
||||
for (unsigned idx = 0 ; idx < tmp->width() ; idx += 1) {
|
||||
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx+1));
|
||||
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx+1));
|
||||
connect(tmp->pin_Result(idx), obj->pin_Result(idx+1));
|
||||
}
|
||||
connect(obj->pin_Result(0), obj->pin_DataB(0));
|
||||
delete obj;
|
||||
des->add_node(tmp);
|
||||
obj = tmp;
|
||||
count += 1;
|
||||
}
|
||||
|
||||
// Now do the same thing on the B side.
|
||||
while ((obj->width() > 1)
|
||||
&& obj->pin_DataB(0).nexus()->drivers_constant()
|
||||
&& (obj->pin_DataB(0).nexus()->driven_value() == verinum::V0)) {
|
||||
|
||||
NetAddSub*tmp = 0;
|
||||
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
|
||||
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
|
||||
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
|
||||
//connect(tmp->pin_Clock(), obj->pin_Clock());
|
||||
//connect(tmp->pin_Cin(), obj->pin_Cin());
|
||||
connect(tmp->pin_Cout(), obj->pin_Cout());
|
||||
//connect(tmp->pin_Overflow(), obj->pin_Overflow());
|
||||
for (unsigned idx = 0 ; idx < tmp->width() ; idx += 1) {
|
||||
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx+1));
|
||||
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx+1));
|
||||
connect(tmp->pin_Result(idx), obj->pin_Result(idx+1));
|
||||
}
|
||||
connect(obj->pin_Result(0), obj->pin_DataA(0));
|
||||
delete obj;
|
||||
des->add_node(tmp);
|
||||
obj = tmp;
|
||||
count += 1;
|
||||
}
|
||||
|
||||
// If the adder is only 1 bit wide, then replace it with the
|
||||
// simple logic gate.
|
||||
if (obj->width() == 1) {
|
||||
NetLogic*tmp;
|
||||
if (obj->pin_Cout().is_linked()) {
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
obj->scope()->local_symbol(),
|
||||
3, NetLogic::AND);
|
||||
connect(tmp->pin(0), obj->pin_Cout());
|
||||
connect(tmp->pin(1), obj->pin_DataA(0));
|
||||
connect(tmp->pin(2), obj->pin_DataB(0));
|
||||
des->add_node(tmp);
|
||||
}
|
||||
tmp = new NetLogic(obj->scope(), obj->name(), 3, NetLogic::XOR);
|
||||
connect(tmp->pin(0), obj->pin_Result(0));
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
|
||||
@@ -153,6 +73,8 @@ void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
|
||||
|
||||
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
{
|
||||
#if 0
|
||||
/* XXXX Need to reimplement this code to account for vectors. */
|
||||
NetScope*scope = obj->scope();
|
||||
|
||||
unsigned const_count = 0;
|
||||
@@ -248,7 +170,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
with a simple XOR gate. */
|
||||
if (top == 1) {
|
||||
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
|
||||
NetLogic::XNOR);
|
||||
NetLogic::XNOR, 1);
|
||||
connect(tmp->pin(0), obj->pin_AEB());
|
||||
connect(tmp->pin(1), obj->pin_DataA(0));
|
||||
connect(tmp->pin(2), obj->pin_DataB(0));
|
||||
@@ -271,66 +193,38 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
delete obj;
|
||||
des->add_node(tmp);
|
||||
count += 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_ff(Design*des, NetFF*obj)
|
||||
{
|
||||
// Look for and count unlinked FF outputs. Note that if the
|
||||
// Data and Q pins are connected together, they can be removed
|
||||
// from the circuit.
|
||||
unsigned unlinked_count = 0;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (connected(obj->pin_Data(idx), obj->pin_Q(idx))) {
|
||||
obj->pin_Data(idx).unlink();
|
||||
obj->pin_Q(idx).unlink();
|
||||
}
|
||||
if (! obj->pin_Q(idx).is_linked())
|
||||
unlinked_count += 1;
|
||||
}
|
||||
// from the circuit, since it doesn't do anything.
|
||||
|
||||
// If the entire FF is unlinked, remove the whole thing.
|
||||
if (unlinked_count == obj->width()) {
|
||||
if (connected(obj->pin_Data(), obj->pin_Q())
|
||||
&& (! obj->pin_Sclr().is_linked())
|
||||
&& (! obj->pin_Sset().is_linked())
|
||||
&& (! obj->pin_Aclr().is_linked())
|
||||
&& (! obj->pin_Aset().is_linked())) {
|
||||
obj->pin_Data().unlink();
|
||||
obj->pin_Q().unlink();
|
||||
delete obj;
|
||||
count += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// If some of the FFs are unconnected, make a new FF array
|
||||
// that does not include the useless FF devices.
|
||||
if (unlinked_count > 0) {
|
||||
NetFF*tmp = new NetFF(obj->scope(), obj->name(),
|
||||
obj->width()-unlinked_count);
|
||||
connect(tmp->pin_Clock(), obj->pin_Clock());
|
||||
connect(tmp->pin_Enable(), obj->pin_Enable());
|
||||
connect(tmp->pin_Aload(), obj->pin_Aload());
|
||||
connect(tmp->pin_Aset(), obj->pin_Aset());
|
||||
connect(tmp->pin_Aclr(), obj->pin_Aclr());
|
||||
connect(tmp->pin_Sload(), obj->pin_Sload());
|
||||
connect(tmp->pin_Sset(), obj->pin_Sset());
|
||||
connect(tmp->pin_Sclr(), obj->pin_Sclr());
|
||||
|
||||
unsigned tidx = 0;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1)
|
||||
if (obj->pin_Q(idx).is_linked()) {
|
||||
connect(tmp->pin_Data(tidx), obj->pin_Data(idx));
|
||||
connect(tmp->pin_Q(tidx), obj->pin_Q(idx));
|
||||
tidx += 1;
|
||||
}
|
||||
|
||||
assert(tidx == obj->width() - unlinked_count);
|
||||
delete obj;
|
||||
des->add_node(tmp);
|
||||
count += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
{
|
||||
#if 0
|
||||
NetScope*scope = obj->scope();
|
||||
#endif
|
||||
|
||||
switch (obj->type()) {
|
||||
|
||||
#if 0
|
||||
/* XXXX This old code assumed that the individual bit
|
||||
slices could be replaced with different gates. They
|
||||
cannot when the device takes atomic vectors, so this
|
||||
needs to be rewritten. XXXX */
|
||||
case NetLogic::NAND:
|
||||
case NetLogic::AND: {
|
||||
unsigned top = obj->pin_count();
|
||||
@@ -445,12 +339,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
case NetLogic::AND:
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
NetLogic::BUF, 1);
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
NetLogic::NOT, 1);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
@@ -476,7 +370,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
obj->type(), 1);
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
@@ -493,7 +387,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
#if 0
|
||||
/* XXXX This old code assumed that the individual bit
|
||||
slices could be replaced with different gates. They
|
||||
cannot when the device takes atomic vectors, so this
|
||||
needs to be rewritten. XXXX */
|
||||
|
||||
case NetLogic::NOR:
|
||||
case NetLogic::OR: {
|
||||
@@ -593,12 +492,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
case NetLogic::OR:
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
NetLogic::BUF, 1);
|
||||
break;
|
||||
case NetLogic::NOR:
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
NetLogic::NOT, 1);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
@@ -615,7 +514,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
delete obj;
|
||||
count += 1;
|
||||
return;
|
||||
}
|
||||
v }
|
||||
|
||||
/* Finally, this cleans up the gate by creating a
|
||||
new [N]OR gate that has the right number of
|
||||
@@ -623,7 +522,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
obj->type(), 1);
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
@@ -640,7 +539,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
#if 0
|
||||
/* XXXX This old code assumed that the individual bit
|
||||
slices could be replaced with different gates. They
|
||||
cannot when the device takes atomic vectors, so this
|
||||
needs to be rewritten. XXXX */
|
||||
case NetLogic::XNOR:
|
||||
case NetLogic::XOR: {
|
||||
unsigned top = obj->pin_count();
|
||||
@@ -762,11 +666,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
if (obj->type() == NetLogic::XOR)
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
NetLogic::NOT, 1);
|
||||
else
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
NetLogic::BUF, 1);
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
@@ -791,11 +695,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
if (obj->type() == NetLogic::XOR)
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
NetLogic::BUF, 1);
|
||||
else
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
NetLogic::NOT, 1);
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
@@ -817,7 +721,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
obj->type(), 1);
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -830,12 +734,54 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_with_bufif(Design*des, NetMux*obj, NetLogic::TYPE type)
|
||||
{
|
||||
NetScope*scope = obj->scope();
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
scope->local_symbol(),
|
||||
3, type, obj->width());
|
||||
|
||||
des->add_node(tmp);
|
||||
|
||||
connect(obj->pin_Result(), tmp->pin(0));
|
||||
connect(obj->pin_Data(type==NetLogic::BUFIF0? 0 : 1), tmp->pin(1));
|
||||
|
||||
if (obj->width() == 1) {
|
||||
/* Special case that the expression is 1 bit
|
||||
wide. Connect the select directly to the enable. */
|
||||
connect(obj->pin_Sel(), tmp->pin(2));
|
||||
|
||||
} else {
|
||||
/* General case that the expression is arbitrarily
|
||||
wide. Replicate the enable signal (which we
|
||||
assume is 1 bit wide) to match the expression,
|
||||
and connect the enable vector to the enable
|
||||
input of the gate. */
|
||||
NetReplicate*rtmp = new NetReplicate(scope,
|
||||
scope->local_symbol(),
|
||||
obj->width(),
|
||||
obj->width());
|
||||
des->add_node(rtmp);
|
||||
|
||||
connect(obj->pin_Sel(), rtmp->pin(1));
|
||||
connect(tmp->pin(2), rtmp->pin(0));
|
||||
|
||||
NetNet*rsig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, obj->width());
|
||||
rsig->local_flag(true);
|
||||
rsig->data_type(IVL_VT_LOGIC);
|
||||
connect(tmp->pin(2), rsig->pin(0));
|
||||
}
|
||||
|
||||
delete obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* This detects the case where the mux selects between a value and
|
||||
* Vz. In this case, replace the device with a bufif with the sel
|
||||
@@ -852,66 +798,36 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
NetMux with an array of BUFIF1 devices, with the enable
|
||||
connected to the select input. */
|
||||
bool flag = true;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (! obj->pin_Data(idx, 0).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj->pin_Data(idx, 0).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
if (! obj->pin_Data(0).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag && obj->pin_Data(0).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
NetScope*scope = obj->scope();
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
scope->local_symbol(),
|
||||
3, NetLogic::BUFIF1);
|
||||
|
||||
connect(obj->pin_Result(idx), tmp->pin(0));
|
||||
connect(obj->pin_Data(idx,1), tmp->pin(1));
|
||||
connect(obj->pin_Sel(0), tmp->pin(2));
|
||||
des->add_node(tmp);
|
||||
}
|
||||
|
||||
replace_with_bufif(des, obj, NetLogic::BUFIF1);
|
||||
count += 1;
|
||||
delete obj;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* If instead the second input is all constant Vz, replace the
|
||||
NetMux with an array of BUFIF0 devices. */
|
||||
flag = true;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (! obj->pin_Data(idx, 1).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
if (! obj->pin_Data(1).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (obj->pin_Data(idx, 1).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
if (flag && obj->pin_Data(1).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
NetScope*scope = obj->scope();
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
scope->local_symbol(),
|
||||
3, NetLogic::BUFIF0);
|
||||
|
||||
connect(obj->pin_Result(idx), tmp->pin(0));
|
||||
connect(obj->pin_Data(idx,0), tmp->pin(1));
|
||||
connect(obj->pin_Sel(0), tmp->pin(2));
|
||||
des->add_node(tmp);
|
||||
}
|
||||
|
||||
replace_with_bufif(des, obj, NetLogic::BUFIF0);
|
||||
count += 1;
|
||||
delete obj;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -990,6 +906,13 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
|
||||
assert(tmp->scope());
|
||||
|
||||
// If the net is a signal name from the source,
|
||||
// then users will probably want to see it in the
|
||||
// waveform dump, so unhooking the constant will
|
||||
// make it look wrong.
|
||||
if (! tmp->local_flag())
|
||||
return;
|
||||
|
||||
// If the net has an eref, then there is an
|
||||
// expression somewhere that reads this signal. So
|
||||
// the constant does get read.
|
||||
@@ -1027,6 +950,46 @@ void cprop(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: cprop.cc,v $
|
||||
* Revision 1.56 2007/03/07 00:38:15 steve
|
||||
* Lint fixes.
|
||||
*
|
||||
* Revision 1.55 2006/05/24 04:32:57 steve
|
||||
* Fix handling of ternary-to-bufif0 constant propagation.
|
||||
*
|
||||
* Revision 1.54 2005/07/15 19:22:52 steve
|
||||
* bufif enable is LOGIC.
|
||||
*
|
||||
* Revision 1.53 2005/05/15 04:44:30 steve
|
||||
* Disable obsolete logic constant fixup code.
|
||||
*
|
||||
* Revision 1.52 2005/04/24 23:44:01 steve
|
||||
* Update DFF support to new data flow.
|
||||
*
|
||||
* Revision 1.51 2005/02/12 22:52:45 steve
|
||||
* Fix copyright notice.
|
||||
*
|
||||
* Revision 1.50 2005/02/12 06:25:40 steve
|
||||
* Restructure NetMux devices to pass vectors.
|
||||
* Generate NetMux devices from ternary expressions,
|
||||
* Reduce NetMux devices to bufif when appropriate.
|
||||
*
|
||||
* Revision 1.49 2005/01/16 04:20:32 steve
|
||||
* Implement LPM_COMPARE nodes as two-input vector functors.
|
||||
*
|
||||
* Revision 1.48 2004/12/11 02:31:25 steve
|
||||
* Rework of internals to carry vectors through nexus instead
|
||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
||||
* down this path.
|
||||
*
|
||||
* Revision 1.47 2004/02/20 18:53:34 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.46 2003/11/08 17:53:34 steve
|
||||
* Do not remove constants accessible to VPI.
|
||||
*
|
||||
* Revision 1.45 2003/10/31 02:40:06 steve
|
||||
* Donot elide FF that has set or clr connections.
|
||||
*
|
||||
* Revision 1.44 2003/04/25 05:06:32 steve
|
||||
* Handle X values in constant == nets.
|
||||
*
|
||||
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
|
||||
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Note: Icarus Verilog also compiles to native Windows binaries if you
|
||||
use the instructions in the mingw.txt file. Some people prefer cygwin
|
||||
binaries, and these instructions apply.
|
||||
|
||||
|
||||
To build using cygwin:
|
||||
|
||||
Prerequisites:
|
||||
|
||||
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
|
||||
|
||||
Procedure:
|
||||
o Get the source code - see the main Icarus Verilog page for how to
|
||||
do this
|
||||
o cd to the verilog directory
|
||||
o autoconf.sh
|
||||
o ./configure
|
||||
o make
|
||||
o make install
|
||||
|
||||
That's all that's needed.
|
||||
|
||||
To build your own extensions - just include vpi_user.h and link with
|
||||
a command like this:
|
||||
|
||||
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
|
||||
|
||||
- Venkat Iyer <[email protected]>
|
||||
|
||||
|
||||
|
||||
|
||||
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Note: Icarus Verilog also compiles to native Windows binaries if you
|
||||
use the instructions in the mingw.txt file. Some people prefer cygwin
|
||||
binaries, and these instructions apply.
|
||||
|
||||
|
||||
To build using cygwin:
|
||||
|
||||
Prerequisites:
|
||||
|
||||
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
|
||||
|
||||
Procedure:
|
||||
o Get the source code - see the main Icarus Verilog page for how to
|
||||
do this
|
||||
o cd to the verilog directory
|
||||
o autoconf.sh
|
||||
o ./configure
|
||||
o make
|
||||
o make install
|
||||
|
||||
That's all that's needed.
|
||||
|
||||
To build your own extensions - just include vpi_user.h and link with
|
||||
a command like this:
|
||||
|
||||
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
|
||||
|
||||
- Venkat Iyer <[email protected]>
|
||||
|
||||
|
||||
|
||||
|
||||
+402
-134
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: design_dump.cc,v 1.144 2003/07/26 03:34:42 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.176 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -29,7 +29,8 @@
|
||||
# include <iostream>
|
||||
# include <iomanip>
|
||||
# include "netlist.h"
|
||||
|
||||
# include "compiler.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
static ostream& operator<< (ostream&o, NetBlock::Type t)
|
||||
{
|
||||
@@ -68,13 +69,77 @@ ostream& operator << (ostream&o, Link::strength_t str)
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& operator << (ostream&o, ivl_variable_type_t val)
|
||||
{
|
||||
switch (val) {
|
||||
case IVL_VT_VOID:
|
||||
o << "void";
|
||||
break;
|
||||
case IVL_VT_NO_TYPE:
|
||||
o << "<no_type>";
|
||||
break;
|
||||
case IVL_VT_REAL:
|
||||
o << "real";
|
||||
break;
|
||||
case IVL_VT_BOOL:
|
||||
o << "bool";
|
||||
break;
|
||||
case IVL_VT_LOGIC:
|
||||
o << "logic";
|
||||
break;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
static inline void dump_scope_path(ostream&o, const NetScope*scope)
|
||||
{
|
||||
if (const NetScope*parent = scope->parent()) {
|
||||
dump_scope_path(o, parent);
|
||||
o << ".";
|
||||
}
|
||||
const hname_t name = scope->fullname();
|
||||
o << name.peek_name();
|
||||
if (name.has_number())
|
||||
o << "[" << name.peek_number() << "]";
|
||||
}
|
||||
|
||||
ostream& operator <<(ostream&o, struct __ScopePathManip marg)
|
||||
{
|
||||
if (marg.scope != 0)
|
||||
dump_scope_path(o, marg.scope);
|
||||
return o;
|
||||
}
|
||||
|
||||
void NetDelaySrc::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "specify delay";
|
||||
if (posedge_) o << " posedge";
|
||||
if (negedge_) o << " negedge";
|
||||
o << " src "
|
||||
<< "(" << transition_delays_[IVL_PE_01]
|
||||
<< "," << transition_delays_[IVL_PE_10]
|
||||
<< "," << transition_delays_[IVL_PE_0z]
|
||||
<< "/" << transition_delays_[IVL_PE_z1]
|
||||
<< "," << transition_delays_[IVL_PE_1z]
|
||||
<< "," << transition_delays_[IVL_PE_z0]
|
||||
<< "/" << transition_delays_[IVL_PE_0x]
|
||||
<< "," << transition_delays_[IVL_PE_x1]
|
||||
<< "," << transition_delays_[IVL_PE_1x]
|
||||
<< "/" << transition_delays_[IVL_PE_x0]
|
||||
<< "," << transition_delays_[IVL_PE_xz]
|
||||
<< "," << transition_delays_[IVL_PE_zx]
|
||||
<< "): " << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
/* Dump a net. This can be a wire or register. */
|
||||
void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << type() << ": " << name() << "[" <<
|
||||
pin_count() << "]";
|
||||
o << setw(ind) << "" << type() << ": " << name()
|
||||
<< "[" << s0_ << ":" << e0_ << " count=" << pin_count() << "]";
|
||||
if (local_flag_)
|
||||
o << " (local)";
|
||||
o << " " << data_type_;
|
||||
if (signed_)
|
||||
o << " signed";
|
||||
switch (port_type_) {
|
||||
@@ -95,9 +160,11 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
}
|
||||
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
|
||||
if (scope())
|
||||
o << " scope=" << scope()->name();
|
||||
o << " #(" << rise_time() << "," << fall_time() << "," <<
|
||||
decay_time() << ") init=";
|
||||
o << " scope=" << scope_path(scope());
|
||||
o << " #(" << rise_time() << "," << fall_time() << ","
|
||||
<< decay_time() << ") vector_width=" << vector_width()
|
||||
<< " pin_count=" << pin_count()
|
||||
<< " init=";
|
||||
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
|
||||
o << pin(idx-1).get_init();
|
||||
|
||||
@@ -114,23 +181,15 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
o << setw(ind+4) << "" << "[" << idx << "]: " << nex
|
||||
<< " " << nex->name() << endl;
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < delay_paths_.size() ; idx += 1) {
|
||||
const NetDelaySrc*cur = delay_paths_[idx];
|
||||
cur->dump(o, ind+4);
|
||||
}
|
||||
|
||||
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_ << "] " <<
|
||||
"[" << idxh_ << ":" << idxl_ << "]" << endl;
|
||||
}
|
||||
|
||||
|
||||
/* Dump a NetNode and its pins. Dump what I know about the netnode on
|
||||
the first line, then list all the pins, with the name of the
|
||||
connected signal. */
|
||||
@@ -189,16 +248,20 @@ void NetObj::dump_obj_attr(ostream&o, unsigned ind) const
|
||||
|
||||
void NetAddSub::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Adder (NetAddSub): " << name() << endl;
|
||||
o << setw(ind) << "" << "Adder (NetAddSub): " << name()
|
||||
<< " width=" << width() << " pin_count=" << pin_count()
|
||||
<< endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetCAssign::dump_node(ostream&o, unsigned ind) const
|
||||
void NetArrayDq::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Procedural continuous assign (NetCAssign): "
|
||||
<< name() << endl;
|
||||
o << setw(ind) << "" << "NetArrayDq: " << name()
|
||||
<< " array=" << mem_->name()
|
||||
<< endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetCLShift::dump_node(ostream&o, unsigned ind) const
|
||||
@@ -216,6 +279,16 @@ void NetCompare::dump_node(ostream&o, unsigned ind) const
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetConcat::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NetConcat: "
|
||||
<< name()
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< " width=" << width_ << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetDivide::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NET_DIVIDE (NetDivide): " << name() << endl;
|
||||
@@ -223,12 +296,6 @@ void NetDivide::dump_node(ostream&o, unsigned ind) const
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetForce::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "force " << lval_->name() << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
void NetMult::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "LPM_MULT (NetMult): " << name() << endl;
|
||||
@@ -239,7 +306,8 @@ void NetMult::dump_node(ostream&o, unsigned ind) const
|
||||
void NetMux::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Multiplexer (NetMux): " << name()
|
||||
<< " scope=" << scope()->name() << endl;
|
||||
<< " width=" << width_ << " swidth=" << swidth_ << " size=" << size_
|
||||
<< " scope=" << scope_path(scope()) << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
@@ -247,22 +315,26 @@ void NetMux::dump_node(ostream&o, unsigned ind) const
|
||||
void NetBUFZ::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NetBUFZ: " << name()
|
||||
<< " scope=" << (scope()? scope()->name() : "")
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< " delay=(" << rise_time() << "," << fall_time() << "," <<
|
||||
decay_time() << ")" << endl;
|
||||
decay_time() << ") width=" << width() << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
void NetCaseCmp::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "case compare === : " << name() << endl;
|
||||
if (eeq_)
|
||||
o << setw(ind) << "" << "case compare === : " << name() << endl;
|
||||
else
|
||||
o << setw(ind) << "" << "case compare !== : " << name() << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
void NetConst::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "constant ";
|
||||
for (unsigned idx = pin_count() ; idx > 0 ; idx -= 1)
|
||||
o << setw(ind) << "" << "constant " << width_ << "'b";
|
||||
for (unsigned idx = width_ ; idx > 0 ; idx -= 1)
|
||||
o << value_[idx-1];
|
||||
o << ": " << name() << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
@@ -271,13 +343,20 @@ 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() : "")
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< " aset_value=" << aset_value_ << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetLiteral::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "constant real " << real_
|
||||
<< ": " << name() << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
void NetLogic::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "logic: ";
|
||||
@@ -339,7 +418,7 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
|
||||
}
|
||||
o << " #(" << rise_time()
|
||||
<< "," << fall_time() << "," << decay_time() << ") " << name()
|
||||
<< " scope=" << (scope()? scope()->name() : "")
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
@@ -353,17 +432,88 @@ void NetModulo::dump_node(ostream&o, unsigned ind) const
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetRamDq::dump_node(ostream&o, unsigned ind) const
|
||||
void NetPartSelect::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "LPM_RAM_DQ (" << mem_->name() << "): "
|
||||
<< name() << endl;
|
||||
const char*pt = "";
|
||||
switch (dir_) {
|
||||
case VP:
|
||||
pt = "VP";
|
||||
break;
|
||||
case PV:
|
||||
pt = "PV";
|
||||
break;
|
||||
case BI:
|
||||
pt = "BI";
|
||||
break;
|
||||
}
|
||||
o << setw(ind) << "" << "NetPartSelect(" << pt << "): "
|
||||
<< name() << " off=" << off_ << " wid=" << wid_ <<endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetReplicate::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NetReplicate: "
|
||||
<< name() << " wid=" << width_ << ", repeat_=" << repeat_
|
||||
<< ", input wid=" << width_/repeat_ << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetSignExtend::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NetSignExtend: "
|
||||
<< name() << " output width=" << width_ << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetUReduce::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "reduction logic: ";
|
||||
switch (type_) {
|
||||
case NONE:
|
||||
o << "NONE";
|
||||
break;
|
||||
case AND:
|
||||
o << "and";
|
||||
break;
|
||||
case OR:
|
||||
o << "or";
|
||||
break;
|
||||
case XOR:
|
||||
o << "xor";
|
||||
break;
|
||||
case NAND:
|
||||
o << "nand";
|
||||
break;
|
||||
case NOR:
|
||||
o << "nor";
|
||||
break;
|
||||
case XNOR:
|
||||
o << "xnor";
|
||||
break;
|
||||
}
|
||||
o << " #(" << rise_time()
|
||||
<< "," << fall_time() << "," << decay_time() << ") " << name()
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetSysFunc::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << def_->name << "(...)" << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetUserFunc::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << def_->name() << "(";
|
||||
o << setw(ind) << "" << scope_path(def_) << "(";
|
||||
o << ")" << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
@@ -371,7 +521,7 @@ void NetUserFunc::dump_node(ostream&o, unsigned ind) const
|
||||
|
||||
void NetTaskDef::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "task " << name_ << ";" << endl;
|
||||
o << setw(ind) << "" << "task " << scope_path(scope_) << ";" << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
|
||||
o << setw(ind+4) << "";
|
||||
@@ -413,11 +563,11 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
|
||||
switch (type_) {
|
||||
case NetProcTop::KINITIAL:
|
||||
o << "initial /* " << get_line() << " in "
|
||||
<< scope_->name() << " */" << endl;
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
case NetProcTop::KALWAYS:
|
||||
o << "always /* " << get_line() << " in "
|
||||
<< scope_->name() << " */" << endl;
|
||||
<< scope_path(scope_) << " */" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -433,22 +583,12 @@ void NetAssign_::dump_lval(ostream&o) const
|
||||
{
|
||||
if (sig_) {
|
||||
o << sig_->name();
|
||||
if (bmux_) {
|
||||
o << "[" << *bmux_ << "]";
|
||||
|
||||
} else {
|
||||
o << "[" << (loff_+lwid_-1) << ":" << loff_ << "]";
|
||||
if (word_) {
|
||||
o << "[word=" << *word_ << "]";
|
||||
}
|
||||
if (base_) {
|
||||
o << "[" << *base_ << " +: " << lwid_ << "]";
|
||||
}
|
||||
} else if (mem_) {
|
||||
// Is there an obvious way to flag memories in the dump
|
||||
// as different from the _real_ bit mux case?
|
||||
// o << "**memory**";
|
||||
o << mem_->name() << "[";
|
||||
if (bmux_) o << *bmux_;
|
||||
else o << "**oops**";
|
||||
o << "]";
|
||||
} else if (var_) {
|
||||
o << "<real " << var_->basename() << ">";
|
||||
} else {
|
||||
o << "";
|
||||
}
|
||||
@@ -474,10 +614,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
|
||||
|
||||
if (const NetExpr*de = get_delay())
|
||||
o << "#(" << *de << ") ";
|
||||
|
||||
o << *rval() << ";" << endl;
|
||||
}
|
||||
|
||||
@@ -487,20 +627,29 @@ 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
|
||||
|
||||
if (const NetExpr*de = get_delay())
|
||||
o << "#(" << *de << ") ";
|
||||
|
||||
o << *rval() << ";" << endl;
|
||||
|
||||
}
|
||||
|
||||
void NetAssignBase::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
if (const NetAssignNB *n1 = dynamic_cast<const NetAssignNB*>(this)) {
|
||||
n1->dump(o,ind);
|
||||
} else if (const NetAssign *n2 = dynamic_cast<const NetAssign*>(this)) {
|
||||
n2->dump(o,ind);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump a block statement */
|
||||
void NetBlock::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << type_;
|
||||
if (subscope_)
|
||||
o << " : " << subscope_->name();
|
||||
o << " : " << scope_path(subscope_);
|
||||
o << endl;
|
||||
|
||||
if (last_) {
|
||||
@@ -548,8 +697,9 @@ void NetCase::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetCAssign::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "cassign " << lval_->name() << " = "
|
||||
<< name() << ";" << endl;
|
||||
o << setw(ind) << "" << "cassign ";
|
||||
dump_lval(o);
|
||||
o << " = " << *rval() << "; /* " << get_line() << " */" << endl;
|
||||
}
|
||||
|
||||
void NetCondit::dump(ostream&o, unsigned ind) const
|
||||
@@ -569,13 +719,14 @@ void NetCondit::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetDeassign::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "deassign " << lval_->name() << "; "
|
||||
<< "/* " << get_line() << " */" << endl;
|
||||
o << setw(ind) << "" << "deassign ";
|
||||
dump_lval(o);
|
||||
o << "; /* " << get_line() << " */" << endl;
|
||||
}
|
||||
|
||||
void NetDisable::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "disable " << target_->name() << "; "
|
||||
o << setw(ind) << "" << "disable " << scope_path(target_) << "; "
|
||||
<< "/* " << get_line() << " */" << endl;
|
||||
}
|
||||
|
||||
@@ -594,7 +745,7 @@ void NetEvProbe::dump_node(ostream&o, unsigned ind) const
|
||||
o << "negedge ";
|
||||
break;
|
||||
}
|
||||
o << setw(ind) << "" << "-> " << event_->full_name() << "; " << endl;
|
||||
o << setw(ind) << "" << "-> " << event_->name() << "; " << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
@@ -607,11 +758,13 @@ void NetEvTrig::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetEvWait::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
assert(nevents() > 0);
|
||||
o << setw(ind) <<"" << "@(" << event(0)->full_name();
|
||||
o << setw(ind) <<"" << "@(";
|
||||
|
||||
if (nevents() > 0)
|
||||
o << event(0)->name();
|
||||
|
||||
for (unsigned idx = 1 ; idx < nevents() ; idx += 1)
|
||||
o << " or " << event(idx)->full_name();
|
||||
o << " or " << event(idx)->name();
|
||||
|
||||
o << ") // " << get_line() << endl;
|
||||
|
||||
@@ -623,8 +776,9 @@ void NetEvWait::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetForce::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "force " << lval_->name() << " = "
|
||||
<< name() << ";" << endl;
|
||||
o << setw(ind) << "" << "force ";
|
||||
dump_lval(o);
|
||||
o << " = " << *rval() << "; /* " << get_line() << " */" << endl;
|
||||
}
|
||||
|
||||
void NetForever::dump(ostream&o, unsigned ind) const
|
||||
@@ -635,7 +789,10 @@ void NetForever::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetFuncDef::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "function " << scope_->name() << endl;
|
||||
o << setw(ind) << "" << "function " << scope_path(scope_) << endl;
|
||||
if (result_sig_)
|
||||
o << setw(ind+2) << "" << "Return signal: "
|
||||
<< result_sig_->name() << endl;
|
||||
if (statement_)
|
||||
statement_->dump(o, ind+2);
|
||||
else
|
||||
@@ -661,12 +818,9 @@ void NetPDelay::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetRelease::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
if (lval_)
|
||||
o << setw(ind) << "" << "release " << lval_->name() << "; "
|
||||
<< "/* " << get_line() << " */" << endl;
|
||||
else
|
||||
o << setw(ind) << "" << "release (null); "
|
||||
<< "/* " << get_line() << " */" << endl;
|
||||
o << setw(ind) << "" << "release ";
|
||||
dump_lval(o);
|
||||
o << "; /* " << get_line() << " */" << endl;
|
||||
}
|
||||
|
||||
void NetRepeat::dump(ostream&o, unsigned ind) const
|
||||
@@ -677,7 +831,9 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetScope::dump(ostream&o) const
|
||||
{
|
||||
o << name();
|
||||
/* This is a constructed hierarchical name. */
|
||||
o << scope_path(this);
|
||||
|
||||
switch (type_) {
|
||||
case BEGIN_END:
|
||||
o << " sequential block";
|
||||
@@ -689,11 +845,14 @@ void NetScope::dump(ostream&o) const
|
||||
o << " function";
|
||||
break;
|
||||
case MODULE:
|
||||
o << " module <" << (module_name_? module_name_ : "") << ">";
|
||||
o << " module <" << (module_name_? module_name_.str() : "") << ">";
|
||||
break;
|
||||
case TASK:
|
||||
o << " task";
|
||||
break;
|
||||
case GENBLOCK:
|
||||
o << " generate block";
|
||||
break;
|
||||
}
|
||||
o << endl;
|
||||
|
||||
@@ -706,7 +865,7 @@ void NetScope::dump(ostream&o) const
|
||||
|
||||
/* Dump the parameters for this scope. */
|
||||
{
|
||||
map<string,param_expr_t>::const_iterator pp;
|
||||
map<perm_string,param_expr_t>::const_iterator pp;
|
||||
for (pp = parameters.begin()
|
||||
; pp != parameters.end() ; pp ++) {
|
||||
o << " parameter ";
|
||||
@@ -731,7 +890,7 @@ void NetScope::dump(ostream&o) const
|
||||
|
||||
/* Dump the saved defparam assignments here. */
|
||||
{
|
||||
map<hname_t,NetExpr*>::const_iterator pp;
|
||||
map<pform_name_t,NetExpr*>::const_iterator pp;
|
||||
for (pp = defparams.begin()
|
||||
; pp != defparams.end() ; pp ++ ) {
|
||||
o << " defparam " << (*pp).first << " = " <<
|
||||
@@ -739,15 +898,11 @@ void NetScope::dump(ostream&o) const
|
||||
}
|
||||
}
|
||||
|
||||
for (NetVariable*cur = vars_ ; cur ; cur = cur->snext_) {
|
||||
o << " real " << cur->basename() << " // "
|
||||
<< cur->get_line() << endl;
|
||||
}
|
||||
|
||||
/* Dump the events in this scope. */
|
||||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
|
||||
o << " event " << cur->name() << "; nprobe="
|
||||
<< cur->nprobe() << " // " << cur->get_line() << endl;
|
||||
<< cur->nprobe() << " scope=" << scope_path(cur->scope())
|
||||
<< " // " << cur->get_line() << endl;
|
||||
}
|
||||
|
||||
// Dump the signals,
|
||||
@@ -759,18 +914,33 @@ void NetScope::dump(ostream&o) const
|
||||
} while (cur != signals_->sig_next_);
|
||||
}
|
||||
|
||||
// Dump the memories,
|
||||
if (memories_) {
|
||||
NetMemory*cur = memories_->snext_;
|
||||
do {
|
||||
cur->dump(o, 4);
|
||||
cur = cur->snext_;
|
||||
} while (cur != memories_->snext_);
|
||||
// Dump specparams
|
||||
typedef map<perm_string,spec_val_t>::const_iterator specparam_it_t;
|
||||
for (specparam_it_t cur = specparams.begin()
|
||||
; cur != specparams.end() ; cur ++ ) {
|
||||
o << " specparam " << (*cur).first
|
||||
<< " = ";
|
||||
spec_val_t value = (*cur).second;
|
||||
switch (value.type) {
|
||||
case IVL_VT_REAL:
|
||||
o << "R:" << value.real_val;
|
||||
break;
|
||||
case IVL_VT_BOOL:
|
||||
o << "I:" << value.integer;
|
||||
break;
|
||||
default:
|
||||
o << "<bad type>";
|
||||
break;
|
||||
}
|
||||
o << endl;
|
||||
}
|
||||
|
||||
switch (type_) {
|
||||
case FUNC:
|
||||
func_def()->dump(o, 4);
|
||||
if (func_def())
|
||||
func_def()->dump(o, 4);
|
||||
else
|
||||
o << " MISSING FUNCTION DEFINITION" << endl;
|
||||
break;
|
||||
case TASK:
|
||||
task_def()->dump(o, 4);
|
||||
@@ -806,7 +976,7 @@ void NetSTask::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetUTask::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << task_->name() << ";" << endl;
|
||||
o << setw(ind) << "" << scope_path(task_) << ";" << endl;
|
||||
}
|
||||
|
||||
void NetWhile::dump(ostream&o, unsigned ind) const
|
||||
@@ -866,6 +1036,9 @@ void NetEBinary::dump(ostream&o) const
|
||||
case 'O':
|
||||
o << "~|";
|
||||
break;
|
||||
case 'p':
|
||||
o << "**";
|
||||
break;
|
||||
case 'r':
|
||||
o << ">>";
|
||||
break;
|
||||
@@ -916,7 +1089,7 @@ void NetEConstParam::dump(ostream&o) const
|
||||
{
|
||||
o << "<" << name_ << "=";
|
||||
NetEConst::dump(o);
|
||||
o << ">";
|
||||
o << ", wid=" << expr_width() << ">";
|
||||
}
|
||||
|
||||
void NetECReal::dump(ostream&o) const
|
||||
@@ -938,7 +1111,7 @@ void NetEEvent::dump(ostream&o) const
|
||||
|
||||
void NetEScope::dump(ostream&o) const
|
||||
{
|
||||
o << "<scope=" << scope_->name() << ">";
|
||||
o << "<scope=" << scope_path(scope_) << ">";
|
||||
}
|
||||
|
||||
void NetESelect::dump(ostream&o) const
|
||||
@@ -974,30 +1147,19 @@ void NetESignal::dump(ostream&o) const
|
||||
{
|
||||
if (has_sign())
|
||||
o << "+";
|
||||
o << name() << "[" << msi_<<":"<<lsi_ << "]";
|
||||
}
|
||||
|
||||
void NetEBitSel::dump(ostream&o) const
|
||||
{
|
||||
sig_->dump(o);
|
||||
o << "[";
|
||||
idx_->dump(o);
|
||||
o << "]";
|
||||
}
|
||||
|
||||
void NetEMemory::dump(ostream&o) const
|
||||
{
|
||||
o << mem_->name() << "[";
|
||||
if (idx_) idx_->dump(o);
|
||||
o << "]";
|
||||
o << name();
|
||||
if (word_) o << "[word=" << *word_ << "]";
|
||||
o << "[" << msi()<<":"<<lsi() << "]";
|
||||
}
|
||||
|
||||
void NetEParam::dump(ostream&o) const
|
||||
{
|
||||
if (scope_ != 0)
|
||||
o << "<" << scope_->name() << "." << name_ << ">";
|
||||
else
|
||||
o << "<" << scope_path(scope_) << "." << name_ << ">";
|
||||
else if (name_)
|
||||
o << "<" << name_ << ">";
|
||||
else
|
||||
o << "<" "???" ">";
|
||||
}
|
||||
|
||||
void NetETernary::dump(ostream&o) const
|
||||
@@ -1008,7 +1170,7 @@ void NetETernary::dump(ostream&o) const
|
||||
|
||||
void NetEUFunc::dump(ostream&o) const
|
||||
{
|
||||
o << name() << "(";
|
||||
o << func_->basename() << "(";
|
||||
if (parms_.count() > 0) {
|
||||
parms_[0]->dump(o);
|
||||
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
||||
@@ -1034,16 +1196,11 @@ void NetEUnary::dump(ostream&o) const
|
||||
o << ")";
|
||||
}
|
||||
|
||||
void NetEVariable::dump(ostream&o) const
|
||||
{
|
||||
o << var_->basename();
|
||||
}
|
||||
|
||||
void Design::dump(ostream&o) const
|
||||
{
|
||||
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
|
||||
o << "SCOPES:" << endl;
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->dump(o);
|
||||
|
||||
@@ -1068,6 +1225,117 @@ void Design::dump(ostream&o) const
|
||||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.176 2007/06/02 03:42:12 steve
|
||||
* Properly evaluate scope path expressions.
|
||||
*
|
||||
* Revision 1.175 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.174 2007/03/02 06:13:22 steve
|
||||
* Add support for edge sensitive spec paths.
|
||||
*
|
||||
* Revision 1.173 2007/02/01 03:14:33 steve
|
||||
* Detect and report arrays without index in net contexts.
|
||||
*
|
||||
* Revision 1.172 2007/01/16 05:44:14 steve
|
||||
* Major rework of array handling. Memories are replaced with the
|
||||
* more general concept of arrays. The NetMemory and NetEMemory
|
||||
* classes are removed from the ivl core program, and the IVL_LPM_RAM
|
||||
* lpm type is removed from the ivl_target API.
|
||||
*
|
||||
* Revision 1.171 2006/10/30 05:44:49 steve
|
||||
* Expression widths with unsized literals are pseudo-infinite width.
|
||||
*
|
||||
* Revision 1.170 2006/10/03 05:06:00 steve
|
||||
* Support real valued specify delays, properly scaled.
|
||||
*
|
||||
* Revision 1.169 2006/09/26 19:48:40 steve
|
||||
* Missing PSpec.cc file.
|
||||
*
|
||||
* Revision 1.168 2006/09/23 04:57:19 steve
|
||||
* Basic support for specify timing.
|
||||
*
|
||||
* Revision 1.167 2006/07/31 03:50:17 steve
|
||||
* Add support for power in constant expressions.
|
||||
*
|
||||
* Revision 1.166 2006/06/18 04:15:50 steve
|
||||
* Add support for system functions in continuous assignments.
|
||||
*
|
||||
* Revision 1.165 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.164 2006/02/02 02:43:57 steve
|
||||
* Allow part selects of memory words in l-values.
|
||||
*
|
||||
* Revision 1.163 2005/08/27 04:32:08 steve
|
||||
* Handle synthesis of fully packed case statements.
|
||||
*
|
||||
* Revision 1.162 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
* Revision 1.161 2005/07/07 16:22:49 steve
|
||||
* Generalize signals to carry types.
|
||||
*
|
||||
* Revision 1.160 2005/05/24 01:44:27 steve
|
||||
* Do sign extension of structuran nets.
|
||||
*
|
||||
* Revision 1.159 2005/05/17 20:56:55 steve
|
||||
* Parameters cannot have their width changed.
|
||||
*
|
||||
* Revision 1.158 2005/05/07 03:13:30 steve
|
||||
* Include delay expressions for assignments in dump.
|
||||
*
|
||||
* Revision 1.157 2005/03/09 05:52:03 steve
|
||||
* Handle case inequality in netlists.
|
||||
*
|
||||
* Revision 1.156 2005/02/08 00:12:36 steve
|
||||
* Add the NetRepeat node, and code generator support.
|
||||
*
|
||||
* Revision 1.155 2005/02/03 04:56:20 steve
|
||||
* laborate reduction gates into LPM_RED_ nodes.
|
||||
*
|
||||
* Revision 1.154 2005/01/24 05:28:30 steve
|
||||
* Remove the NetEBitSel and combine all bit/part select
|
||||
* behavior into the NetESelect node and IVL_EX_SELECT
|
||||
* ivl_target expression type.
|
||||
*
|
||||
* Revision 1.153 2005/01/22 18:16:00 steve
|
||||
* Remove obsolete NetSubnet class.
|
||||
*
|
||||
* Revision 1.152 2005/01/09 20:16:00 steve
|
||||
* Use PartSelect/PV and VP to handle part selects through ports.
|
||||
*
|
||||
* Revision 1.151 2004/12/29 23:55:43 steve
|
||||
* Unify elaboration of l-values for all proceedural assignments,
|
||||
* including assing, cassign and force.
|
||||
*
|
||||
* Generate NetConcat devices for gate outputs that feed into a
|
||||
* vector results. Use this to hande gate arrays. Also let gate
|
||||
* arrays handle vectors of gates when the outputs allow for it.
|
||||
*
|
||||
* Revision 1.150 2004/12/11 02:31:25 steve
|
||||
* Rework of internals to carry vectors through nexus instead
|
||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
||||
* down this path.
|
||||
*
|
||||
* Revision 1.149 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.148 2004/05/31 23:34:36 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.147 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.146 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.145 2003/12/17 16:52:39 steve
|
||||
* Debug dumps for synth2.
|
||||
*
|
||||
* Revision 1.144 2003/07/26 03:34:42 steve
|
||||
* Start handling pad of expressions in code generators.
|
||||
*
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.5 2002/12/08 03:06:30 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.7 2004/10/13 22:01:34 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.7
|
||||
VERSION = 0.8
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -37,14 +37,12 @@ mandir = @mandir@
|
||||
dllib=@DLLIB@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
|
||||
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: iverilog-vpi@EXEEXT@
|
||||
@@ -63,7 +61,7 @@ iverilog-vpi@EXEEXT@: $O
|
||||
|
||||
|
||||
main.o: main.c
|
||||
$(CC) $(CFLAGS) -c $(srcdir)/main.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
|
||||
|
||||
# Windows specific...
|
||||
res.o: res.rc
|
||||
|
||||
+573
-565
File diff suppressed because it is too large
Load Diff
+9
-19
@@ -16,12 +16,12 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.18 2003/08/10 00:39:13 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.26 2007/02/06 05:07:31 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.7
|
||||
VERSION = 0.8
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -37,14 +37,12 @@ mandir = @mandir@
|
||||
dllib=@DLLIB@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
|
||||
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: iverilog@EXEEXT@
|
||||
@@ -52,22 +50,16 @@ all: iverilog@EXEEXT@
|
||||
clean:
|
||||
rm -f *.o lexor.c parse.c parse.h parse.output
|
||||
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
|
||||
rm -f iverilog@EXEEXT@
|
||||
rm -f iverilog@EXEEXT@ iverilog.pdf iverilog.ps
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile
|
||||
|
||||
O = main.o build_string.o lexor.o parse.o substit.o cflexor.o cfparse.o
|
||||
O = main.o substit.o cflexor.o cfparse.o
|
||||
|
||||
iverilog@EXEEXT@: $O
|
||||
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
|
||||
|
||||
lexor.c: lexor.lex
|
||||
flex -s -olexor.c $(srcdir)/lexor.lex
|
||||
|
||||
parse.h parse.c: parse.y
|
||||
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
|
||||
|
||||
cflexor.c: cflexor.lex
|
||||
flex -s -Pcf -ocflexor.c $(srcdir)/cflexor.lex
|
||||
|
||||
@@ -76,11 +68,9 @@ cfparse.h cfparse.c: cfparse.y
|
||||
|
||||
|
||||
main.o: main.c globals.h
|
||||
$(CC) $(CFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
||||
|
||||
build_string.o: build_string.c globals.h
|
||||
lexor.o: lexor.c parse.h globals.h
|
||||
parse.o: parse.c globals.h
|
||||
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
|
||||
cfparse.o: cfparse.c globals.h cfparse_misc.h
|
||||
|
||||
@@ -90,7 +80,7 @@ iverilog.ps: $(srcdir)/iverilog.man
|
||||
iverilog.pdf: iverilog.ps
|
||||
ps2pdf iverilog.ps iverilog.pdf
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@MING32@,yes)
|
||||
INSTALL_DOC = $(prefix)/iverilog.pdf $(mandir)/man1/iverilog.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
all: iverilog.pdf
|
||||
@@ -115,4 +105,4 @@ installdirs: ../mkinstalldirs
|
||||
|
||||
uninstall:
|
||||
rm -f $(bindir)/iverilog@EXEEXT@
|
||||
rm -f $(mandir)/man1/iverilog.1
|
||||
rm -f $(mandir)/man1/iverilog.1 $(prefix)/iverilog.pdf
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#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>
|
||||
|
||||
int build_string(char*output, size_t olen, const char*pattern)
|
||||
{
|
||||
char tmp_buf[1024];
|
||||
|
||||
char*output_save = output;
|
||||
while (*pattern) {
|
||||
|
||||
if (*pattern == '%') {
|
||||
pattern += 1;
|
||||
switch (*pattern) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case '%':
|
||||
*output++ = '%';
|
||||
break;
|
||||
|
||||
case '[': {
|
||||
const char*tail;
|
||||
pattern += 1;
|
||||
assert(*pattern);
|
||||
tail = strchr(pattern+1, ']');
|
||||
assert(tail);
|
||||
strncpy(tmp_buf, pattern+1, tail-pattern-1);
|
||||
tmp_buf[tail-pattern-1] = 0;
|
||||
|
||||
if (((*pattern == 's') && start)
|
||||
|| ((*pattern == 'v') && verbose_flag)
|
||||
|| ((*pattern == 'M') && depfile)
|
||||
|| ((*pattern == 'N') && npath)
|
||||
|| ((*pattern == 'T') && mtm)) {
|
||||
int rc = build_string(output, olen,
|
||||
tmp_buf);
|
||||
output += rc;
|
||||
olen -= rc;
|
||||
}
|
||||
pattern = tail;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'B':
|
||||
strcpy(output, base);
|
||||
output += strlen(base);
|
||||
olen -= strlen(base);
|
||||
break;
|
||||
|
||||
case '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);
|
||||
output += strlen(f_list);
|
||||
olen -= strlen(f_list);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (mod_list) {
|
||||
strcpy(output, mod_list);
|
||||
output += strlen(mod_list);
|
||||
olen -= strlen(mod_list);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
if (depfile) {
|
||||
strcpy(output, depfile);
|
||||
output += strlen(depfile);
|
||||
olen -= strlen(depfile);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
if (npath) {
|
||||
strcpy(output, npath);
|
||||
output += strlen(npath);
|
||||
olen -= strlen(npath);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
strcpy(output, opath);
|
||||
output += strlen(opath);
|
||||
olen -= strlen(opath);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (start) {
|
||||
strcpy(output, start);
|
||||
output += strlen(start);
|
||||
olen -= strlen(start);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
if (mtm) {
|
||||
strcpy(output, mtm);
|
||||
output += strlen(mtm);
|
||||
olen -= strlen(mtm);
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
strcpy(output, targ);
|
||||
output += strlen(targ);
|
||||
olen -= strlen(targ);
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
strcpy(output, warning_flags);
|
||||
output += strlen(warning_flags);
|
||||
olen -= strlen(warning_flags);
|
||||
break;
|
||||
|
||||
}
|
||||
pattern += 1;
|
||||
|
||||
} else {
|
||||
*output++ = *pattern++;
|
||||
olen -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
*output = 0;
|
||||
return output-output_save;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: build_string.c,v $
|
||||
* Revision 1.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.
|
||||
*
|
||||
* Revision 1.1 2000/10/08 22:36:56 steve
|
||||
* iverilog with an iverilog.conf configuration file.
|
||||
*
|
||||
*/
|
||||
|
||||
+43
-7
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cflexor.lex,v 1.6 2002/05/28 20:40:37 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cflexor.lex,v 1.11 2007/03/22 16:08:18 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "cfparse.h"
|
||||
@@ -37,12 +37,14 @@
|
||||
YYLTYPE yylloc;
|
||||
|
||||
static int comment_enter;
|
||||
static char* trim_trailing_white(char*txt, int trim);
|
||||
|
||||
%}
|
||||
|
||||
%x CCOMMENT
|
||||
%x LCOMMENT
|
||||
%x PLUS_ARGS
|
||||
%x FILE_NAME
|
||||
|
||||
%%
|
||||
|
||||
@@ -76,6 +78,7 @@ static int comment_enter;
|
||||
|
||||
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
|
||||
|
||||
"+integer-width+" { BEGIN(PLUS_ARGS); return TOK_INTEGER_WIDTH; }
|
||||
|
||||
/* If it is not any known plus-flag, return the generic form. */
|
||||
"+"[^\n \t\b\f\r+]* {
|
||||
@@ -112,17 +115,50 @@ static int comment_enter;
|
||||
/* 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; }
|
||||
"/"[\r\n] { /* Special case of file name "/" */
|
||||
cflval.text = trim_trailing_white(yytext, 0);
|
||||
return TOK_STRING; }
|
||||
"/"[^\*\/] { /* A file name that starts with "/". */
|
||||
yymore();
|
||||
BEGIN(FILE_NAME); }
|
||||
[^/\n \t\b\r+-][^/\n\r]* { /* A file name that starts with other than "/" */
|
||||
yymore();
|
||||
BEGIN(FILE_NAME); }
|
||||
|
||||
<FILE_NAME>"//" {
|
||||
/* Found a trailing comment. Returning the terminated name. */
|
||||
cflval.text = trim_trailing_white(yytext, 2);
|
||||
BEGIN(LCOMMENT);
|
||||
return TOK_STRING; }
|
||||
<FILE_NAME>"/"?[^/\n\r]* {
|
||||
yymore();
|
||||
/* not a comment... continuing */; }
|
||||
<FILE_NAME>[\n\r] {
|
||||
/* No trailing comment. Return the file name. */
|
||||
cflval.text = trim_trailing_white(yytext, 0);
|
||||
BEGIN(0);
|
||||
return TOK_STRING; }
|
||||
|
||||
/* Fallback match. */
|
||||
. { return yytext[0]; }
|
||||
|
||||
%%
|
||||
|
||||
static char* trim_trailing_white(char*text, int trim)
|
||||
{
|
||||
char*cp = text + strlen(text);
|
||||
while (cp > text && trim > 0) {
|
||||
trim -= 1;
|
||||
cp -= 1;
|
||||
*cp = 0;
|
||||
}
|
||||
while (cp > text && strchr("\n\r\t\b", cp[-1]))
|
||||
cp -= 1;
|
||||
|
||||
cp[0] = 0;
|
||||
return strdup(text);
|
||||
}
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
|
||||
+18
-6
@@ -17,14 +17,17 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cfparse.y,v 1.8 2002/06/23 20:10:51 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cfparse.y,v 1.12 2007/04/19 02:52:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
# include "globals.h"
|
||||
# include "cfparse_misc.h"
|
||||
# include <ctype.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* This flag is set to 0, 1 or 2 if file names are to be translated to
|
||||
@@ -59,6 +62,7 @@ static void translate_file_name(char*text)
|
||||
|
||||
%token TOK_Da TOK_Dv TOK_Dy
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
|
||||
%token TOK_INTEGER_WIDTH
|
||||
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
||||
|
||||
%%
|
||||
@@ -80,7 +84,7 @@ item
|
||||
: TOK_STRING
|
||||
{ char*tmp = substitutions($1);
|
||||
translate_file_name(tmp);
|
||||
process_file_name(tmp);
|
||||
process_file_name(tmp, 0);
|
||||
free($1);
|
||||
free(tmp);
|
||||
}
|
||||
@@ -95,9 +99,7 @@ item
|
||||
| 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);
|
||||
process_file_name(tmp, 1);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
@@ -142,6 +144,15 @@ item
|
||||
|
||||
| TOK_LIBEXT libext_args
|
||||
|
||||
/* These are various misc flags that are supported. */
|
||||
|
||||
| TOK_INTEGER_WIDTH TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
free($2);
|
||||
integer_width = strtoul(tmp,0,10);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* The +<word> tokens that are not otherwise matched, are
|
||||
ignored. The skip_args rule arranges for all the argument words
|
||||
to be consumed. */
|
||||
@@ -207,4 +218,5 @@ skip_arg : TOK_PLUSARG
|
||||
|
||||
int yyerror(const char*msg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
+11
-1
@@ -20,7 +20,7 @@
|
||||
* 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 $"
|
||||
#ident "$Id: cfparse_misc.h,v 1.6 2004/02/15 18:03:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -38,8 +38,18 @@ struct cfltype {
|
||||
# define YYLTYPE struct cfltype
|
||||
extern YYLTYPE yylloc;
|
||||
|
||||
int cflex(void);
|
||||
int cferror(const char *);
|
||||
int cfparse(void);
|
||||
|
||||
/*
|
||||
* $Log: cfparse_misc.h,v $
|
||||
* Revision 1.6 2004/02/15 18:03:30 steve
|
||||
* Cleanup of warnings.
|
||||
*
|
||||
* Revision 1.5 2003/09/26 21:25:58 steve
|
||||
* Warnings cleanup.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
+20
-56
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: globals.h,v 1.16 2002/08/12 01:35:01 steve Exp $"
|
||||
#ident "$Id: globals.h,v 1.21 2007/04/19 02:52:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stddef.h>
|
||||
@@ -29,15 +29,7 @@ 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;
|
||||
|
||||
extern char*mod_list;
|
||||
|
||||
/* This is the optional -Tmin|typ|max setting. */
|
||||
extern const char*mtm;
|
||||
extern char* iconfig_common_path;
|
||||
|
||||
/* Ths is the optional -M<dependfile> value, if one was supplied. */
|
||||
extern const char*depfile;
|
||||
@@ -57,14 +49,14 @@ 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;
|
||||
/* This is the integer-width argument that will be passed to ivl. */
|
||||
extern unsigned integer_width;
|
||||
|
||||
/* 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);
|
||||
extern void process_file_name(const char*name, int lib_flag);
|
||||
|
||||
/* Add the name to the list of library directories. */
|
||||
extern void process_library_switch(const char*name);
|
||||
@@ -86,12 +78,23 @@ extern char warning_flags[];
|
||||
extern char* library_flags;
|
||||
extern char* library_flags2;
|
||||
|
||||
extern const char*lookup_pattern(const char*key);
|
||||
|
||||
extern int build_string(char*out, size_t olen, const char*pattern);
|
||||
|
||||
/*
|
||||
* $Log: globals.h,v $
|
||||
* Revision 1.21 2007/04/19 02:52:53 steve
|
||||
* Add support for -v flag in command file.
|
||||
*
|
||||
* Revision 1.20 2007/03/07 04:24:59 steve
|
||||
* Make integer width controllable.
|
||||
*
|
||||
* Revision 1.19 2003/11/18 06:31:46 steve
|
||||
* Remove the iverilog.conf file.
|
||||
*
|
||||
* Revision 1.18 2003/11/13 04:09:49 steve
|
||||
* Pass flags through the temporary config file.
|
||||
*
|
||||
* Revision 1.17 2003/11/01 04:21:57 steve
|
||||
* Add support for a target static config file.
|
||||
*
|
||||
* Revision 1.16 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
@@ -106,44 +109,5 @@ extern int build_string(char*out, size_t olen, const char*pattern);
|
||||
* 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.
|
||||
*
|
||||
* Revision 1.2 2000/10/28 03:45:47 steve
|
||||
* Use the conf file to generate the vvm ivl string.
|
||||
*
|
||||
* Revision 1.1 2000/10/08 22:36:56 steve
|
||||
* iverilog with an iverilog.conf configuration file.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
+71
-24
@@ -1,10 +1,10 @@
|
||||
.TH iverilog 1 "$Date: 2003/08/09 04:31:44 $" Version "$Date: 2003/08/09 04:31:44 $"
|
||||
.TH iverilog 1 "$Date: 2007/06/05 01:56:12 $" Version "$Date: 2007/06/05 01:56:12 $"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[-ESVv] [-Cpath] [-ccmdfile] [-g1|-g2|-g3.0] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-ESVv] [-Bpath] [-ccmdfile] [-g1|-g2|-g2x|-gspecify-gxtypes] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
|
||||
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
|
||||
|
||||
@@ -21,11 +21,12 @@ types are added as code generators are implemented.
|
||||
\fIiverilog\fP accepts the following options:
|
||||
.TP 8
|
||||
.B -B\fIbase\fP
|
||||
The \fIiverilog\fP program uses external programs to preprocess and
|
||||
compile the Verilog source. Normally, the path used to locate these
|
||||
tools is built into the \fIiverilog\fP program. However, the \fB-B\fP
|
||||
switch allows the user to select a different set of programs. The path
|
||||
given is used to locate \fIivlpp\fP, \fIivl\fP and the VPI modules.
|
||||
The \fIiverilog\fP program uses external programs and configuration
|
||||
files to preprocess and compile the Verilog source. Normally, the path
|
||||
used to locate these tools is built into the \fIiverilog\fP
|
||||
program. However, the \fB-B\fP switch allows the user to select a
|
||||
different set of programs. The path given is used to locate
|
||||
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
|
||||
.TP 8
|
||||
.B -c\fIfile\fP
|
||||
This flag specifies an input file that contains a list of Verilog
|
||||
@@ -33,14 +34,6 @@ source files. This is similar to the \fIcommand file\fP of other
|
||||
Verilog simulators, in that it is a file that contains the file names
|
||||
instead of taking them on the command line. See \fBCommand Files\fP below.
|
||||
.TP 8
|
||||
.B -C\fIpath\fP
|
||||
This flag selects the driver configuration file to use. Normally, the
|
||||
iverilog program will read its configuration file from
|
||||
/usr/lib/ivl/iverilog.conf (or the install path configured at compile
|
||||
time) but the user can specify the path to a different configuration
|
||||
file. This is useful when testing new configuration files. See the
|
||||
installed configuration file for a summary of the file format.
|
||||
.TP 8
|
||||
.B -D\fImacro\fP
|
||||
Defines macro \fImacro\fP with the string `1' as its definition. This
|
||||
form is normally only used to trigger ifdef conditionals in the
|
||||
@@ -55,16 +48,31 @@ is the Verilog input, but with file inclusions and macro references
|
||||
expanded and removed. This is useful, for example, to preprocess
|
||||
Verilog source for use by other compilers.
|
||||
.TP 8
|
||||
.B -g1\fI|\fP-g2\fI|\fP-g3.0
|
||||
.B -g1\fI|\fP-g2\fI|\fP-g2x
|
||||
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,
|
||||
\fIIEEE1364-2001\fP(2), or \fIVerilog with extension\fP(2x). 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
|
||||
.B -gspecify\fI|\fP-gno-specify
|
||||
Enable (default) or disable specify block support. When enabled,
|
||||
specify block code is elaborated. When disabled, specify blocks are
|
||||
parsed but ignored. Specify blocks are commonly not needed for RTL
|
||||
simulation, and in fact can hurt performance of the
|
||||
simulation. However, disabling specify blocks reduces accuracy of
|
||||
full-timing simulations.
|
||||
.TP 8
|
||||
.B -gxtypes\fI|\fP-gno-xtypes
|
||||
Enable (default) or disable support for extended types. Enabling
|
||||
extended types allows for new types that are supported by Icarus
|
||||
Verilog as extensions beyond the baseline Verilog. It may be necessary
|
||||
to disable extended types if compiling code that clashes with the few
|
||||
new keywords used to implement the type system.
|
||||
.TP 8
|
||||
.B -I\fIincludedir\fP
|
||||
Append directory \fIincludedir\fP to list of directories searched
|
||||
for Verilog include files. The \fB-I\fP switch may be used many times
|
||||
to specify several directories to search, the directories are searched
|
||||
@@ -81,6 +89,8 @@ leading or trailing space.
|
||||
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 system module is implicit and always included.
|
||||
If a System Function Table file (<module>.sft) exists for the module it
|
||||
will be loaded automatically.
|
||||
.TP 8
|
||||
.B -N\fIpath\fP
|
||||
This is used for debugging the compiler proper. Dump the final netlist
|
||||
@@ -127,7 +137,11 @@ Use this switch to specify the target output format. See the
|
||||
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, as well as the version of the
|
||||
product as a whole.
|
||||
product as a whole. You will notice that the command lines include
|
||||
a reference to a key temporary file that passes information to the
|
||||
compiler proper. To keep that file from being deleted at the end
|
||||
of the process, provide a file name of your own in the environment
|
||||
variable \fBIVERILOG_ICONFIG\fP.
|
||||
.TP 8
|
||||
.B -V
|
||||
Print the version of the compiler, and exit.
|
||||
@@ -187,7 +201,7 @@ implies the synthesis \fB-S\fP flag.
|
||||
|
||||
.SH "WARNING TYPES"
|
||||
These are the types of warnings that can be selected by the \fB-W\fP
|
||||
switch. All the warning types (other then \fBall\fP) can also be
|
||||
switch. All the warning types (other than \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.
|
||||
|
||||
@@ -215,6 +229,33 @@ inherit timescale from another file. Both probably mean that
|
||||
timescales are inconsistent, and simulation timing can be confusing
|
||||
and dependent on compilation order.
|
||||
|
||||
.SH "SYSTEM FUNCTION TABLE FILES"
|
||||
If the source file name as a \fB.sft\fP suffix, then it is taken to be
|
||||
a system function table file. A System function table file is used to
|
||||
describe to the compiler the return types for system functions. This
|
||||
is necessary because the compiler needs this information to elaborate
|
||||
expressions that contain these system functions, but cannot run the
|
||||
sizetf functions since it has no run-time.
|
||||
|
||||
The format of the table is ASCII, one function per line. Empty lines
|
||||
are ignored, and lines that start with the '\fI#\fP' character are
|
||||
comment lines. Each non-comment line starts with the function name,
|
||||
then the vpi type (i.e. vpiSysFuncReal). The following types are
|
||||
supported:
|
||||
|
||||
.TP 8
|
||||
.B vpiSysFuncReal
|
||||
The function returns a real/realtime value.
|
||||
|
||||
.TP 8
|
||||
.B vpiSysFuncInt
|
||||
The function returns an integer.
|
||||
|
||||
.TP 8
|
||||
.B vpiSysFuncSized <wid> <signed|unsigned>
|
||||
The function returns a vector with the given width, and is signed or
|
||||
unsigned according to the flag.
|
||||
|
||||
.SH "COMMAND FILES"
|
||||
The command file allows the user to place source file names and
|
||||
certain command line switches into a text file instead of on a long
|
||||
@@ -225,7 +266,7 @@ well as # comments, if the # starts the line.
|
||||
.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.
|
||||
character. Variables are substituted in file names.
|
||||
|
||||
.TP 8
|
||||
.B -y\ \fIlibdir\fP
|
||||
@@ -280,19 +321,25 @@ become munged.
|
||||
.B +tolower-filename\fP
|
||||
This is similar to the \fB+toupper-filename\fP hack described above.
|
||||
|
||||
.TP 8
|
||||
.B +integer-width+\fIvalue\fP
|
||||
This allows the programmer to select the width for integer variables
|
||||
in the Verilog source. The default is 32, the value can be any desired
|
||||
integer value.
|
||||
|
||||
.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
|
||||
substituted 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
|
||||
.SH EXAMPLES
|
||||
These examples assume that you have a Verilog source file called hello.v in
|
||||
the current directory
|
||||
|
||||
@@ -325,5 +372,5 @@ vvp(1),
|
||||
.nf
|
||||
Copyright \(co 2002 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: lexor.lex,v 1.5 2001/07/25 03:10:50 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <string.h>
|
||||
# include "parse.h"
|
||||
|
||||
%}
|
||||
|
||||
%x CTOKENS
|
||||
%x PATTERN
|
||||
|
||||
%%
|
||||
|
||||
"#".* { /* eat comments */; }
|
||||
|
||||
"\n" { /* eat line-ends */; }
|
||||
"\r" { /* eat line-ends */; }
|
||||
|
||||
"[" { BEGIN(CTOKENS); return '['; }
|
||||
|
||||
<CTOKENS>"]" { BEGIN(0); return ']'; }
|
||||
|
||||
<CTOKENS>[ \t\b]+ { /* skip white space */; }
|
||||
|
||||
<CTOKENS>"-S" { return CT_S; }
|
||||
|
||||
<CTOKENS>"-t"[a-zA-Z0-9\-_]+ {
|
||||
yylval.text = strdup(yytext+2);
|
||||
return CT_t; }
|
||||
|
||||
"<"[^>]*">" {
|
||||
BEGIN(PATTERN);
|
||||
yylval.text = strdup(yytext);
|
||||
return PATTERN_NAME; }
|
||||
|
||||
<PATTERN>.* {
|
||||
BEGIN(0);
|
||||
/* Trim off a trailing \r. This is an issue in the DOS world. */
|
||||
if (yytext[strlen(yytext)-1] == '\r')
|
||||
yytext[strlen(yytext)-1] = 0;
|
||||
|
||||
yylval.text = strdup(yytext);
|
||||
return PATTERN_TEXT; }
|
||||
|
||||
. { fprintf(stderr, "driver lexor: Unmatched character: %c\n", yytext[0]); }
|
||||
|
||||
%%
|
||||
|
||||
void reset_lexor(FILE*fd)
|
||||
{
|
||||
yyrestart(fd);
|
||||
}
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
+329
-292
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2001 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2005 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,13 +16,30 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ident "$Id: main.c,v 1.52 2003/02/22 04:55:36 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: main.c,v 1.76 2007/06/05 01:56:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
const char NOTICE[] =
|
||||
" This program is free software; you can redistribute it and/or modify\n"
|
||||
" it under the terms of the GNU General Public License as published by\n"
|
||||
" the Free Software Foundation; either version 2 of the License, or\n"
|
||||
" (at your option) any later version.\n"
|
||||
"\n"
|
||||
" This program is distributed in the hope that it will be useful,\n"
|
||||
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
" GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
" You should have received a copy of the GNU General Public License\n"
|
||||
" along with this program; if not, write to the Free Software\n"
|
||||
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
|
||||
;
|
||||
|
||||
const char HELP[] =
|
||||
"Usage: iverilog [-ESvV] [-B base] [-C path] [-c cmdfile] [-g1|-g2|-g3.0]\n"
|
||||
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile] [-g1|-g2|-g2x]\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"
|
||||
@@ -72,6 +89,7 @@ extern const char*optarg;
|
||||
#endif
|
||||
|
||||
# include "globals.h"
|
||||
#include "cfparse_misc.h" /* cfparse() */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
const char sep = '\\';
|
||||
@@ -82,23 +100,23 @@ const char sep = '/';
|
||||
extern void cfreset(FILE*fd, const char*path);
|
||||
|
||||
const char*base = 0;
|
||||
const char*pbase = 0;
|
||||
const char*mtm = 0;
|
||||
const char*opath = "a.out";
|
||||
const char*npath = 0;
|
||||
const char*targ = "vvp";
|
||||
const char*depfile = 0;
|
||||
|
||||
const char*generation = "-g3.0";
|
||||
const char*generation = "2x";
|
||||
const char*gen_specify = "specify";
|
||||
const char*gen_xtypes = "xtypes";
|
||||
|
||||
char warning_flags[16] = "";
|
||||
|
||||
char*inc_list = 0;
|
||||
char*def_list = 0;
|
||||
unsigned integer_width = 32;
|
||||
|
||||
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
|
||||
@@ -107,12 +125,17 @@ char*source_path = 0;
|
||||
FILE*source_file = 0;
|
||||
unsigned source_count = 0;
|
||||
|
||||
char*defines_path = 0;
|
||||
FILE*defines_file = 0;
|
||||
|
||||
char*iconfig_path = 0;
|
||||
FILE*iconfig_file = 0;
|
||||
|
||||
static char iconfig_common_path_buf[4096] = "";
|
||||
char*iconfig_common_path = iconfig_common_path_buf;
|
||||
|
||||
int synth_flag = 0;
|
||||
int verbose_flag = 0;
|
||||
int command_file = 0;
|
||||
|
||||
FILE *fp;
|
||||
|
||||
@@ -121,6 +144,48 @@ char tmp[MAXSIZE];
|
||||
|
||||
static char ivl_root[MAXSIZE];
|
||||
|
||||
/* Structure to keep a FIFO list of the command files */
|
||||
typedef struct t_command_file {
|
||||
char *filename;
|
||||
struct t_command_file *next;
|
||||
} s_command_file, *p_command_file;
|
||||
p_command_file cmd_file_head = NULL; /* The FIFO head */
|
||||
p_command_file cmd_file_tail = NULL; /* The FIFO tail */
|
||||
|
||||
/* Function to add a comamnd file name to the FIFO. */
|
||||
void add_cmd_file(const char* filename)
|
||||
{
|
||||
p_command_file new;
|
||||
|
||||
new = (p_command_file) malloc(sizeof(s_command_file));
|
||||
new->filename = strdup(filename);
|
||||
new->next = NULL;
|
||||
if (cmd_file_head == NULL) {
|
||||
cmd_file_head = new;
|
||||
cmd_file_tail = new;
|
||||
} else {
|
||||
cmd_file_tail->next = new;
|
||||
cmd_file_tail = new;
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to return the top comamnd file name from the FIFO. */
|
||||
char *get_cmd_file()
|
||||
{
|
||||
char *filename;
|
||||
|
||||
if (cmd_file_head == NULL) filename = NULL;
|
||||
else {
|
||||
p_command_file head;
|
||||
|
||||
filename = cmd_file_head->filename;
|
||||
head = cmd_file_head;
|
||||
cmd_file_head = cmd_file_head->next;
|
||||
free(head);
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
@@ -194,40 +259,67 @@ static const char*my_tempfile(const char*str, FILE**fout)
|
||||
*/
|
||||
static int t_default(char*cmd, unsigned ncmd)
|
||||
{
|
||||
int rc;
|
||||
const char*pattern;
|
||||
unsigned rc;
|
||||
#ifdef __MINGW32__
|
||||
unsigned ncmd_start = ncmd;
|
||||
#endif
|
||||
|
||||
pattern = lookup_pattern("<ivl>");
|
||||
if (pattern == 0) {
|
||||
fprintf(stderr, "No such target: %s\n", targ);
|
||||
return -1;
|
||||
snprintf(tmp, sizeof tmp, " | %s/ivl", base);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
if (verbose_flag) {
|
||||
const char*vv = " -v";
|
||||
rc = strlen(vv);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, vv);
|
||||
ncmd += rc;
|
||||
}
|
||||
|
||||
tmp[0] = ' ';
|
||||
tmp[1] = '|';
|
||||
tmp[2] = ' ';
|
||||
rc = build_string(tmp+3, sizeof tmp - 3, pattern);
|
||||
cmd = realloc(cmd, ncmd+3+rc+1);
|
||||
if (npath != 0) {
|
||||
snprintf(tmp, sizeof tmp, " -N%s", npath);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
}
|
||||
|
||||
snprintf(tmp, sizeof tmp, " -C%s", iconfig_path);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
snprintf(tmp, sizeof tmp, " -C%s -- -", iconfig_common_path);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
{
|
||||
char *t;
|
||||
for (t = tmp; *t; t++)
|
||||
for (t = cmd+ncmd_start; *t; t++)
|
||||
{
|
||||
if (*t == '/') *t = '\\';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
|
||||
|
||||
if (verbose_flag)
|
||||
printf("translate: %s\n", cmd);
|
||||
|
||||
|
||||
rc = system(cmd);
|
||||
remove(source_path);
|
||||
remove(iconfig_path);
|
||||
if ( ! getenv("IVERILOG_ICONFIG")) {
|
||||
remove(source_path);
|
||||
remove(iconfig_path);
|
||||
remove(defines_path);
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
if (rc == 127) {
|
||||
fprintf(stderr, "Failed to execute: %s\n", cmd);
|
||||
@@ -247,9 +339,6 @@ static int t_default(char*cmd, unsigned ncmd)
|
||||
|
||||
static void process_warning_switch(const char*name)
|
||||
{
|
||||
if (warning_flags[0] == 0)
|
||||
strcpy(warning_flags, "-W");
|
||||
|
||||
if (strcmp(name,"all") == 0) {
|
||||
strcat(warning_flags, "ipt");
|
||||
|
||||
@@ -300,50 +389,55 @@ void process_library2_switch(const char *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);
|
||||
}
|
||||
fprintf(defines_file, "I:%s\n", 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);
|
||||
}
|
||||
fprintf(defines_file,"D:%s\n", name);
|
||||
}
|
||||
|
||||
void process_file_name(const char*name)
|
||||
/*
|
||||
* This function is called while processing a file name in a command
|
||||
* file, or a file name on the command line. Look to see if there is a
|
||||
* .sft suffix, and if so pass that as a sys_func file. Otherwise, it
|
||||
* is a Verilog source file to be written into the file list.
|
||||
*/
|
||||
void process_file_name(const char*name, int lib_flag)
|
||||
{
|
||||
fprintf(source_file, "%s\n", name);
|
||||
source_count += 1;
|
||||
if (strlen(name) > 4 && strcasecmp(".sft", name+strlen(name)-4) == 0) {
|
||||
fprintf(iconfig_file,"sys_func:%s\n", name);
|
||||
|
||||
} else {
|
||||
fprintf(source_file, "%s\n", name);
|
||||
source_count += 1;
|
||||
if (lib_flag)
|
||||
fprintf(iconfig_file,"library_file:%s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
int process_generation(const char*name)
|
||||
{
|
||||
if (strcmp(name,"1") == 0)
|
||||
generation = "-g1";
|
||||
generation = "1";
|
||||
|
||||
else if (strcmp(name,"2") == 0)
|
||||
generation = "-g2";
|
||||
generation = "2";
|
||||
|
||||
else if (strcmp(name,"3.0") == 0)
|
||||
generation = "-g3.0";
|
||||
else if (strcmp(name,"2x") == 0)
|
||||
generation = "2x";
|
||||
|
||||
else if (strcmp(name,"xtypes") == 0)
|
||||
gen_xtypes = "xtypes";
|
||||
|
||||
else if (strcmp(name,"no-xtypes") == 0)
|
||||
gen_xtypes = "no-xtypes";
|
||||
|
||||
else if (strcmp(name,"specify") == 0)
|
||||
gen_specify = "specify";
|
||||
|
||||
else if (strcmp(name,"no-specify") == 0)
|
||||
gen_specify = "no-specify";
|
||||
|
||||
else {
|
||||
fprintf(stderr, "Unknown/Unsupported Language generation "
|
||||
@@ -351,22 +445,37 @@ int process_generation(const char*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");
|
||||
" 2x -- Verilog with extensions\n"
|
||||
"Other generation flags:\n"
|
||||
" specify | no-specify\n"
|
||||
" xtypes | no-xtypes\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it exists add the SFT file for the given module.
|
||||
*/
|
||||
void add_sft_file(const char *module)
|
||||
{
|
||||
char *file;
|
||||
|
||||
file = (char *) malloc(strlen(base)+1+strlen(module)+4+1);
|
||||
sprintf(file, "%s%c%s.sft", base, sep, module);
|
||||
if (access(file, R_OK) == 0)
|
||||
fprintf(iconfig_file, "sys_func:%s\n", file);
|
||||
free(file);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char*config_path = 0;
|
||||
char*cmd;
|
||||
unsigned ncmd;
|
||||
int e_flag = 0;
|
||||
int version_flag = 0;
|
||||
int opt, idx, rc;
|
||||
char*cp;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
{ char * s;
|
||||
@@ -416,30 +525,61 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
defines_path = strdup(my_tempfile("ivrlg2", &defines_file));
|
||||
if (NULL == defines_file) {
|
||||
fprintf(stderr, "%s: Error opening temporary file %s\n",
|
||||
argv[0], defines_path);
|
||||
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
|
||||
|
||||
fclose(source_file);
|
||||
remove(source_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(defines_file, "D:__ICARUS__=1\n");
|
||||
|
||||
/* Create another temporary file for passing configuration
|
||||
information to ivl. */
|
||||
iconfig_path = strdup(my_tempfile("ivrlh", &iconfig_file));
|
||||
|
||||
if ( (iconfig_path = getenv("IVERILOG_ICONFIG")) ) {
|
||||
fprintf(stderr, "%s: IVERILOG_ICONFIG=%s\n",
|
||||
argv[0], iconfig_path);
|
||||
|
||||
iconfig_file = fopen(iconfig_path, "w");
|
||||
|
||||
} else {
|
||||
|
||||
iconfig_path = strdup(my_tempfile("ivrlh", &iconfig_file));
|
||||
}
|
||||
|
||||
if (NULL == iconfig_file) {
|
||||
fprintf(stderr, "%s: Error opening temporary file %s\n",
|
||||
argv[0], iconfig_path);
|
||||
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
|
||||
fclose(source_file);
|
||||
remove(source_path);
|
||||
|
||||
fclose(defines_file);
|
||||
remove(defines_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) {
|
||||
while ((opt = getopt(argc, argv, "B:c:D:Ef:g:hI:M:m:N::o:p:Ss:T:t:vVW:y:Y:")) != EOF) {
|
||||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
base = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
config_path = optarg;
|
||||
/* Undocumented feature: The preprocessor itself
|
||||
may be located at a different location. If the
|
||||
base starts with a 'P', set this special base
|
||||
instead of the main base. */
|
||||
if (optarg[0] == 'P') {
|
||||
pbase = optarg+1;
|
||||
} else {
|
||||
base=optarg;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
command_filename = malloc(strlen(optarg)+1);
|
||||
strcpy(command_filename, optarg);
|
||||
add_cmd_file(optarg);
|
||||
break;
|
||||
case 'D':
|
||||
process_define(optarg);
|
||||
@@ -450,17 +590,7 @@ int main(int argc, char **argv)
|
||||
case 'f':
|
||||
fprintf(stderr, "warning: The -f flag is moved to -p\n");
|
||||
case 'p':
|
||||
if (f_list == 0) {
|
||||
f_list = malloc(strlen(" -p")+strlen(optarg)+1);
|
||||
strcpy(f_list, " -p");
|
||||
strcat(f_list, optarg);
|
||||
} else {
|
||||
f_list = realloc(f_list, strlen(f_list) +
|
||||
strlen(" -p") +
|
||||
strlen(optarg) + 1);
|
||||
strcat(f_list, " -p");
|
||||
strcat(f_list, optarg);
|
||||
}
|
||||
fprintf(iconfig_file, "flag:%s\n", optarg);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
@@ -481,17 +611,8 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (mod_list == 0) {
|
||||
mod_list = malloc(strlen(" -m")+strlen(optarg)+1);
|
||||
strcpy(mod_list, " -m");
|
||||
strcat(mod_list, optarg);
|
||||
} else {
|
||||
mod_list = realloc(mod_list, strlen(mod_list)
|
||||
+ strlen(" -m")
|
||||
+ strlen(optarg) + 1);
|
||||
strcat(mod_list, " -m");
|
||||
strcat(mod_list, optarg);
|
||||
}
|
||||
fprintf(iconfig_file, "module:%s\n", optarg);
|
||||
add_sft_file(optarg);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
@@ -506,18 +627,7 @@ int main(int argc, char **argv)
|
||||
synth_flag = 1;
|
||||
break;
|
||||
case 's':
|
||||
if (start) {
|
||||
static const char *s = " -s ";
|
||||
size_t l = strlen(start);
|
||||
start = realloc(start, l + strlen(optarg) + strlen(s) + 1);
|
||||
strcpy(start + l, s);
|
||||
strcpy(start + l + strlen(s), optarg);
|
||||
} else {
|
||||
static const char *s = "-s ";
|
||||
start = malloc(strlen(optarg) + strlen(s) + 1);
|
||||
strcpy(start, s);
|
||||
strcpy(start + strlen(s), optarg);
|
||||
}
|
||||
fprintf(iconfig_file, "root:%s\n", optarg);
|
||||
break;
|
||||
case 'T':
|
||||
if (strcmp(optarg,"min") == 0) {
|
||||
@@ -556,16 +666,39 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (pbase == 0)
|
||||
pbase = base;
|
||||
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION "\n");
|
||||
printf("Copyright 1998-2002 Stephen Williams\n");
|
||||
printf("$Name: $\n");
|
||||
printf("Icarus Verilog version " VERSION " ($Name: $)\n");
|
||||
printf("Copyright 1998-2003 Stephen Williams\n");
|
||||
puts(NOTICE);
|
||||
|
||||
if (version_flag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (command_filename) {
|
||||
/* Make a common conf file path to reflect the target. */
|
||||
sprintf(iconfig_common_path, "%s%c%s%s.conf",
|
||||
base,sep, targ, synth_flag? "-s" : "");
|
||||
|
||||
/* Write values to the iconfig file. */
|
||||
fprintf(iconfig_file, "basedir:%s\n", base);
|
||||
|
||||
/* Tell the core where to find the system.sft. This file
|
||||
describes the system functions so that elaboration knows
|
||||
how to handle them. */
|
||||
fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
|
||||
|
||||
if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
|
||||
fprintf(iconfig_file, "generation:%s\n", generation);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_specify);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_xtypes);
|
||||
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
|
||||
fprintf(iconfig_file, "out:%s\n", opath);
|
||||
if (depfile) fprintf(iconfig_file, "depfile:%s\n", depfile);
|
||||
|
||||
while ( (command_filename = get_cmd_file()) ) {
|
||||
int rc;
|
||||
|
||||
if (( fp = fopen(command_filename, "r")) == NULL ) {
|
||||
@@ -581,71 +714,42 @@ int main(int argc, char **argv)
|
||||
command_filename);
|
||||
return 1;
|
||||
}
|
||||
free(command_filename);
|
||||
}
|
||||
|
||||
if (depfile) {
|
||||
fprintf(defines_file, "M:%s\n", depfile);
|
||||
}
|
||||
|
||||
/* 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]);
|
||||
process_file_name(argv[idx], 0);
|
||||
|
||||
|
||||
fclose(source_file);
|
||||
source_file = 0;
|
||||
|
||||
fclose(defines_file);
|
||||
defines_file = 0;
|
||||
|
||||
if (source_count == 0) {
|
||||
fprintf(stderr, "%s: No input files.\n", argv[0]);
|
||||
fprintf(stderr, "%s\n", HELP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Load the iverilog.conf file to get our substitution
|
||||
strings. */
|
||||
|
||||
{ char path[1024];
|
||||
FILE*fd;
|
||||
if (config_path) {
|
||||
strcpy(path, config_path);
|
||||
} else {
|
||||
sprintf(path, "%s%civerilog.conf", base,sep);
|
||||
}
|
||||
fd = fopen(path, "r");
|
||||
if (fd == 0) {
|
||||
fprintf(stderr, "Config file \"%s\" not found\n",path);
|
||||
return 1;
|
||||
}
|
||||
reset_lexor(fd);
|
||||
yyparse();
|
||||
}
|
||||
|
||||
/* Start building the preprocess command line. */
|
||||
|
||||
sprintf(tmp, "%s%civlpp %s%s -D__ICARUS__=1 -f%s ", base,sep,
|
||||
sprintf(tmp, "%s%civlpp %s%s -F%s -f%s ", pbase,sep,
|
||||
verbose_flag?" -v":"",
|
||||
e_flag?"":" -L", source_path);
|
||||
e_flag?"":" -L", defines_path, source_path);
|
||||
|
||||
ncmd = strlen(tmp);
|
||||
cmd = malloc(ncmd + 1);
|
||||
strcpy(cmd, tmp);
|
||||
|
||||
if (inc_list) {
|
||||
cmd = realloc(cmd, ncmd + strlen(inc_list) + 1);
|
||||
strcat(cmd, inc_list);
|
||||
ncmd += strlen(inc_list);
|
||||
}
|
||||
|
||||
if (def_list) {
|
||||
cmd = realloc(cmd, ncmd + strlen(def_list) + 1);
|
||||
strcat(cmd, def_list);
|
||||
ncmd += strlen(def_list);
|
||||
}
|
||||
|
||||
if (depfile) {
|
||||
cmd = realloc(cmd, ncmd + strlen(depfile) + 5);
|
||||
strcat(cmd, " -M ");
|
||||
strcat(cmd, depfile);
|
||||
ncmd += strlen(depfile) + 4;
|
||||
}
|
||||
|
||||
/* If the -E flag was given on the command line, then all we
|
||||
do is run the preprocessor and put the output where the
|
||||
user wants it. */
|
||||
@@ -664,7 +768,8 @@ int main(int argc, char **argv)
|
||||
rc = system(cmd);
|
||||
remove(source_path);
|
||||
fclose(iconfig_file);
|
||||
remove(iconfig_path);
|
||||
if ( ! getenv("IVERILOG_ICONFIG"))
|
||||
remove(iconfig_path);
|
||||
|
||||
if (rc != 0) {
|
||||
if (WIFEXITED(rc)) {
|
||||
@@ -679,13 +784,13 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(iconfig_file, "iwidth:%u\n", integer_width);
|
||||
|
||||
/* 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 : "");
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F%s\n",
|
||||
pbase, sep, defines_path);
|
||||
|
||||
/* Done writing to the iconfig file. Close it now. */
|
||||
fclose(iconfig_file);
|
||||
@@ -697,150 +802,82 @@ int main(int argc, char **argv)
|
||||
|
||||
/*
|
||||
* $Log: main.c,v $
|
||||
* Revision 1.76 2007/06/05 01:56:12 steve
|
||||
* Bring in .SFT file automatically if -m used.
|
||||
*
|
||||
* Revision 1.75 2007/04/19 02:52:53 steve
|
||||
* Add support for -v flag in command file.
|
||||
*
|
||||
* Revision 1.74 2007/04/18 03:23:38 steve
|
||||
* Add support for multiple command files. (Cary R.)
|
||||
*
|
||||
* Revision 1.73 2007/03/07 04:24:59 steve
|
||||
* Make integer width controllable.
|
||||
*
|
||||
* Revision 1.72 2006/10/02 18:15:47 steve
|
||||
* Fix handling of dep path in new argument passing method.
|
||||
*
|
||||
* Revision 1.71 2006/09/28 04:35:18 steve
|
||||
* Support selective control of specify and xtypes features.
|
||||
*
|
||||
* Revision 1.70 2006/09/20 22:30:52 steve
|
||||
* Do not pass -D__ICARUS__ to ivlpp.
|
||||
*
|
||||
* Revision 1.69 2006/07/26 00:11:40 steve
|
||||
* Pass depfiles through temp defines file.
|
||||
*
|
||||
* Revision 1.68 2006/07/26 00:02:48 steve
|
||||
* Pass defines and includes through temp file.
|
||||
*
|
||||
* Revision 1.67 2005/07/14 23:38:44 steve
|
||||
* Display as version 0.9.devel
|
||||
*
|
||||
* Revision 1.66 2005/06/28 04:25:55 steve
|
||||
* Remove reference to SystemVerilog.
|
||||
*
|
||||
* Revision 1.65 2004/06/17 14:47:22 steve
|
||||
* Add a .sft file for the system functions.
|
||||
*
|
||||
* Revision 1.64 2004/03/10 04:51:25 steve
|
||||
* Add support for system function table files.
|
||||
*
|
||||
* Revision 1.63 2004/02/15 18:03:30 steve
|
||||
* Cleanup of warnings.
|
||||
*
|
||||
* Revision 1.62 2003/12/12 04:36:48 steve
|
||||
* Fix make check to support -tconf configuration method.
|
||||
*
|
||||
* Revision 1.61 2003/11/18 06:31:46 steve
|
||||
* Remove the iverilog.conf file.
|
||||
*
|
||||
* Revision 1.60 2003/11/13 05:55:33 steve
|
||||
* Move the DLL= flag to target config files.
|
||||
*
|
||||
* Revision 1.59 2003/11/13 04:09:49 steve
|
||||
* Pass flags through the temporary config file.
|
||||
*
|
||||
* Revision 1.58 2003/11/01 04:21:57 steve
|
||||
* Add support for a target static config file.
|
||||
*
|
||||
* Revision 1.57 2003/10/26 22:43:42 steve
|
||||
* Improve -V messages,
|
||||
*
|
||||
* Revision 1.56 2003/09/26 21:25:58 steve
|
||||
* Warnings cleanup.
|
||||
*
|
||||
* Revision 1.55 2003/09/23 05:57:15 steve
|
||||
* Pass -m flag from driver via iconfig file.
|
||||
*
|
||||
* Revision 1.54 2003/09/22 01:12:09 steve
|
||||
* Pass more ivl arguments through the iconfig file.
|
||||
*
|
||||
* Revision 1.53 2003/08/26 16:26:02 steve
|
||||
* ifdef idents correctly.
|
||||
*
|
||||
* Revision 1.52 2003/02/22 04:55:36 steve
|
||||
* portbind adds p, not i, flag.
|
||||
*
|
||||
* Revision 1.51 2003/02/22 04:12:49 steve
|
||||
* Add the portbind warning.
|
||||
*
|
||||
* Revision 1.50 2003/01/10 19:01:04 steve
|
||||
* Only use libiberty.h if available.
|
||||
*
|
||||
* Revision 1.49 2002/12/04 03:26:59 steve
|
||||
* Mingw32 compatible temp file management.
|
||||
*
|
||||
* Revision 1.48 2002/12/04 02:29:36 steve
|
||||
* Use O_EXCL when opening temp files.
|
||||
*
|
||||
* Revision 1.47 2002/08/12 01:27:48 steve
|
||||
* Escape the backslash in the windows file name.
|
||||
*
|
||||
* Revision 1.46 2002/08/10 22:36:59 steve
|
||||
* No longer any nead for -rdynamic flag
|
||||
*
|
||||
* Revision 1.45 2002/08/10 22:27:13 steve
|
||||
* Kill links to vvm.
|
||||
*
|
||||
* Revision 1.44 2002/07/15 00:33:50 steve
|
||||
* Improve temporary file name guess.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
-167
@@ -1,167 +0,0 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse.y,v 1.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"
|
||||
|
||||
|
||||
void yyerror(const char*);
|
||||
|
||||
enum drive_code_t {
|
||||
CODE_S,
|
||||
CODE_t,
|
||||
};
|
||||
|
||||
struct drive_cond {
|
||||
struct drive_cond*next;
|
||||
enum drive_code_t code;
|
||||
char* text;
|
||||
};
|
||||
|
||||
static struct drive_cond *cur_cond = 0;
|
||||
|
||||
static void add_cond(enum drive_code_t code, char*text)
|
||||
{
|
||||
struct drive_cond*tmp;
|
||||
tmp = calloc(1, sizeof(struct drive_cond));
|
||||
tmp->code = code;
|
||||
tmp->text = text;
|
||||
|
||||
tmp->next = cur_cond;
|
||||
cur_cond = tmp;
|
||||
}
|
||||
|
||||
struct drive_pattern {
|
||||
struct drive_pattern*next;
|
||||
char*name;
|
||||
char*text;
|
||||
struct drive_cond*cond;
|
||||
};
|
||||
|
||||
static struct drive_pattern *patterns = 0;
|
||||
static struct drive_pattern *plast = 0;
|
||||
|
||||
static void add_pattern(char*name, char*text)
|
||||
{
|
||||
struct drive_pattern*tmp;
|
||||
tmp = calloc(1, sizeof(struct drive_pattern));
|
||||
tmp->name = name;
|
||||
tmp->text = text;
|
||||
tmp->cond = cur_cond;
|
||||
tmp->next = 0;
|
||||
|
||||
|
||||
if (plast) {
|
||||
plast->next = tmp;
|
||||
plast = tmp;
|
||||
} else {
|
||||
patterns = tmp;
|
||||
plast = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
const char*lookup_pattern(const char*key)
|
||||
{
|
||||
struct drive_pattern*cur;
|
||||
struct drive_cond*cc;
|
||||
|
||||
for (cur = patterns ; cur ; cur = cur->next) {
|
||||
|
||||
if (strcmp(key, cur->name) != 0)
|
||||
continue;
|
||||
|
||||
for (cc = cur->cond ; cc ; cc = cc->next) {
|
||||
|
||||
switch (cc->code) {
|
||||
case CODE_S:
|
||||
if (synth_flag)
|
||||
continue;
|
||||
break;
|
||||
case CODE_t:
|
||||
if (strcmp(targ, cc->text) == 0)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (cc) continue;
|
||||
|
||||
return cur->text;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char*text;
|
||||
};
|
||||
|
||||
%token <text> PATTERN_NAME PATTERN_TEXT
|
||||
%token <text> CT_t
|
||||
%token CT_S
|
||||
|
||||
%%
|
||||
|
||||
start: section_list ;
|
||||
|
||||
section_list
|
||||
: section
|
||||
| section_list section
|
||||
;
|
||||
|
||||
section : '[' ctoken_list ']' pattern_list { cur_cond = 0; } ;
|
||||
|
||||
ctoken_list
|
||||
: ctoken
|
||||
| ctoken_list ctoken
|
||||
;
|
||||
|
||||
ctoken : CT_S { add_cond(CODE_S, 0); }
|
||||
| CT_t { add_cond(CODE_t, $1); }
|
||||
;
|
||||
|
||||
pattern_list
|
||||
: pattern
|
||||
| pattern_list pattern
|
||||
;
|
||||
|
||||
pattern : PATTERN_NAME PATTERN_TEXT
|
||||
{ add_pattern($1, $2); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void yyerror(const char*msg)
|
||||
{
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
}
|
||||
+6
-3
@@ -17,7 +17,7 @@
|
||||
* 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 $"
|
||||
#ident "$Id: substit.c,v 1.5 2003/12/19 01:27:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string.h>
|
||||
@@ -66,7 +66,7 @@ char* substitutions(const char*str)
|
||||
cp += strlen(cp);
|
||||
|
||||
} else {
|
||||
if ( (cp - buf) == nbuf ) {
|
||||
if ( cp == (buf + nbuf) ) {
|
||||
size_t old_size = nbuf;
|
||||
nbuf = old_size + 32;
|
||||
buf = realloc(buf, nbuf);
|
||||
@@ -79,7 +79,7 @@ char* substitutions(const char*str)
|
||||
|
||||
/* Add the trailing nul to the string, and reallocate the
|
||||
buffer to be a tight fit. */
|
||||
if ( (cp - buf) == nbuf ) {
|
||||
if ( cp == (buf + nbuf) ) {
|
||||
size_t old_size = nbuf;
|
||||
nbuf = old_size + 1;
|
||||
buf = realloc(buf, nbuf);
|
||||
@@ -96,6 +96,9 @@ char* substitutions(const char*str)
|
||||
|
||||
/*
|
||||
* $Log: substit.c,v $
|
||||
* Revision 1.5 2003/12/19 01:27:10 steve
|
||||
* Fix various unsigned compare warnings.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
+33
-6
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: dup_expr.cc,v 1.15 2003/05/30 02:55:32 steve Exp $"
|
||||
#ident "$Id: dup_expr.cc,v 1.21 2006/11/04 06:10:13 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -67,7 +67,8 @@ NetEScope* NetEScope::dup_expr() const
|
||||
|
||||
NetESelect* NetESelect::dup_expr() const
|
||||
{
|
||||
return new NetESelect(expr_->dup_expr(), base_->dup_expr(),
|
||||
return new NetESelect(expr_->dup_expr(),
|
||||
base_? base_->dup_expr() : 0,
|
||||
expr_width());
|
||||
}
|
||||
|
||||
@@ -75,6 +76,8 @@ NetESFunc* NetESFunc::dup_expr() const
|
||||
{
|
||||
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms());
|
||||
assert(tmp);
|
||||
|
||||
tmp->cast_signed(has_sign());
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
||||
assert(tmp->parm(idx));
|
||||
tmp->parm(idx, tmp->parm(idx)->dup_expr());
|
||||
@@ -85,7 +88,7 @@ NetESFunc* NetESFunc::dup_expr() const
|
||||
|
||||
NetESignal* NetESignal::dup_expr() const
|
||||
{
|
||||
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
|
||||
NetESignal*tmp = new NetESignal(net_);
|
||||
assert(tmp);
|
||||
tmp->expr_width(expr_width());
|
||||
return tmp;
|
||||
@@ -109,8 +112,9 @@ NetEUFunc* NetEUFunc::dup_expr() const
|
||||
tmp_parms[idx] = parms_[idx]->dup_expr();
|
||||
}
|
||||
|
||||
tmp = new NetEUFunc(func_, result_->dup_expr(), tmp_parms);
|
||||
tmp = new NetEUFunc(func_, result_sig_->dup_expr(), tmp_parms);
|
||||
|
||||
assert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -121,14 +125,37 @@ NetEUnary* NetEUnary::dup_expr() const
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEVariable* NetEVariable::dup_expr() const
|
||||
NetEUReduce* NetEUReduce::dup_expr() const
|
||||
{
|
||||
NetEVariable*tmp = new NetEVariable(var_);
|
||||
NetEUReduce*tmp = new NetEUReduce(op_, expr_->dup_expr());
|
||||
assert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: dup_expr.cc,v $
|
||||
* Revision 1.21 2006/11/04 06:10:13 steve
|
||||
* Handle dup of pad as well as normal select.
|
||||
*
|
||||
* Revision 1.20 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
* Revision 1.19 2004/12/11 02:31:25 steve
|
||||
* Rework of internals to carry vectors through nexus instead
|
||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
||||
* down this path.
|
||||
*
|
||||
* Revision 1.18 2004/06/17 16:06:18 steve
|
||||
* Help system function signedness survive elaboration.
|
||||
*
|
||||
* Revision 1.17 2004/05/31 23:34:36 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.16 2003/10/31 02:47:11 steve
|
||||
* NetEUReduce has its own dup_expr method.
|
||||
*
|
||||
* Revision 1.15 2003/05/30 02:55:32 steve
|
||||
* Support parameters in real expressions and
|
||||
* as real expressions, and fix multiply and
|
||||
|
||||
+48
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected].com)
|
||||
* Copyright (c) 2000-2003 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_anet.cc,v 1.8 2003/06/21 01:21:43 steve Exp $"
|
||||
#ident "$Id: elab_anet.cc,v 1.13 2007/03/22 16:08:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include <iostream>
|
||||
|
||||
NetNet* PExpr::elaborate_anet(Design*des, NetScope*scope) const
|
||||
@@ -83,15 +84,18 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
|
||||
concat operator from least significant to most significant,
|
||||
which is opposite from how they are given in the list.
|
||||
|
||||
Allow for a repeat count other then 1 by repeating the
|
||||
Allow for a repeat count other than 1 by repeating the
|
||||
connect loop as many times as necessary. */
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT_REG, pins);
|
||||
/* Assume that all the data types are the same. */
|
||||
osig->data_type(nets[0]->data_type());
|
||||
|
||||
pins = 0;
|
||||
for (unsigned idx = nets.count() ; idx > 0 ; idx -= 1) {
|
||||
NetNet*cur = nets[idx-1];
|
||||
assert(cur->data_type() == osig->data_type());
|
||||
for (unsigned pin = 0; pin < cur->pin_count(); pin += 1) {
|
||||
connect(osig->pin(pins), cur->pin(pin));
|
||||
pins += 1;
|
||||
@@ -104,17 +108,33 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet*sig = des->find_signal(scope, path_);
|
||||
assert(scope);
|
||||
|
||||
NetNet* sig = 0;
|
||||
NetMemory* mem = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
symbol_search(des, scope, path_, sig, mem, par, eve);
|
||||
|
||||
|
||||
if (mem != 0) {
|
||||
cerr << get_line() << ": error: memories not allowed "
|
||||
<< "on left side of procedural continuous "
|
||||
<< "assignment." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (eve != 0) {
|
||||
cerr << get_line() << ": error: named events not allowed "
|
||||
<< "on left side of procedural continuous "
|
||||
<< "assignment." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sig == 0) {
|
||||
if (des->find_memory(scope, path_)) {
|
||||
cerr << get_line() << ": error: memories not allowed "
|
||||
<< "on left side of procedural continuous "
|
||||
<< "assignment." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cerr << get_line() << ": error: reg ``" << path_ << "'' "
|
||||
<< "is undefined in this scope." << endl;
|
||||
des->errors += 1;
|
||||
@@ -139,7 +159,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
cerr << get_line() << ": error: bit/part selects not allowed "
|
||||
<< "on left side of procedural continuous assignment."
|
||||
<< endl;
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -149,6 +169,21 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_anet.cc,v $
|
||||
* Revision 1.13 2007/03/22 16:08:14 steve
|
||||
* Spelling fixes from Larry
|
||||
*
|
||||
* Revision 1.12 2006/05/01 20:47:58 steve
|
||||
* More explicit datatype setup.
|
||||
*
|
||||
* Revision 1.11 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
* Revision 1.10 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.9 2003/09/19 03:50:12 steve
|
||||
* Remove find_memory method from Design class.
|
||||
*
|
||||
* Revision 1.8 2003/06/21 01:21:43 steve
|
||||
* Harmless fixup of warnings.
|
||||
*
|
||||
|
||||
+1286
-403
File diff suppressed because it is too large
Load Diff
+310
-178
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2006 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
|
||||
@@ -17,15 +17,17 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_lval.cc,v 1.26 2003/01/27 05:09:17 steve Exp $"
|
||||
#ident "$Id: elab_lval.cc,v 1.44 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
|
||||
# include "netmisc.h"
|
||||
# include "compiler.h"
|
||||
# include <iostream>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
/*
|
||||
* These methods generate a NetAssign_ object for the l-value of the
|
||||
@@ -39,7 +41,7 @@
|
||||
* If there is a part select (i.e., foo[3:1] <= <value>) the NetAssign_
|
||||
* is made only as wide as it needs to be (3 bits in this example) and
|
||||
* connected to the correct bits of foo. A constant bit select is a
|
||||
* special case of the part select.
|
||||
* special case of the part select.
|
||||
*
|
||||
* If the bit-select is non-constant (i.e., foo[<expr>] = <value>) the
|
||||
* NetAssign_ is made wide enough to connect to all the bits of foo,
|
||||
@@ -65,7 +67,9 @@
|
||||
* is to try to make a net elaboration, and see if the result is
|
||||
* suitable for assignment.
|
||||
*/
|
||||
NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
|
||||
NetAssign_* PExpr::elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_force) const
|
||||
{
|
||||
NetNet*ll = 0;
|
||||
if (ll == 0) {
|
||||
@@ -91,7 +95,9 @@ NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
|
||||
* a is the MSB and b the LSB. Connect the LSB to the low pins of the
|
||||
* NetAssign_ object.
|
||||
*/
|
||||
NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
|
||||
NetAssign_* PEConcat::elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_force) const
|
||||
{
|
||||
if (repeat_) {
|
||||
cerr << get_line() << ": error: Repeat concatenations make "
|
||||
@@ -111,7 +117,7 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
|
||||
continue;
|
||||
}
|
||||
|
||||
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope);
|
||||
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force);
|
||||
|
||||
/* If the l-value doesn't elaborate, the error was
|
||||
already detected and printed. We just skip it and let
|
||||
@@ -138,41 +144,72 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
|
||||
/*
|
||||
* Handle the ident as an l-value. This includes bit and part selects
|
||||
* of that ident.
|
||||
*
|
||||
* XXXX FIXME: The search order looks for signals all the way up the
|
||||
* scope tree, then looks for memories then variables. It should be
|
||||
* looking for signals, memories and variables in parallel.
|
||||
*/
|
||||
NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_force) const
|
||||
{
|
||||
NetNet*reg = des->find_signal(scope, path_);
|
||||
NetNet* reg = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
symbol_search(des, scope, path_, reg, par, eve);
|
||||
if (reg == 0) {
|
||||
if (NetMemory*mem = des->find_memory(scope, path_)) {
|
||||
return elaborate_mem_lval_(des, scope, mem);
|
||||
}
|
||||
|
||||
if (NetVariable*var = des->find_variable(scope, path_)) {
|
||||
NetAssign_*cur = new NetAssign_(var);
|
||||
return cur;
|
||||
}
|
||||
|
||||
cerr << get_line() << ": error: Could not find variable ``"
|
||||
<< path_ << "'' in ``" << scope->name() <<
|
||||
<< path_ << "'' in ``" << scope_path(scope) <<
|
||||
"''" << endl;
|
||||
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(reg);
|
||||
ivl_assert(*this, reg);
|
||||
|
||||
const name_component_t&name_tail = path_.back();
|
||||
|
||||
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||
if (!name_tail.index.empty())
|
||||
use_sel = name_tail.index.back().sel;
|
||||
|
||||
// This is the special case that the l-value is an entire
|
||||
// memory. This is, in fact, an error.
|
||||
if (reg->array_dimensions() > 0 && name_tail.index.empty()) {
|
||||
cerr << get_line() << ": error: Cannot assign to array "
|
||||
<< path_ << ". Did you forget a word index?" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reg->array_dimensions() > 0)
|
||||
return elaborate_lval_net_word_(des, scope, reg);
|
||||
|
||||
if (use_sel == index_component_t::SEL_PART) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_part_(des, scope, lv);
|
||||
return lv;
|
||||
}
|
||||
|
||||
if (use_sel == index_component_t::SEL_IDX_UP) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_idx_up_(des, scope, lv);
|
||||
return lv;
|
||||
}
|
||||
|
||||
if (use_sel == index_component_t::SEL_IDX_DO) {
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
elaborate_lval_net_idx_do_(des, scope, lv);
|
||||
return lv;
|
||||
}
|
||||
|
||||
/* Get the signal referenced by the identifier, and make sure
|
||||
it is a register. (Wires are not allows in this context. */
|
||||
if (reg->type() != NetNet::REG) {
|
||||
it is a register. Wires are not allows in this context,
|
||||
unless this is the l-value of a force. */
|
||||
if ((reg->type() != NetNet::REG) && !is_force) {
|
||||
cerr << get_line() << ": error: " << path_ <<
|
||||
" is not a reg/integer/time in " << scope->name() <<
|
||||
" is not a valid l-value in " << scope_path(scope) <<
|
||||
"." << endl;
|
||||
cerr << reg->get_line() << ": : " << path_ <<
|
||||
" is declared here as " << reg->type() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -180,57 +217,29 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
long msb, lsb;
|
||||
NetExpr*mux;
|
||||
|
||||
if (msb_ && lsb_) {
|
||||
/* This handles part selects. In this case, there are
|
||||
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);
|
||||
if (vl == 0) {
|
||||
cerr << lsb_->get_line() << ": error: "
|
||||
"Part select expressions must be constant."
|
||||
<< endl;
|
||||
cerr << lsb_->get_line() << ": : This lsb expression "
|
||||
"violates the rule: " << *lsb_ << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
verinum*vm = msb_->eval_const(des, scope);
|
||||
if (vm == 0) {
|
||||
cerr << msb_->get_line() << ": error: "
|
||||
"Part select expressions must be constant."
|
||||
<< endl;
|
||||
cerr << msb_->get_line() << ": : This msb expression "
|
||||
"violates the rule: " << *msb_ << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
if (use_sel == index_component_t::SEL_BIT) {
|
||||
|
||||
msb = vm->as_long();
|
||||
lsb = vl->as_long();
|
||||
mux = 0;
|
||||
|
||||
} else if (msb_) {
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
ivl_assert(*this, index_tail.msb != 0);
|
||||
ivl_assert(*this, index_tail.lsb == 0);
|
||||
|
||||
/* If there is only a single select expression, it is a
|
||||
bit select. Evaluate the constant value and treat it
|
||||
as a part select with a bit width of 1. If the
|
||||
expression it not constant, then return the
|
||||
expression as a mux. */
|
||||
assert(lsb_ == 0);
|
||||
verinum*v = msb_->eval_const(des, scope);
|
||||
if (v == 0) {
|
||||
NetExpr*m = msb_->elaborate_expr(des, scope);
|
||||
assert(m);
|
||||
msb = 0;
|
||||
lsb = 0;
|
||||
mux = m;
|
||||
|
||||
NetExpr*index_expr = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
|
||||
if (NetEConst*index_con = dynamic_cast<NetEConst*> (index_expr)) {
|
||||
msb = index_con->value().as_long();
|
||||
lsb = index_con->value().as_long();
|
||||
mux = 0;
|
||||
|
||||
} else {
|
||||
|
||||
msb = v->as_long();
|
||||
lsb = v->as_long();
|
||||
mux = 0;
|
||||
msb = 0;
|
||||
lsb = 0;
|
||||
mux = index_expr;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -238,8 +247,6 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
/* No select expressions, so presume a part select the
|
||||
width of the register. */
|
||||
|
||||
assert(msb_ == 0);
|
||||
assert(lsb_ == 0);
|
||||
msb = reg->msb();
|
||||
lsb = reg->lsb();
|
||||
mux = 0;
|
||||
@@ -254,7 +261,19 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
bmux to select the target bit. */
|
||||
lv = new NetAssign_(reg);
|
||||
|
||||
lv->set_bmux(mux);
|
||||
/* Correct the mux for the range of the vector. */
|
||||
if (reg->msb() < reg->lsb())
|
||||
mux = make_sub_expr(reg->lsb(), mux);
|
||||
else if (reg->lsb() != 0)
|
||||
mux = make_add_expr(mux, - reg->lsb());
|
||||
|
||||
lv->set_part(mux, 1);
|
||||
|
||||
} else if (msb == reg->msb() && lsb == reg->lsb()) {
|
||||
|
||||
/* No bit select, and part select covers the entire
|
||||
vector. Simplest case. */
|
||||
lv = new NetAssign_(reg);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -278,7 +297,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
converted to normalized form so is relative the
|
||||
variable pins. */
|
||||
|
||||
if ((wid + loff) > reg->pin_count()) {
|
||||
if ((wid + loff) > reg->vector_width()) {
|
||||
cerr << get_line() << ": error: bit/part select "
|
||||
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
|
||||
<< " is out of range." << endl;
|
||||
@@ -287,57 +306,191 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
lv = new NetAssign_(reg);
|
||||
lv->set_part(loff, wid);
|
||||
|
||||
assert(moff < reg->pin_count());
|
||||
lv->set_part(new NetEConst(verinum(loff)), wid);
|
||||
}
|
||||
|
||||
|
||||
return lv;
|
||||
}
|
||||
|
||||
NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope,
|
||||
NetMemory*mem) const
|
||||
NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
||||
NetScope*scope,
|
||||
NetNet*reg) const
|
||||
{
|
||||
if (msb_ == 0) {
|
||||
cerr << get_line() << ": error: Assign to memory \""
|
||||
<< mem->name() << "\" requires a word select index."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
const name_component_t&name_tail = path_.back();
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
|
||||
if (msb_ && lsb_) {
|
||||
cerr << get_line() << ": error: Cannot use part select on "
|
||||
<< "memory \"" << mem->name() << ".\"" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
const index_component_t&index_head = name_tail.index.front();
|
||||
ivl_assert(*this, index_head.sel == index_component_t::SEL_BIT);
|
||||
ivl_assert(*this, index_head.msb != 0);
|
||||
ivl_assert(*this, index_head.lsb == 0);
|
||||
|
||||
assert(msb_ && !lsb_);
|
||||
NetExpr*word = elab_and_eval(des, scope, index_head.msb, -1);
|
||||
|
||||
NetExpr*ix = msb_->elaborate_expr(des, scope);
|
||||
if (ix == 0)
|
||||
return 0;
|
||||
// If there is a non-zero base to the memory, then build an
|
||||
// expression to calculate the canonical address.
|
||||
if (long base = reg->array_first()) {
|
||||
|
||||
/* Evaluate the memory index expression down as must as
|
||||
possible. Ideally, we can get it down to a constant. */
|
||||
if (! dynamic_cast<NetEConst*>(ix)) {
|
||||
NetExpr*tmp = ix->eval_tree();
|
||||
if (tmp) {
|
||||
tmp->set_line(*ix);
|
||||
delete ix;
|
||||
ix = tmp;
|
||||
word = make_add_expr(word, 0-base);
|
||||
if (NetExpr*tmp = word->eval_tree()) {
|
||||
word = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
NetAssign_*lv = new NetAssign_(mem);
|
||||
lv->set_bmux(ix);
|
||||
lv->set_part(0, mem->width());
|
||||
NetAssign_*lv = new NetAssign_(reg);
|
||||
lv->set_word(word);
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: Set array word=" << *word << endl;
|
||||
|
||||
// Test for the case that the index is a constant, and is out
|
||||
// of bounds. The "word" expression is the word index already
|
||||
// converted to canonical address, so this just needs to check
|
||||
// that the address is not too big.
|
||||
if (NetEConst*word_const = dynamic_cast<NetEConst*>(word)) {
|
||||
verinum word_val = word_const->value();
|
||||
long index = word_val.as_long();
|
||||
if (index < 0 || index >= reg->array_count()) {
|
||||
cerr << get_line() << ": warning: Constant array index "
|
||||
<< (index + reg->array_first())
|
||||
<< " is out of range for array "
|
||||
<< reg->name() << "." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* An array word may also have part selects applied to them. */
|
||||
|
||||
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||
if (name_tail.index.size() > 1)
|
||||
use_sel = name_tail.index.back().sel;
|
||||
|
||||
if (use_sel == index_component_t::SEL_PART)
|
||||
elaborate_lval_net_part_(des, scope, lv);
|
||||
|
||||
if (use_sel == index_component_t::SEL_IDX_UP)
|
||||
elaborate_lval_net_idx_up_(des, scope, lv);
|
||||
|
||||
if (use_sel == index_component_t::SEL_IDX_DO)
|
||||
elaborate_lval_net_idx_do_(des, scope, lv);
|
||||
|
||||
return lv;
|
||||
}
|
||||
|
||||
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
|
||||
bool PEIdent::elaborate_lval_net_part_(Design*des,
|
||||
NetScope*scope,
|
||||
NetAssign_*lv) const
|
||||
{
|
||||
long msb, lsb;
|
||||
bool flag = calculate_parts_(des, scope, msb, lsb);
|
||||
if (!flag)
|
||||
return false;
|
||||
|
||||
NetNet*reg = lv->sig();
|
||||
assert(reg);
|
||||
|
||||
if (msb == reg->msb() && lsb == reg->lsb()) {
|
||||
|
||||
/* No bit select, and part select covers the entire
|
||||
vector. Simplest case. */
|
||||
|
||||
} else {
|
||||
|
||||
/* If the bit/part select is constant, then make the
|
||||
NetAssign_ only as wide as it needs to be and connect
|
||||
only to the selected bits of the reg. */
|
||||
unsigned loff = reg->sb_to_idx(lsb);
|
||||
unsigned moff = reg->sb_to_idx(msb);
|
||||
unsigned wid = moff - loff + 1;
|
||||
|
||||
if (moff < loff) {
|
||||
cerr << get_line() << ": error: part select "
|
||||
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
|
||||
<< " is reversed." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 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->vector_width()) {
|
||||
cerr << get_line() << ": error: bit/part select "
|
||||
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
|
||||
<< " is out of range." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
lv->set_part(new NetEConst(verinum(loff)), wid);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PEIdent::elaborate_lval_net_idx_up_(Design*des,
|
||||
NetScope*scope,
|
||||
NetAssign_*lv) const
|
||||
{
|
||||
const name_component_t&name_tail = path_.back();;
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
ivl_assert(*this, index_tail.msb != 0);
|
||||
ivl_assert(*this, index_tail.lsb != 0);
|
||||
|
||||
NetNet*reg = lv->sig();
|
||||
assert(reg);
|
||||
|
||||
if (reg->type() != NetNet::REG) {
|
||||
cerr << get_line() << ": error: " << path_ <<
|
||||
" is not a reg/integer/time in " << scope_path(scope) <<
|
||||
"." << endl;
|
||||
cerr << reg->get_line() << ": : " << path_ <<
|
||||
" is declared here as " << reg->type() << "." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long wid;
|
||||
calculate_up_do_width_(des, scope, wid);
|
||||
|
||||
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
|
||||
/* Correct the mux for the range of the vector. */
|
||||
if (reg->msb() < reg->lsb())
|
||||
base = make_sub_expr(reg->lsb(), base);
|
||||
else if (reg->lsb() != 0)
|
||||
base = make_add_expr(base, - reg->lsb());
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: Set part select width="
|
||||
<< wid << ", base=" << *base << endl;
|
||||
|
||||
lv->set_part(base, wid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PEIdent::elaborate_lval_net_idx_do_(Design*des,
|
||||
NetScope*scope,
|
||||
NetAssign_*lv) const
|
||||
{
|
||||
const name_component_t&name_tail = path_.back();;
|
||||
ivl_assert(*this, !name_tail.index.empty());
|
||||
|
||||
const index_component_t&index_tail = name_tail.index.back();
|
||||
ivl_assert(*this, index_tail.msb != 0);
|
||||
ivl_assert(*this, index_tail.lsb != 0);
|
||||
|
||||
cerr << get_line() << ": internal error: don't know how to "
|
||||
"deal with SEL_IDX_DO in lval?" << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*, bool) const
|
||||
{
|
||||
cerr << get_line() << ": error: Constant values not allowed "
|
||||
<< "in l-value expressions." << endl;
|
||||
@@ -347,94 +500,73 @@ NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
|
||||
|
||||
/*
|
||||
* $Log: elab_lval.cc,v $
|
||||
* Revision 1.26 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
* Revision 1.44 2007/06/02 03:42:12 steve
|
||||
* Properly evaluate scope path expressions.
|
||||
*
|
||||
* Revision 1.25 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
* Revision 1.43 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.24 2003/01/19 00:35:39 steve
|
||||
* Detect null arguments to concatenation operator.
|
||||
* Revision 1.42 2007/03/14 05:06:49 steve
|
||||
* Replace some asserts with ivl_asserts.
|
||||
*
|
||||
* Revision 1.23 2002/11/21 23:27:51 steve
|
||||
* Precalculate indices to l-value arrays.
|
||||
* Revision 1.41 2007/03/05 05:59:10 steve
|
||||
* Handle processes within generate loops.
|
||||
*
|
||||
* Revision 1.22 2002/11/21 18:15:40 steve
|
||||
* Fix const test of msb in assignment l-values.
|
||||
* Revision 1.40 2007/02/27 05:14:38 steve
|
||||
* Detect and warn about lval array index out fo bounds.
|
||||
*
|
||||
* Revision 1.21 2002/11/02 01:10:49 steve
|
||||
* Detect memories without work index in l-value.
|
||||
* Revision 1.39 2007/02/01 05:25:26 steve
|
||||
* Error message better reflects more general reality.
|
||||
*
|
||||
* Revision 1.20 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
* Revision 1.38 2007/01/16 05:44:15 steve
|
||||
* Major rework of array handling. Memories are replaced with the
|
||||
* more general concept of arrays. The NetMemory and NetEMemory
|
||||
* classes are removed from the ivl core program, and the IVL_LPM_RAM
|
||||
* lpm type is removed from the ivl_target API.
|
||||
*
|
||||
* 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.37 2006/11/04 06:19:25 steve
|
||||
* Remove last bits of relax_width methods, and use test_width
|
||||
* to calculate the width of an r-value expression that may
|
||||
* contain unsized numbers.
|
||||
*
|
||||
* Revision 1.18 2002/03/09 04:02:26 steve
|
||||
* Constant expressions are not l-values for task ports.
|
||||
* Revision 1.36 2006/06/02 04:48:50 steve
|
||||
* Make elaborate_expr methods aware of the width that the context
|
||||
* requires of it. In the process, fix sizing of the width of unary
|
||||
* minus is context determined sizes.
|
||||
*
|
||||
* 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.35 2006/04/16 00:54:04 steve
|
||||
* Cleanup lval part select handling.
|
||||
*
|
||||
* Revision 1.16 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
* Revision 1.34 2006/04/16 00:15:43 steve
|
||||
* Fix part selects in l-values.
|
||||
*
|
||||
* Revision 1.15 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
* Revision 1.33 2006/02/02 02:43:57 steve
|
||||
* Allow part selects of memory words in l-values.
|
||||
*
|
||||
* 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.
|
||||
* Revision 1.32 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
* Revision 1.31 2004/12/29 23:55:43 steve
|
||||
* Unify elaboration of l-values for all proceedural assignments,
|
||||
* including assing, cassign and force.
|
||||
*
|
||||
* 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)
|
||||
* Generate NetConcat devices for gate outputs that feed into a
|
||||
* vector results. Use this to hande gate arrays. Also let gate
|
||||
* arrays handle vectors of gates when the outputs allow for it.
|
||||
*
|
||||
* Revision 1.12 2001/02/09 03:16:48 steve
|
||||
* Report bit/part select out of range errors. (PR#133)
|
||||
* Revision 1.30 2004/12/11 02:31:25 steve
|
||||
* Rework of internals to carry vectors through nexus instead
|
||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
||||
* down this path.
|
||||
*
|
||||
* Revision 1.11 2001/01/10 03:13:23 steve
|
||||
* Build task outputs as lval instead of nets. (PR#98)
|
||||
* Revision 1.29 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.10 2001/01/06 06:31:58 steve
|
||||
* declaration initialization for time variables.
|
||||
*
|
||||
* Revision 1.9 2001/01/06 02:29:36 steve
|
||||
* Support arrays of integers.
|
||||
*
|
||||
* Revision 1.8 2000/12/12 06:14:51 steve
|
||||
* sorry for concatenated memories in l-values. (PR#76)
|
||||
*
|
||||
* Revision 1.7 2000/12/01 02:55:37 steve
|
||||
* Detect part select errors on l-values.
|
||||
*
|
||||
* Revision 1.6 2000/10/31 17:49:02 steve
|
||||
* Support time variables.
|
||||
*
|
||||
* Revision 1.5 2000/10/26 17:09:46 steve
|
||||
* Fix handling of errors in behavioral lvalues. (PR#28)
|
||||
*
|
||||
* Revision 1.4 2000/09/10 15:43:59 steve
|
||||
* Some error checking.
|
||||
*
|
||||
* Revision 1.3 2000/09/10 03:59:59 steve
|
||||
* Agressively merge NetAssign_ within concatenations.
|
||||
*
|
||||
* Revision 1.2 2000/09/10 02:18:16 steve
|
||||
* elaborate complex l-values
|
||||
*
|
||||
* Revision 1.1 2000/09/09 15:21:26 steve
|
||||
* move lval elaboration to PExpr virtual methods.
|
||||
* Revision 1.28 2004/08/28 14:59:44 steve
|
||||
* More detailed error message about bad variable.
|
||||
*
|
||||
* Revision 1.27 2003/09/19 03:30:05 steve
|
||||
* Fix name search in elab_lval.
|
||||
*/
|
||||
|
||||
|
||||
+1889
-1074
File diff suppressed because it is too large
Load Diff
+62
-19
@@ -17,13 +17,15 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_pexpr.cc,v 1.20 2003/05/30 02:55:32 steve Exp $"
|
||||
#ident "$Id: elab_pexpr.cc,v 1.28 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "compiler.h"
|
||||
# include "util.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
@@ -52,7 +54,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp);
|
||||
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp, -1);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -118,7 +120,7 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
|
||||
NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
return elaborate_expr(des, scope);
|
||||
return elaborate_expr(des, scope, -1, false);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -129,41 +131,53 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
*/
|
||||
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
hname_t path = path_;
|
||||
char*name = path.remove_tail_name();
|
||||
pform_name_t path = path_;
|
||||
name_component_t name_tail = path_.back();
|
||||
path.pop_back();
|
||||
|
||||
NetScope*pscope = scope;
|
||||
if (path.peek_name(0))
|
||||
pscope = des->find_scope(scope, path);
|
||||
if (path_.size() > 0) {
|
||||
list<hname_t> tmp = eval_scope_path(des, scope, path);
|
||||
pscope = des->find_scope(scope, tmp);
|
||||
}
|
||||
|
||||
const NetExpr*ex = pscope->get_parameter(name);
|
||||
const NetExpr*ex_msb;
|
||||
const NetExpr*ex_lsb;
|
||||
const NetExpr*ex = pscope->get_parameter(name_tail.name, ex_msb, ex_lsb);
|
||||
if (ex == 0) {
|
||||
cerr << get_line() << ": error: identifier ``" << path_ <<
|
||||
"'' is not a parameter in " << scope->name() << "." << endl;
|
||||
cerr << get_line() << ": error: identifier ``" << name_tail.name <<
|
||||
"'' is not a parameter in "<< scope_path(scope)<< "." << endl;
|
||||
des->errors += 1;
|
||||
delete name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
|
||||
NetExpr*res = new NetEParam(des, pscope, name_tail.name);
|
||||
res->set_line(*this);
|
||||
assert(res);
|
||||
delete name;
|
||||
|
||||
assert(idx_ == 0);
|
||||
if (msb_ && lsb_) {
|
||||
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||
if (!name_tail.index.empty())
|
||||
use_sel = name_tail.index.back().sel;
|
||||
|
||||
switch (use_sel) {
|
||||
case index_component_t::SEL_NONE:
|
||||
break;
|
||||
default:
|
||||
case index_component_t::SEL_PART:
|
||||
cerr << get_line() << ": sorry: Cannot part select "
|
||||
"bits of parameters." << endl;
|
||||
des->errors += 1;
|
||||
break;
|
||||
|
||||
} else if (msb_) {
|
||||
case index_component_t::SEL_BIT:
|
||||
|
||||
/* We have here a bit select. Insert a NetESelect node
|
||||
to handle it. */
|
||||
NetExpr*tmp = msb_->elaborate_pexpr(des, scope);
|
||||
NetExpr*tmp = name_tail.index.back().msb->elaborate_pexpr(des, scope);
|
||||
if (tmp != 0) {
|
||||
res = new NetESelect(res, tmp, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -174,13 +188,13 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
*/
|
||||
NetExpr*PENumber::elaborate_pexpr(Design*des, NetScope*sc) const
|
||||
{
|
||||
return elaborate_expr(des, sc);
|
||||
return elaborate_expr(des, sc, -1, false);
|
||||
}
|
||||
|
||||
|
||||
NetEConst* PEString::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
return elaborate_expr(des, scope);
|
||||
return elaborate_expr(des, scope, -1, false);
|
||||
}
|
||||
|
||||
NetETernary* PETernary::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
@@ -229,6 +243,35 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_pexpr.cc,v $
|
||||
* Revision 1.28 2007/06/02 03:42:12 steve
|
||||
* Properly evaluate scope path expressions.
|
||||
*
|
||||
* Revision 1.27 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.26 2007/04/26 03:06:22 steve
|
||||
* Rework hname_t to use perm_strings.
|
||||
*
|
||||
* Revision 1.25 2006/11/04 06:19:25 steve
|
||||
* Remove last bits of relax_width methods, and use test_width
|
||||
* to calculate the width of an r-value expression that may
|
||||
* contain unsized numbers.
|
||||
*
|
||||
* Revision 1.24 2006/06/02 04:48:50 steve
|
||||
* Make elaborate_expr methods aware of the width that the context
|
||||
* requires of it. In the process, fix sizing of the width of unary
|
||||
* minus is context determined sizes.
|
||||
*
|
||||
* Revision 1.23 2006/02/02 02:43:58 steve
|
||||
* Allow part selects of memory words in l-values.
|
||||
*
|
||||
* Revision 1.22 2005/11/27 05:56:20 steve
|
||||
* Handle bit select of parameter with ranges.
|
||||
*
|
||||
* Revision 1.21 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.20 2003/05/30 02:55:32 steve
|
||||
* Support parameters in real expressions and
|
||||
* as real expressions, and fix multiply and
|
||||
|
||||
+393
-120
@@ -17,12 +17,14 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_scope.cc,v 1.25 2003/06/24 01:38:02 steve Exp $"
|
||||
#ident "$Id: elab_scope.cc,v 1.46 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "compiler.h"
|
||||
# include "netmisc.h"
|
||||
# include <iostream>
|
||||
# include <stdio.h>
|
||||
|
||||
/*
|
||||
* Elaboration happens in two passes, generally. The first scans the
|
||||
@@ -32,10 +34,10 @@
|
||||
*/
|
||||
|
||||
# include "Module.h"
|
||||
# include "PData.h"
|
||||
# include "PEvent.h"
|
||||
# include "PExpr.h"
|
||||
# include "PGate.h"
|
||||
# include "PGenerate.h"
|
||||
# include "PTask.h"
|
||||
# include "PWire.h"
|
||||
# include "Statement.h"
|
||||
@@ -44,8 +46,14 @@
|
||||
# include <typeinfo>
|
||||
# include <assert.h>
|
||||
|
||||
bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||
const replace_t&replacements) const
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << get_line() << ": debug: Elaborate scope "
|
||||
<< scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
// Generate all the parameters that this instance of this
|
||||
// module introduces to the design. This loop elaborates the
|
||||
// parameters, but doesn't evaluate references to
|
||||
@@ -57,8 +65,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,param_expr_t>::const_iterator mparm_it_t;
|
||||
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
|
||||
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
|
||||
typedef map<pform_name_t,PExpr*>::const_iterator pform_parm_it_t;
|
||||
|
||||
|
||||
// This loop scans the parameters in the module, and creates
|
||||
@@ -69,8 +77,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
NetEParam*tmp = new NetEParam;
|
||||
tmp->set_line(*((*cur).second.expr));
|
||||
if ((*cur).second.msb)
|
||||
tmp->cast_signed( (*cur).second.signed_flag );
|
||||
tmp->cast_signed( (*cur).second.signed_flag );
|
||||
|
||||
scope->set_parameter((*cur).first, tmp, 0, 0, false);
|
||||
}
|
||||
@@ -98,6 +105,67 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
PExpr*ex = (*cur).second.expr;
|
||||
assert(ex);
|
||||
|
||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||
NetExpr*msb = 0;
|
||||
NetExpr*lsb = 0;
|
||||
bool signed_flag = (*cur).second.signed_flag;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
if (signed_flag) {
|
||||
/* If explicitly signed, then say so. */
|
||||
val->cast_signed(true);
|
||||
} else if ((*cur).second.msb) {
|
||||
/* If there is a range, then the signedness comes
|
||||
from the type and not the expression. */
|
||||
val->cast_signed(signed_flag);
|
||||
} else {
|
||||
/* otherwise, let the expression describe
|
||||
itself. */
|
||||
signed_flag = val->has_sign();
|
||||
}
|
||||
|
||||
val = scope->set_parameter((*cur).first, val,
|
||||
msb, lsb, signed_flag);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
|
||||
/* run parameter replacements that were collected from the
|
||||
containing scope and meant for me. */
|
||||
for (replace_t::const_iterator cur = replacements.begin()
|
||||
; cur != replacements.end() ; cur ++) {
|
||||
|
||||
NetExpr*val = (*cur).second;
|
||||
if (debug_scopes) {
|
||||
cerr << get_line() << ": debug: "
|
||||
<< "Replace " << (*cur).first
|
||||
<< " with expression " << *val
|
||||
<< " from " << val->get_line() << "." << endl;
|
||||
}
|
||||
bool flag = scope->replace_parameter((*cur).first, val);
|
||||
if (! flag) {
|
||||
cerr << val->get_line() << ": warning: parameter "
|
||||
<< (*cur).first << " not found in "
|
||||
<< scope_path(scope) << "." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; cur ++) {
|
||||
|
||||
PExpr*ex = (*cur).second.expr;
|
||||
assert(ex);
|
||||
|
||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||
NetExpr*msb = 0;
|
||||
NetExpr*lsb = 0;
|
||||
@@ -122,18 +190,6 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
delete val;
|
||||
}
|
||||
|
||||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; cur ++) {
|
||||
|
||||
PExpr*ex = (*cur).second.expr;
|
||||
assert(ex);
|
||||
|
||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||
val = scope->set_parameter((*cur).first, val, 0, 0, false);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
|
||||
// Run through the defparams for this module, elaborate the
|
||||
// expressions in this context and save the result is a table
|
||||
// for later final override.
|
||||
@@ -144,7 +200,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// here because the parameter receiving the assignment may be
|
||||
// in a scope not discovered by this pass.
|
||||
|
||||
for (hparm_it_t cur = defparms.begin()
|
||||
for (pform_parm_it_t cur = defparms.begin()
|
||||
; cur != defparms.end() ; cur ++ ) {
|
||||
|
||||
PExpr*ex = (*cur).second;
|
||||
@@ -165,18 +221,30 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
delete[]attr;
|
||||
|
||||
// Generate schemes can create new scopes in the form of
|
||||
// generated code. Scan the generate schemes, and *generate*
|
||||
// new scopes, which is slightly different from simple
|
||||
// elaboration.
|
||||
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur ++ ) {
|
||||
(*cur) -> generate_scope(des, scope);
|
||||
}
|
||||
|
||||
|
||||
// Tasks introduce new scopes, so scan the tasks in this
|
||||
// module. Create a scope for the task and pass that to the
|
||||
// elaborate_scope method of the PTask for detailed
|
||||
// processing.
|
||||
|
||||
typedef map<string,PTask*>::const_iterator tasks_it_t;
|
||||
typedef map<perm_string,PTask*>::const_iterator tasks_it_t;
|
||||
|
||||
for (tasks_it_t cur = tasks_.begin()
|
||||
; cur != tasks_.end() ; cur ++ ) {
|
||||
|
||||
NetScope*task_scope = new NetScope(scope, (*cur).first.c_str(),
|
||||
hname_t use_name( (*cur).first );
|
||||
NetScope*task_scope = new NetScope(scope, use_name,
|
||||
NetScope::TASK);
|
||||
(*cur).second->elaborate_scope(des, task_scope);
|
||||
}
|
||||
@@ -186,12 +254,13 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// perspective of scopes. So handle them exactly the same
|
||||
// way.
|
||||
|
||||
typedef map<string,PFunction*>::const_iterator funcs_it_t;
|
||||
typedef map<perm_string,PFunction*>::const_iterator funcs_it_t;
|
||||
|
||||
for (funcs_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++ ) {
|
||||
|
||||
NetScope*func_scope = new NetScope(scope, (*cur).first.c_str(),
|
||||
hname_t use_name( (*cur).first );
|
||||
NetScope*func_scope = new NetScope(scope, use_name,
|
||||
NetScope::FUNC);
|
||||
(*cur).second->elaborate_scope(des, func_scope);
|
||||
}
|
||||
@@ -201,7 +270,6 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// scan all of them to create those scopes.
|
||||
|
||||
typedef list<PGate*>::const_iterator gates_it_t;
|
||||
|
||||
for (gates_it_t cur = gates_.begin()
|
||||
; cur != gates_.end() ; cur ++ ) {
|
||||
|
||||
@@ -222,23 +290,127 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
// Scan through all the named events in this scope. We do not
|
||||
// need anything more then the current scope to do this
|
||||
// need anything more than the current scope to do this
|
||||
// elaboration, so do it now. This allows for normal
|
||||
// elaboration to reference these events.
|
||||
|
||||
for (map<string,PEvent*>::const_iterator et = events.begin()
|
||||
for (map<perm_string,PEvent*>::const_iterator et = events.begin()
|
||||
; et != events.end() ; et ++ ) {
|
||||
|
||||
(*et).second->elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
for (map<hname_t,PData*>::const_iterator cur = datum.begin()
|
||||
; cur != datum.end() ; cur ++ ) {
|
||||
return des->errors == 0;
|
||||
}
|
||||
|
||||
(*cur).second->elaborate_scope(des, scope);
|
||||
bool PGenerate::generate_scope(Design*des, NetScope*container)
|
||||
{
|
||||
switch (scheme_type) {
|
||||
case GS_LOOP:
|
||||
return generate_scope_loop_(des, container);
|
||||
|
||||
default:
|
||||
cerr << get_line() << ": sorry: Generate of this sort"
|
||||
<< " is not supported yet!" << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the elaborate scope method for a generate loop.
|
||||
*/
|
||||
bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
{
|
||||
// We're going to need a genvar...
|
||||
int genvar;
|
||||
|
||||
// The initial value for the genvar does not need (nor can it
|
||||
// use) the genvar itself, so we can evaluate this expression
|
||||
// the same way any other paramter value is evaluated.
|
||||
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1);
|
||||
NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
|
||||
if (init == 0) {
|
||||
cerr << get_line() << ": error: Cannot evaluate genvar"
|
||||
<< " init expression: " << *loop_init << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return des->errors == 0;
|
||||
genvar = init->value().as_long();
|
||||
delete init_ex;
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: genvar init = " << genvar << endl;
|
||||
|
||||
container->genvar_tmp = loop_index;
|
||||
container->genvar_tmp_val = 0;
|
||||
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
|
||||
assert(test);
|
||||
while (test->value().as_long()) {
|
||||
|
||||
// The actual name of the scope includes the genvar so
|
||||
// that each instance has a unique name in the
|
||||
// container. The format of using [] is part of the
|
||||
// Verilog standard.
|
||||
hname_t use_name (scope_name, genvar);
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: "
|
||||
<< "Create generated scope " << use_name << endl;
|
||||
|
||||
NetScope*scope = new NetScope(container, use_name,
|
||||
NetScope::GENBLOCK);
|
||||
|
||||
// Set in the scope a localparam for the value of the
|
||||
// genvar within this instance of the generate
|
||||
// block. Code within this scope thus has access to the
|
||||
// genvar as a constant.
|
||||
{
|
||||
verinum genvar_verinum(genvar);
|
||||
genvar_verinum.has_sign(true);
|
||||
NetEConstParam*gp = new NetEConstParam(scope,
|
||||
loop_index,
|
||||
genvar_verinum);
|
||||
scope->set_localparam(loop_index, gp);
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: "
|
||||
<< "Create implicit localparam "
|
||||
<< loop_index << " = " << genvar_verinum << endl;
|
||||
}
|
||||
|
||||
// Scan the generated scope for gates that may create
|
||||
// their own scopes.
|
||||
typedef list<PGate*>::const_iterator pgate_list_it_t;
|
||||
for (pgate_list_it_t cur = gates.begin()
|
||||
; cur != gates.end() ; cur ++) {
|
||||
(*cur) ->elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
scope_list_.push_back(scope);
|
||||
|
||||
// Calculate the step for the loop variable.
|
||||
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1);
|
||||
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
|
||||
assert(step);
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: genvar step from "
|
||||
<< genvar << " to " << step->value().as_long() << endl;
|
||||
|
||||
genvar = step->value().as_long();
|
||||
container->genvar_tmp_val = genvar;
|
||||
delete step;
|
||||
delete test_ex;
|
||||
test_ex = elab_and_eval(des, container, loop_test, -1);
|
||||
test = dynamic_cast<NetEConst*>(test_ex);
|
||||
assert(test);
|
||||
}
|
||||
|
||||
// Clear the genvar_tmp field in the scope to reflect that the
|
||||
// genvar is no longer value for evaluating expressions.
|
||||
container->genvar_tmp = perm_string();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
@@ -257,7 +429,7 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
// about to create, and if I find it then somebody beat me to
|
||||
// it.
|
||||
|
||||
if (sc->child(get_name())) {
|
||||
if (sc->child(hname_t(get_name()))) {
|
||||
cerr << get_line() << ": error: Instance/Scope name " <<
|
||||
get_name() << " already used in this context." <<
|
||||
endl;
|
||||
@@ -280,114 +452,149 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
<< "module " << mod->mod_name() << " within itself." << endl;
|
||||
|
||||
cerr << get_line() << ": : The offending instance is "
|
||||
<< sc->name() << "." << get_name() << " within "
|
||||
<< scn->name() << "." << endl;
|
||||
<< scope_path(sc) << "." << get_name() << " within "
|
||||
<< scope_path(scn) << "." << endl;
|
||||
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the new scope as a MODULE with my name.
|
||||
NetScope*my_scope = new NetScope(sc, get_name().c_str(), NetScope::MODULE);
|
||||
my_scope->set_module_name(mod->mod_name());
|
||||
NetExpr*mse = msb_ ? elab_and_eval(des, sc, msb_, -1) : 0;
|
||||
NetExpr*lse = lsb_ ? elab_and_eval(des, sc, lsb_, -1) : 0;
|
||||
NetEConst*msb = dynamic_cast<NetEConst*> (mse);
|
||||
NetEConst*lsb = dynamic_cast<NetEConst*> (lse);
|
||||
|
||||
// Set time units and precision.
|
||||
my_scope->time_unit(mod->time_unit);
|
||||
my_scope->time_precision(mod->time_precision);
|
||||
des->set_precision(mod->time_precision);
|
||||
assert( (msb == 0) || (lsb != 0) );
|
||||
|
||||
// This call actually arranges for the description of the
|
||||
// module type to process this instance and handle parameters
|
||||
// and sub-scopes that might occur. Parameters are also
|
||||
// created in that scope, as they exist. (I'll override them
|
||||
// later.)
|
||||
mod->elaborate_scope(des, my_scope);
|
||||
long instance_low = 0;
|
||||
long instance_high = 0;
|
||||
long instance_count = 1;
|
||||
bool instance_array = false;
|
||||
|
||||
// Look for module parameter replacements. The "replace" map
|
||||
// maps parameter name to replacement expression that is
|
||||
// passed. It is built up by the ordered overrides or named
|
||||
// overrides.
|
||||
if (msb) {
|
||||
instance_array = true;
|
||||
instance_high = msb->value().as_long();
|
||||
instance_low = lsb->value().as_long();
|
||||
if (instance_high > instance_low)
|
||||
instance_count = instance_high - instance_low + 1;
|
||||
else
|
||||
instance_count = instance_low - instance_high + 1;
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
map<string,PExpr*> replace;
|
||||
delete mse;
|
||||
delete lse;
|
||||
}
|
||||
|
||||
NetScope::scope_vec_t instances (instance_count);
|
||||
if (debug_scopes) {
|
||||
cerr << get_line() << ": debug: Create " << instance_count
|
||||
<< " instances of " << get_name()
|
||||
<< "." << endl;
|
||||
}
|
||||
|
||||
// Positional parameter overrides are matched to parameter
|
||||
// names by using the param_names list of parameter
|
||||
// names. This is an ordered list of names so the first name
|
||||
// is parameter 0, the second parameter 1, and so on.
|
||||
// Run through the module instances, and make scopes out of
|
||||
// them. Also do parameter overrides that are done on the
|
||||
// instantiation line.
|
||||
for (int idx = 0 ; idx < instance_count ; idx += 1) {
|
||||
|
||||
if (overrides_) {
|
||||
assert(parms_ == 0);
|
||||
list<string>::const_iterator cur = mod->param_names.begin();
|
||||
unsigned idx = 0;
|
||||
for (;;) {
|
||||
if (idx >= overrides_->count())
|
||||
break;
|
||||
if (cur == mod->param_names.end())
|
||||
break;
|
||||
hname_t use_name (get_name());
|
||||
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
if (instance_array) {
|
||||
int instance_idx = idx;
|
||||
if (instance_low < instance_high)
|
||||
instance_idx = instance_low + idx;
|
||||
else
|
||||
instance_idx = instance_low - idx;
|
||||
|
||||
idx += 1;
|
||||
cur ++;
|
||||
use_name = hname_t(get_name(), instance_idx);
|
||||
}
|
||||
}
|
||||
|
||||
// Named parameter overrides carry a name with each override
|
||||
// so the mapping into the replace list is much easier.
|
||||
if (parms_) {
|
||||
assert(overrides_ == 0);
|
||||
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
|
||||
replace[parms_[idx].name] = parms_[idx].parm;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// And here we scan the replacements we collected. Elaborate
|
||||
// the expression in my context, then replace the sub-scope
|
||||
// parameter value with the new expression.
|
||||
|
||||
for (mparm_it_t cur = replace.begin()
|
||||
; cur != replace.end() ; cur ++ ) {
|
||||
|
||||
PExpr*tmp = (*cur).second;
|
||||
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
||||
bool flag = my_scope->replace_parameter((*cur).first, val);
|
||||
if (! flag) {
|
||||
cerr << val->get_line() << ": warning: parameter "
|
||||
<< (*cur).first << " not found in "
|
||||
<< sc->name() << "." << endl;
|
||||
if (debug_scopes) {
|
||||
cerr << get_line() << ": debug: Module instance " << use_name
|
||||
<< " becomes child of " << scope_path(sc)
|
||||
<< "." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate the datum within the module. This variable make be
|
||||
* within a subscope (i.e. a function or task) so use the components
|
||||
* of the name to find the precise scope where this item goes.
|
||||
*/
|
||||
void PData::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetScope*sub_scope = scope;
|
||||
for (unsigned idx = 0 ; idx < (hname_.component_count()-1); idx += 1) {
|
||||
sub_scope = sub_scope->child(hname_.peek_name(idx));
|
||||
// Create the new scope as a MODULE with my name.
|
||||
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE);
|
||||
my_scope->set_module_name(mod->mod_name());
|
||||
my_scope->default_nettype(mod->default_nettype);
|
||||
|
||||
if (sub_scope == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Could not find sub-scope "
|
||||
<< hname_.peek_name(idx) << " of "
|
||||
<< hname_ << " in module " << scope->name()
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
instances[idx] = my_scope;
|
||||
|
||||
// Set time units and precision.
|
||||
my_scope->time_unit(mod->time_unit);
|
||||
my_scope->time_precision(mod->time_precision);
|
||||
des->set_precision(mod->time_precision);
|
||||
|
||||
// Look for module parameter replacements. The "replace" map
|
||||
// maps parameter name to replacement expression that is
|
||||
// passed. It is built up by the ordered overrides or named
|
||||
// overrides.
|
||||
|
||||
typedef map<perm_string,PExpr*>::const_iterator mparm_it_t;
|
||||
map<perm_string,PExpr*> replace;
|
||||
|
||||
|
||||
// Positional parameter overrides are matched to parameter
|
||||
// names by using the param_names list of parameter
|
||||
// names. This is an ordered list of names so the first name
|
||||
// is parameter 0, the second parameter 1, and so on.
|
||||
|
||||
if (overrides_) {
|
||||
assert(parms_ == 0);
|
||||
list<perm_string>::const_iterator cur
|
||||
= mod->param_names.begin();
|
||||
unsigned idx = 0;
|
||||
for (;;) {
|
||||
if (idx >= overrides_->count())
|
||||
break;
|
||||
if (cur == mod->param_names.end())
|
||||
break;
|
||||
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
|
||||
idx += 1;
|
||||
cur ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Named parameter overrides carry a name with each override
|
||||
// so the mapping into the replace list is much easier.
|
||||
if (parms_) {
|
||||
assert(overrides_ == 0);
|
||||
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
|
||||
replace[parms_[idx].name] = parms_[idx].parm;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Module::replace_t replace_net;
|
||||
|
||||
// And here we scan the replacements we collected. Elaborate
|
||||
// the expression in my context, then replace the sub-scope
|
||||
// parameter value with the new expression.
|
||||
|
||||
for (mparm_it_t cur = replace.begin()
|
||||
; cur != replace.end() ; cur ++ ) {
|
||||
|
||||
PExpr*tmp = (*cur).second;
|
||||
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
||||
replace_net[(*cur).first] = val;
|
||||
}
|
||||
|
||||
// This call actually arranges for the description of the
|
||||
// module type to process this instance and handle parameters
|
||||
// and sub-scopes that might occur. Parameters are also
|
||||
// created in that scope, as they exist. (I'll override them
|
||||
// later.)
|
||||
mod->elaborate_scope(des, my_scope, replace_net);
|
||||
|
||||
}
|
||||
|
||||
const char*basename = hname_.peek_tail_name();
|
||||
NetVariable*tmp = new NetVariable(lex_strings.add(basename));
|
||||
tmp->set_line(*this);
|
||||
sub_scope->add_variable(tmp);
|
||||
/* Stash the instance array of scopes into the parent
|
||||
scope. Later elaboration passes will use this vector to
|
||||
further elaborate the array. */
|
||||
sc->instance_arrays[get_name()] = instances;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -439,8 +646,8 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetScope*my_scope = scope;
|
||||
|
||||
if (name_ != "") {
|
||||
my_scope = new NetScope(scope, name_.c_str(), bl_type_==BL_PAR
|
||||
if (name_ != 0) {
|
||||
my_scope = new NetScope(scope, hname_t(name_), bl_type_==BL_PAR
|
||||
? NetScope::FORK_JOIN
|
||||
: NetScope::BEGIN_END);
|
||||
}
|
||||
@@ -549,6 +756,72 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_scope.cc,v $
|
||||
* Revision 1.46 2007/06/02 03:42:12 steve
|
||||
* Properly evaluate scope path expressions.
|
||||
*
|
||||
* Revision 1.45 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.44 2007/03/22 16:08:15 steve
|
||||
* Spelling fixes from Larry
|
||||
*
|
||||
* Revision 1.43 2007/03/08 06:11:35 steve
|
||||
* Elaborate scopes of modules instantated in generate loops.
|
||||
*
|
||||
* Revision 1.42 2007/03/05 05:59:10 steve
|
||||
* Handle processes within generate loops.
|
||||
*
|
||||
* Revision 1.41 2006/06/02 04:48:50 steve
|
||||
* Make elaborate_expr methods aware of the width that the context
|
||||
* requires of it. In the process, fix sizing of the width of unary
|
||||
* minus is context determined sizes.
|
||||
*
|
||||
* Revision 1.40 2006/04/12 05:05:03 steve
|
||||
* Use elab_and_eval to evaluate genvar expressions.
|
||||
*
|
||||
* Revision 1.39 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.38 2006/03/30 01:49:07 steve
|
||||
* Fix instance arrays indexed by overridden parameters.
|
||||
*
|
||||
* Revision 1.37 2006/03/18 22:53:38 steve
|
||||
* Support more parameter syntax.
|
||||
*
|
||||
* Revision 1.36 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
* Revision 1.35 2004/09/10 00:15:17 steve
|
||||
* Missing stdio.h header for warnings.
|
||||
*
|
||||
* Revision 1.34 2004/09/05 17:44:41 steve
|
||||
* Add support for module instance arrays.
|
||||
*
|
||||
* Revision 1.33 2004/08/26 04:02:03 steve
|
||||
* Add support for localparam ranges.
|
||||
*
|
||||
* Revision 1.32 2004/06/13 04:56:54 steve
|
||||
* Add support for the default_nettype directive.
|
||||
*
|
||||
* Revision 1.31 2004/05/25 19:21:06 steve
|
||||
* More identifier lists use perm_strings.
|
||||
*
|
||||
* Revision 1.30 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.29 2004/02/19 07:06:57 steve
|
||||
* LPM, logic and Variables have perm_string names.
|
||||
*
|
||||
* Revision 1.28 2004/02/18 17:11:55 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.27 2003/09/13 01:01:51 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.26 2003/08/28 04:11:17 steve
|
||||
* Spelling patch.
|
||||
*
|
||||
* Revision 1.25 2003/06/24 01:38:02 steve
|
||||
* Various warnings fixed.
|
||||
*
|
||||
|
||||
+427
-154
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2004 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_sig.cc,v 1.31 2003/07/15 03:49:22 steve Exp $"
|
||||
#ident "$Id: elab_sig.cc,v 1.52 2007/06/02 03:42:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -27,11 +27,14 @@
|
||||
# include "Module.h"
|
||||
# include "PExpr.h"
|
||||
# include "PGate.h"
|
||||
# include "PGenerate.h"
|
||||
# include "PTask.h"
|
||||
# include "PWire.h"
|
||||
# include "compiler.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
/*
|
||||
* This local function checks if a named signal is connected to a
|
||||
@@ -39,8 +42,10 @@
|
||||
* within the port_t that have a matching name.
|
||||
*/
|
||||
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
||||
const hname_t&name)
|
||||
NetNet*sig)
|
||||
{
|
||||
perm_string name = sig->name();
|
||||
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
|
||||
Module::port_t*pp = ports[idx];
|
||||
@@ -51,9 +56,15 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
||||
// This port has an internal connection. In this case,
|
||||
// the port has 0 or more NetEIdent objects concatenated
|
||||
// together that form the port.
|
||||
|
||||
// Note that module ports should not have any heirarchy
|
||||
// in their names: they are in the root of the module
|
||||
// scope by definition.
|
||||
|
||||
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
||||
perm_string pname = peek_tail_name(pp->expr[cc]->path());
|
||||
assert(pp->expr[cc]);
|
||||
if (pp->expr[cc]->path() == name)
|
||||
if (pname == name)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -61,14 +72,28 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static NetNet*find_signal_in_scope(NetScope*scope, const hname_t&path)
|
||||
{
|
||||
NetScope*cur = scope;
|
||||
unsigned idx = 0;
|
||||
|
||||
while (path.peek_name(idx+1)) {
|
||||
cur = cur->child(path.peek_name(idx));
|
||||
if (cur == 0)
|
||||
return 0;
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
return cur->find_signal(path.peek_name(idx));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
// Get all the explicitly declared wires of the module and
|
||||
// start the signals list with them.
|
||||
const map<hname_t,PWire*>&wl = get_wires();
|
||||
|
||||
// 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) {
|
||||
@@ -76,12 +101,12 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
if (pp == 0)
|
||||
continue;
|
||||
|
||||
map<hname_t,PWire*>::const_iterator wt;
|
||||
map<pform_name_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);
|
||||
pform_name_t port_path (pp->expr[cc]->path());
|
||||
wt = wires_.find(port_path);
|
||||
|
||||
if (wt == wl.end()) {
|
||||
if (wt == wires_.end()) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< "Port " << pp->expr[cc]->path() << " ("
|
||||
<< (idx+1) << ") of module " << name_
|
||||
@@ -101,14 +126,11 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
}
|
||||
}
|
||||
|
||||
for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
|
||||
; wt != wl.end()
|
||||
; wt ++ ) {
|
||||
for (map<pform_name_t,PWire*>::const_iterator wt = wires_.begin()
|
||||
; wt != wires_.end() ; wt ++ ) {
|
||||
|
||||
PWire*cur = (*wt).second;
|
||||
cur->elaborate_sig(des, scope);
|
||||
|
||||
NetNet*sig = scope->find_signal_in_child(cur->path());
|
||||
NetNet*sig = cur->elaborate_sig(des, scope);
|
||||
|
||||
// If this wire is a signal of the module (as opposed to
|
||||
// a port of a function) and is a port, then check that
|
||||
@@ -120,12 +142,10 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
if (sig && (sig->scope() == scope)
|
||||
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
|
||||
|
||||
hname_t name = (*wt).first;
|
||||
|
||||
if (! signal_is_in_port(ports, name)) {
|
||||
if (! signal_is_in_port(ports, sig)) {
|
||||
|
||||
cerr << cur->get_line() << ": error: Signal "
|
||||
<< name << " has a declared direction "
|
||||
<< sig->name() << " has a declared direction "
|
||||
<< "but is not a port." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
@@ -157,6 +177,16 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Run through all the generate schemes to enaborate the
|
||||
// signals that they hold. Note that the generate schemes hold
|
||||
// the scopes that they instantiated, so we don't pass any
|
||||
// scope in.
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; cur ++ ) {
|
||||
(*cur) -> elaborate_sig(des);
|
||||
}
|
||||
|
||||
// Get all the gates of the module and elaborate them by
|
||||
@@ -174,15 +204,17 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
|
||||
typedef map<string,PFunction*>::const_iterator mfunc_it_t;
|
||||
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
|
||||
|
||||
for (mfunc_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++) {
|
||||
NetScope*fscope = scope->child((*cur).first);
|
||||
|
||||
hname_t use_name ( (*cur).first );
|
||||
NetScope*fscope = scope->child(use_name);
|
||||
if (scope == 0) {
|
||||
cerr << (*cur).second->get_line() << ": internal error: "
|
||||
<< "Child scope for function " << (*cur).first
|
||||
<< " missing in " << scope->name() << "." << endl;
|
||||
<< " missing in " << scope_path(scope) << "." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -195,11 +227,11 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
// elaborate the ports of the tasks defined within this
|
||||
// module. Run through them now.
|
||||
|
||||
typedef map<string,PTask*>::const_iterator mtask_it_t;
|
||||
typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
|
||||
|
||||
for (mtask_it_t cur = tasks_.begin()
|
||||
; cur != tasks_.end() ; cur ++) {
|
||||
NetScope*tscope = scope->child((*cur).first);
|
||||
NetScope*tscope = scope->child( hname_t((*cur).first) );
|
||||
assert(tscope);
|
||||
(*cur).second->elaborate_sig(des, tscope);
|
||||
}
|
||||
@@ -210,31 +242,86 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
|
||||
Module*rmod) const
|
||||
{
|
||||
// Missing module instance names have already been rejected.
|
||||
assert(get_name() != "");
|
||||
bool flag = true;
|
||||
|
||||
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
|
||||
|
||||
for (unsigned idx = 0 ; idx < instance.count() ; idx += 1) {
|
||||
// I know a priori that the elaborate_scope created the scope
|
||||
// already, so just look it up as a child of the current scope.
|
||||
NetScope*my_scope = instance[idx];
|
||||
assert(my_scope);
|
||||
|
||||
if (my_scope->parent() != scope) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Instance " << scope_path(my_scope)
|
||||
<< " is in parent " << scope_path(my_scope->parent())
|
||||
<< " instead of " << scope_path(scope)
|
||||
<< endl;
|
||||
}
|
||||
assert(my_scope->parent() == scope);
|
||||
|
||||
if (! rmod->elaborate_sig(des, my_scope))
|
||||
flag = false;
|
||||
|
||||
if (msb_) {
|
||||
cerr << get_line() << ": sorry: Module instantiation arrays "
|
||||
"are not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// I know a priori that the elaborate_scope created the scope
|
||||
// already, so just look it up as a child of the current scope.
|
||||
NetScope*my_scope = scope->child(get_name());
|
||||
assert(my_scope);
|
||||
|
||||
return rmod->elaborate_sig(des, my_scope);
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool PGenerate::elaborate_sig(Design*des) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
typedef list<NetScope*>::const_iterator scope_list_it_t;
|
||||
for (scope_list_it_t cur = scope_list_.begin()
|
||||
; cur != scope_list_.end() ; cur ++ ) {
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: Elaborate nets in "
|
||||
<< "scope " << scope_path(*cur) << endl;
|
||||
flag = elaborate_sig_(des, *cur) & flag;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
|
||||
{
|
||||
// Scan the declared PWires to elaborate the obvious signals
|
||||
// in the current scope.
|
||||
typedef map<pform_name_t,PWire*>::const_iterator wires_it_t;
|
||||
for (wires_it_t wt = wires.begin()
|
||||
; wt != wires.end() ; wt ++ ) {
|
||||
|
||||
PWire*cur = (*wt).second;
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: Elaborate PWire "
|
||||
<< cur->path() << " in scope " << scope_path(scope) << endl;
|
||||
|
||||
cur->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
typedef list<PGate*>::const_iterator pgate_list_it_t;
|
||||
for (pgate_list_it_t cur = gates.begin()
|
||||
; cur != gates.end() ; cur ++) {
|
||||
(*cur) ->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A function definition exists within an elaborated module.
|
||||
* A function definition exists within an elaborated module. This
|
||||
* matters when elaborating signals, as the ports of the function are
|
||||
* created as signals/variables for each instance of the
|
||||
* function. That is why PFunction has an elaborate_sig method.
|
||||
*/
|
||||
void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
string fname = scope->basename();
|
||||
perm_string fname = scope->basename();
|
||||
assert(scope->type() == NetScope::FUNC);
|
||||
|
||||
/* Make sure the function has at least one input port. If it
|
||||
@@ -248,21 +335,88 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
|
||||
NetNet*ret_sig = 0;
|
||||
|
||||
/* Get the reg for the return value. I know the name of the
|
||||
reg variable, and I know that it is in this scope, so look
|
||||
it up directly. */
|
||||
ports[0] = scope->find_signal(scope->basename());
|
||||
if (ports[0] == 0) {
|
||||
cerr << get_line() << ": internal error: function scope "
|
||||
<< scope->name() << " is missing return reg "
|
||||
<< fname << "." << endl;
|
||||
scope->dump(cerr);
|
||||
des->errors += 1;
|
||||
return;
|
||||
/* Create the signals/variables of the return value and write
|
||||
them into the function scope. */
|
||||
switch (return_type_.type) {
|
||||
|
||||
case PTF_REG:
|
||||
case PTF_REG_S:
|
||||
if (return_type_.range) {
|
||||
NetExpr*me = elab_and_eval(des, scope,
|
||||
(*return_type_.range)[0], -1);
|
||||
assert(me);
|
||||
NetExpr*le = elab_and_eval(des, scope,
|
||||
(*return_type_.range)[1], -1);
|
||||
assert(le);
|
||||
|
||||
long mnum = 0, lnum = 0;
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
|
||||
mnum = tmp->value().as_long();
|
||||
} else {
|
||||
cerr << me->get_line() << ": error: "
|
||||
"Unable to evaluate constant expression "
|
||||
<< *me << "." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(le)) {
|
||||
lnum = tmp->value().as_long();
|
||||
} else {
|
||||
cerr << le->get_line() << ": error: "
|
||||
"Unable to evaluate constant expression "
|
||||
<< *le << "." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
|
||||
|
||||
} else {
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG);
|
||||
}
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(return_type_.type == PTF_REG_S);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
||||
case PTF_INTEGER:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, integer_width);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(true);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
||||
case PTF_TIME:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, 64);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(false);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_LOGIC);
|
||||
break;
|
||||
|
||||
case PTF_REAL:
|
||||
case PTF_REALTIME:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, 1);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
ret_sig->data_type(IVL_VT_REAL);
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << get_line() << ": internal error: I don't know how "
|
||||
<< "to deal with return type of function "
|
||||
<< scope->basename() << "." << endl;
|
||||
}
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count() : 0);
|
||||
|
||||
if (ports_)
|
||||
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
|
||||
|
||||
@@ -270,32 +424,38 @@ 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>. */
|
||||
|
||||
hname_t path = (*ports_)[idx]->path();
|
||||
string pname = path.peek_name(1);
|
||||
string ppath = path.peek_name(0);
|
||||
pform_name_t path = (*ports_)[idx]->path();
|
||||
ivl_assert(*this, path.size() == 2);
|
||||
|
||||
perm_string pname = peek_tail_name(path);
|
||||
perm_string ppath = peek_head_name(path);
|
||||
|
||||
if (ppath != scope->basename()) {
|
||||
cerr << get_line() << ": internal error: function "
|
||||
<< "port " << (*ports_)[idx]->path()
|
||||
<< " has wrong name for function "
|
||||
<< scope->name() << "." << endl;
|
||||
<< scope_path(scope) << "." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetNet*tmp = scope->find_signal(pname);
|
||||
if (tmp == 0) {
|
||||
cerr << get_line() << ": internal error: function "
|
||||
<< scope->name() << " is missing port "
|
||||
<< scope_path(scope) << " is missing port "
|
||||
<< pname << "." << endl;
|
||||
scope->dump(cerr);
|
||||
cerr << get_line() << ": Continuing..." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
ports[idx+1] = tmp;
|
||||
ports[idx] = tmp;
|
||||
}
|
||||
|
||||
|
||||
NetFuncDef*def = new NetFuncDef(scope, ports);
|
||||
NetFuncDef*def = 0;
|
||||
if (ret_sig) def = new NetFuncDef(scope, ret_sig, ports);
|
||||
|
||||
assert(def);
|
||||
scope->set_func_def(def);
|
||||
}
|
||||
|
||||
@@ -319,36 +479,34 @@ 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>. */
|
||||
|
||||
hname_t path = (*ports_)[idx]->path();
|
||||
assert(path.peek_name(0) && path.peek_name(1));
|
||||
pform_name_t path = (*ports_)[idx]->path();
|
||||
ivl_assert(*this, path.size() == 2);
|
||||
|
||||
perm_string scope_name = peek_head_name(path);
|
||||
perm_string port_name = peek_tail_name(path);
|
||||
|
||||
/* 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(path.peek_name(0)) != scope) {
|
||||
cerr << "internal error: task scope " << path
|
||||
<< " not the same as scope " << scope->name()
|
||||
<< "?!" << endl;
|
||||
return;
|
||||
}
|
||||
ivl_assert(*this, scope->basename() == scope_name);
|
||||
|
||||
/* 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(path.peek_name(1));
|
||||
NetNet*tmp = scope->find_signal(port_name);
|
||||
|
||||
if (tmp == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Could not find port " << path.peek_name(1)
|
||||
<< " in scope " << scope->name() << endl;
|
||||
<< "Could not find port " << port_name
|
||||
<< " in scope " << scope_path(scope) << endl;
|
||||
scope->dump(cerr);
|
||||
}
|
||||
|
||||
ports[idx] = tmp;
|
||||
}
|
||||
|
||||
NetTaskDef*def = new NetTaskDef(scope->name(), ports);
|
||||
NetTaskDef*def = new NetTaskDef(scope, ports);
|
||||
scope->set_task_def(def);
|
||||
}
|
||||
|
||||
@@ -364,16 +522,26 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const
|
||||
* elaboration this creates an object in the design that represent the
|
||||
* defined item.
|
||||
*/
|
||||
void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
NetNet* 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. */
|
||||
{ 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);
|
||||
{ pform_name_t tmp_path = hname_;
|
||||
tmp_path.pop_back();
|
||||
while (! tmp_path.empty()) {
|
||||
name_component_t cur = tmp_path.front();
|
||||
tmp_path.pop_front();
|
||||
|
||||
scope = scope->child( hname_t(cur.name) );
|
||||
|
||||
if (scope == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Bad scope component for name "
|
||||
<< hname_ << endl;
|
||||
assert(scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,7 +579,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
NetEConst*tmp;
|
||||
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
|
||||
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx], -1);
|
||||
|
||||
tmp = dynamic_cast<NetEConst*>(texpr);
|
||||
if (tmp == 0) {
|
||||
@@ -419,20 +587,20 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
"Unable to evaluate constant expression ``" <<
|
||||
*msb_[idx] << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mnum[idx] = tmp->value().as_long();
|
||||
delete texpr;
|
||||
|
||||
texpr = elab_and_eval(des, scope, lsb_[idx]);
|
||||
texpr = elab_and_eval(des, scope, lsb_[idx], -1);
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
lnum[idx] = tmp->value().as_long();
|
||||
@@ -448,7 +616,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
<< "'' declared both as a vector and a scalar."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -461,7 +629,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
|
||||
" for signal ``" << hname_ << "''" << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,51 +647,197 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
|
||||
des, scope);
|
||||
|
||||
long array_s0 = 0;
|
||||
long array_e0 = 0;
|
||||
unsigned array_dimensions = 0;
|
||||
|
||||
/* If the ident has idx expressions, then this is a
|
||||
memory. It can only have the idx registers after the msb
|
||||
and lsb expressions are filled. And, if it has one index,
|
||||
it has both. */
|
||||
if (lidx_ || ridx_) {
|
||||
assert(lidx_ && ridx_);
|
||||
|
||||
// If the register has indices, then this is a
|
||||
// memory. Create the memory object.
|
||||
verinum*lval = lidx_->eval_const(des, scope);
|
||||
verinum*rval = ridx_->eval_const(des, scope);
|
||||
NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
|
||||
NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);
|
||||
|
||||
if ((lval == 0) || (rval == 0)) {
|
||||
if ((lexp == 0) || (rexp == 0)) {
|
||||
cerr << get_line() << ": internal error: There is "
|
||||
<< "a problem evaluating indices for ``"
|
||||
<< hname_.peek_tail_name() << "''." << endl;
|
||||
<< hname_ << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(lval);
|
||||
assert(rval);
|
||||
NetEConst*lcon = dynamic_cast<NetEConst*> (lexp);
|
||||
NetEConst*rcon = dynamic_cast<NetEConst*> (rexp);
|
||||
|
||||
string name = hname_.peek_tail_name();
|
||||
if ((lcon == 0) || (rcon == 0)) {
|
||||
cerr << get_line() << ": internal error: The indices "
|
||||
<< "are not constant for array ``"
|
||||
<< hname_ << "''." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long lnum = lval->as_long();
|
||||
long rnum = rval->as_long();
|
||||
delete lval;
|
||||
delete rval;
|
||||
new NetMemory(scope, name, wid, lnum, rnum);
|
||||
// The constructor automatically adds the memory object
|
||||
// to the scope. Do I need to set line number information?
|
||||
verinum lval = lcon->value();
|
||||
verinum rval = rcon->value();
|
||||
|
||||
} else {
|
||||
delete lexp;
|
||||
delete rexp;
|
||||
|
||||
string name = hname_.peek_tail_name();
|
||||
NetNet*sig = new NetNet(scope, name, wtype, msb, lsb);
|
||||
sig->set_line(*this);
|
||||
sig->port_type(port_type_);
|
||||
sig->set_signed(get_signed());
|
||||
sig->set_isint(get_isint());
|
||||
|
||||
for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
|
||||
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
|
||||
array_dimensions = 1;
|
||||
array_s0 = lval.as_long();
|
||||
array_e0 = rval.as_long();
|
||||
}
|
||||
|
||||
/* If the net type is supply0 or supply1, replace it
|
||||
with a simple wire with a pulldown/pullup with supply
|
||||
strength. In other words, transform:
|
||||
|
||||
supply0 foo;
|
||||
|
||||
to:
|
||||
|
||||
wire foo;
|
||||
pulldown #(supply0) (foo);
|
||||
|
||||
This reduces the backend burden, and behaves exactly
|
||||
the same. */
|
||||
|
||||
NetLogic*pull = 0;
|
||||
if (wtype == NetNet::SUPPLY0 || wtype == NetNet::SUPPLY1) {
|
||||
NetLogic::TYPE pull_type = (wtype==NetNet::SUPPLY1)
|
||||
? NetLogic::PULLUP
|
||||
: NetLogic::PULLDOWN;
|
||||
pull = new NetLogic(scope, scope->local_symbol(),
|
||||
1, pull_type, wid);
|
||||
pull->set_line(*this);
|
||||
pull->pin(0).drive0(Link::SUPPLY);
|
||||
pull->pin(0).drive1(Link::SUPPLY);
|
||||
des->add_node(pull);
|
||||
wtype = NetNet::WIRE;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_line() << ": debug: "
|
||||
<< "Generate a SUPPLY pulldown for the "
|
||||
<< "supply0 net." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
perm_string name = peek_tail_name(hname_);
|
||||
if (debug_elaborate) {
|
||||
cerr << get_line() << ": debug: Create signal "
|
||||
<< wtype << " ["<<msb<<":"<<lsb<<"] " << name
|
||||
<< " in scope " << scope_path(scope) << endl;
|
||||
}
|
||||
|
||||
|
||||
NetNet*sig = array_dimensions > 0
|
||||
? new NetNet(scope, name, wtype, msb, lsb, array_s0, array_e0)
|
||||
: new NetNet(scope, name, wtype, msb, lsb);
|
||||
|
||||
ivl_variable_type_t use_data_type = data_type_;
|
||||
if (use_data_type == IVL_VT_NO_TYPE) {
|
||||
use_data_type = IVL_VT_LOGIC;
|
||||
if (debug_elaborate) {
|
||||
cerr << get_line() << ": debug: "
|
||||
<< "Signal " << name
|
||||
<< " in scope " << scope_path(scope)
|
||||
<< " defaults to data type " << use_data_type << endl;
|
||||
}
|
||||
}
|
||||
|
||||
sig->data_type(use_data_type);
|
||||
sig->set_line(*this);
|
||||
sig->port_type(port_type_);
|
||||
sig->set_signed(get_signed());
|
||||
sig->set_isint(get_isint());
|
||||
|
||||
if (pull)
|
||||
connect(sig->pin(0), pull->pin(0));
|
||||
|
||||
for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
|
||||
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_sig.cc,v $
|
||||
* Revision 1.52 2007/06/02 03:42:12 steve
|
||||
* Properly evaluate scope path expressions.
|
||||
*
|
||||
* Revision 1.51 2007/05/24 04:07:11 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.50 2007/04/26 03:06:22 steve
|
||||
* Rework hname_t to use perm_strings.
|
||||
*
|
||||
* Revision 1.49 2007/04/02 01:12:34 steve
|
||||
* Seperate arrayness from word count
|
||||
*
|
||||
* Revision 1.48 2007/03/08 06:11:35 steve
|
||||
* Elaborate scopes of modules instantated in generate loops.
|
||||
*
|
||||
* Revision 1.47 2007/03/07 04:24:59 steve
|
||||
* Make integer width controllable.
|
||||
*
|
||||
* Revision 1.46 2007/03/06 05:22:49 steve
|
||||
* Support signed function return values.
|
||||
*
|
||||
* Revision 1.45 2007/02/01 05:24:08 steve
|
||||
* Include type in signal create message.
|
||||
*
|
||||
* Revision 1.44 2007/01/29 02:07:34 steve
|
||||
* Types of task/function arguments set in multiple steps.
|
||||
*
|
||||
* Revision 1.43 2007/01/16 05:44:15 steve
|
||||
* Major rework of array handling. Memories are replaced with the
|
||||
* more general concept of arrays. The NetMemory and NetEMemory
|
||||
* classes are removed from the ivl core program, and the IVL_LPM_RAM
|
||||
* lpm type is removed from the ivl_target API.
|
||||
*
|
||||
* Revision 1.42 2006/06/02 04:48:50 steve
|
||||
* Make elaborate_expr methods aware of the width that the context
|
||||
* requires of it. In the process, fix sizing of the width of unary
|
||||
* minus is context determined sizes.
|
||||
*
|
||||
* Revision 1.41 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.40 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
* Revision 1.39 2005/07/07 16:22:49 steve
|
||||
* Generalize signals to carry types.
|
||||
*
|
||||
* Revision 1.38 2005/02/13 01:15:07 steve
|
||||
* Replace supply nets with wires connected to pullup/down supply devices.
|
||||
*
|
||||
* Revision 1.37 2004/12/11 02:31:25 steve
|
||||
* Rework of internals to carry vectors through nexus instead
|
||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
||||
* down this path.
|
||||
*
|
||||
* Revision 1.36 2004/09/27 22:34:10 steve
|
||||
* Cleanup and factoring of autoconf.
|
||||
*
|
||||
* Revision 1.35 2004/09/05 17:44:41 steve
|
||||
* Add support for module instance arrays.
|
||||
*
|
||||
* Revision 1.34 2004/05/31 23:34:37 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.33 2004/02/18 17:11:55 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.32 2003/09/20 05:24:00 steve
|
||||
* Evaluate memory index constants using elab_and_eval.
|
||||
*
|
||||
* Revision 1.31 2003/07/15 03:49:22 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
@@ -594,46 +908,5 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
* Revision 1.11 2001/02/10 20:29:39 steve
|
||||
* In the context of range declarations, use elab_and_eval instead
|
||||
* of the less robust eval_const methods.
|
||||
*
|
||||
* Revision 1.10 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
* Revision 1.9 2001/01/07 07:00:31 steve
|
||||
* Detect port direction attached to non-ports.
|
||||
*
|
||||
* Revision 1.8 2001/01/04 04:47:51 steve
|
||||
* Add support for << is signal indices.
|
||||
*
|
||||
* Revision 1.7 2000/12/11 00:31:43 steve
|
||||
* Add support for signed reg variables,
|
||||
* simulate in t-vvm signed comparisons.
|
||||
*
|
||||
* Revision 1.6 2000/12/04 17:37:04 steve
|
||||
* Add Attrib class for holding NetObj attributes.
|
||||
*
|
||||
* Revision 1.5 2000/11/20 00:58:40 steve
|
||||
* Add support for supply nets (PR#17)
|
||||
*
|
||||
* Revision 1.4 2000/09/07 22:37:48 steve
|
||||
* ack, detect when lval fails.
|
||||
*
|
||||
* Revision 1.3 2000/07/30 18:25:43 steve
|
||||
* Rearrange task and function elaboration so that the
|
||||
* NetTaskDef and NetFuncDef functions are created during
|
||||
* signal enaboration, and carry these objects in the
|
||||
* NetScope class instead of the extra, useless map in
|
||||
* the Design class.
|
||||
*
|
||||
* Revision 1.2 2000/07/14 06:12:57 steve
|
||||
* Move inital value handling from NetNet to Nexus
|
||||
* objects. This allows better propogation of inital
|
||||
* values.
|
||||
*
|
||||
* Clean up constant propagation a bit to account
|
||||
* for regs that are not really values.
|
||||
*
|
||||
* Revision 1.1 2000/05/02 16:27:38 steve
|
||||
* Move signal elaboration to a separate pass.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+1523
-575
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2005 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: emit.cc,v 1.74 2003/05/30 02:55:32 steve Exp $"
|
||||
#ident "$Id: emit.cc,v 1.89 2007/01/16 05:44:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -57,18 +57,17 @@ bool NetAddSub::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetArrayDq::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->lpm_array_dq(this);
|
||||
}
|
||||
|
||||
bool NetCaseCmp::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_case_cmp(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCAssign::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_cassign(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCLShift::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_clshift(this);
|
||||
@@ -81,6 +80,11 @@ bool NetCompare::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetConcat::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->concat(this);
|
||||
}
|
||||
|
||||
bool NetConst::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->net_const(this);
|
||||
@@ -98,10 +102,9 @@ bool NetFF::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetForce::emit_node(struct target_t*tgt) const
|
||||
bool NetLiteral::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_force(this);
|
||||
return true;
|
||||
return tgt->net_literal(this);
|
||||
}
|
||||
|
||||
bool NetModulo::emit_node(struct target_t*tgt) const
|
||||
@@ -122,10 +125,29 @@ bool NetMux::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetRamDq::emit_node(struct target_t*tgt) const
|
||||
bool NetPartSelect::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->lpm_ram_dq(this);
|
||||
return true;
|
||||
return tgt->part_select(this);
|
||||
}
|
||||
|
||||
bool NetReplicate::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->replicate(this);
|
||||
}
|
||||
|
||||
bool NetSignExtend::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->sign_extend(this);
|
||||
}
|
||||
|
||||
bool NetUReduce::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->ureduce(this);
|
||||
}
|
||||
|
||||
bool NetSysFunc::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->net_sysfunction(this);
|
||||
}
|
||||
|
||||
bool NetUserFunc::emit_node(struct target_t*tgt) const
|
||||
@@ -312,9 +334,6 @@ void NetScope::emit_scope(struct target_t*tgt) const
|
||||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
|
||||
tgt->event(cur);
|
||||
|
||||
for (NetVariable*cur = vars_ ; cur ; cur = cur->snext_)
|
||||
tgt->variable(cur);
|
||||
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->emit_scope(tgt);
|
||||
|
||||
@@ -324,34 +343,42 @@ void NetScope::emit_scope(struct target_t*tgt) const
|
||||
tgt->signal(cur);
|
||||
cur = cur->sig_next_;
|
||||
} while (cur != signals_->sig_next_);
|
||||
|
||||
/* Run the signals again, but this time to connect the
|
||||
delay paths. This is done as a second pass because
|
||||
the paths reference other signals that may be later
|
||||
in the list. We can do it here becase delay paths are
|
||||
always connected within the scope. */
|
||||
cur = signals_->sig_next_;
|
||||
do {
|
||||
tgt->signal_paths(cur);
|
||||
cur = cur->sig_next_;
|
||||
} while (cur != signals_->sig_next_);
|
||||
}
|
||||
|
||||
if (memories_) {
|
||||
NetMemory*cur = memories_->snext_;
|
||||
do {
|
||||
tgt->memory(cur);
|
||||
cur = cur->snext_;
|
||||
} while (cur != memories_->snext_);
|
||||
}
|
||||
}
|
||||
|
||||
void NetScope::emit_defs(struct target_t*tgt) const
|
||||
bool NetScope::emit_defs(struct target_t*tgt) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
switch (type_) {
|
||||
case MODULE:
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->emit_defs(tgt);
|
||||
flag &= cur->emit_defs(tgt);
|
||||
break;
|
||||
|
||||
case FUNC:
|
||||
tgt->func_def(this);
|
||||
flag &= tgt->func_def(this);
|
||||
break;
|
||||
case TASK:
|
||||
tgt->task_def(this);
|
||||
break;
|
||||
default: /* BEGIN_END and FORK_JOIN, do nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
|
||||
@@ -359,42 +386,50 @@ void NetWhile::emit_proc_recurse(struct target_t*tgt) const
|
||||
proc_->emit_proc(tgt);
|
||||
}
|
||||
|
||||
bool Design::emit(struct target_t*tgt) const
|
||||
int Design::emit(struct target_t*tgt) const
|
||||
{
|
||||
bool rc = true;
|
||||
int rc = 0;
|
||||
|
||||
rc = rc && tgt->start_design(this);
|
||||
if (rc == false)
|
||||
return false;
|
||||
if (tgt->start_design(this) == false)
|
||||
return -2;
|
||||
|
||||
// enumerate the scopes
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->emit_scope(tgt);
|
||||
|
||||
|
||||
// emit nodes
|
||||
bool nodes_rc = true;
|
||||
if (nodes_) {
|
||||
NetNode*cur = nodes_->node_next_;
|
||||
do {
|
||||
rc = rc && cur->emit_node(tgt);
|
||||
nodes_rc = nodes_rc && cur->emit_node(tgt);
|
||||
cur = cur->node_next_;
|
||||
} while (cur != nodes_->node_next_);
|
||||
}
|
||||
|
||||
|
||||
// emit task and function definitions
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
bool tasks_rc = true;
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->emit_defs(tgt);
|
||||
tasks_rc &= (*scope)->emit_defs(tgt);
|
||||
|
||||
|
||||
// emit the processes
|
||||
bool proc_rc = true;
|
||||
for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
|
||||
rc = rc && idx->emit(tgt);
|
||||
proc_rc &= idx->emit(tgt);
|
||||
|
||||
if (tgt->end_design(this) != 0)
|
||||
rc = false;
|
||||
rc = tgt->end_design(this);
|
||||
|
||||
if (nodes_rc == false)
|
||||
return -1;
|
||||
if (tasks_rc == false)
|
||||
return -2;
|
||||
if (proc_rc == false)
|
||||
return -3;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -429,11 +464,6 @@ void NetECRealParam::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_rparam(this);
|
||||
}
|
||||
|
||||
void NetEMemory::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_memory(this);
|
||||
}
|
||||
|
||||
void NetEParam::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
cerr << get_line() << ":internal error: unexpected NetEParam."
|
||||
@@ -470,11 +500,6 @@ void NetESignal::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_signal(this);
|
||||
}
|
||||
|
||||
void NetEBitSel::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_subsignal(this);
|
||||
}
|
||||
|
||||
void NetETernary::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_ternary(this);
|
||||
@@ -485,12 +510,7 @@ void NetEUnary::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_unary(this);
|
||||
}
|
||||
|
||||
void NetEVariable::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_variable(this);
|
||||
}
|
||||
|
||||
bool emit(const Design*des, const char*type)
|
||||
int emit(const Design*des, const char*type)
|
||||
{
|
||||
for (unsigned idx = 0 ; target_table[idx] ; idx += 1) {
|
||||
const struct target*tgt = target_table[idx];
|
||||
@@ -501,12 +521,71 @@ bool emit(const Design*des, const char*type)
|
||||
|
||||
cerr << "error: Code generator type " << type
|
||||
<< " not found." << endl;
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.89 2007/01/16 05:44:15 steve
|
||||
* Major rework of array handling. Memories are replaced with the
|
||||
* more general concept of arrays. The NetMemory and NetEMemory
|
||||
* classes are removed from the ivl core program, and the IVL_LPM_RAM
|
||||
* lpm type is removed from the ivl_target API.
|
||||
*
|
||||
* Revision 1.88 2006/11/10 05:44:44 steve
|
||||
* Process delay paths in second path over signals.
|
||||
*
|
||||
* Revision 1.87 2006/06/18 04:15:50 steve
|
||||
* Add support for system functions in continuous assignments.
|
||||
*
|
||||
* Revision 1.86 2005/07/11 16:56:50 steve
|
||||
* Remove NetVariable and ivl_variable_t structures.
|
||||
*
|
||||
* Revision 1.85 2005/07/07 16:22:49 steve
|
||||
* Generalize signals to carry types.
|
||||
*
|
||||
* Revision 1.84 2005/05/24 01:44:27 steve
|
||||
* Do sign extension of structuran nets.
|
||||
*
|
||||
* Revision 1.83 2005/02/08 00:12:36 steve
|
||||
* Add the NetRepeat node, and code generator support.
|
||||
*
|
||||
* Revision 1.82 2005/02/03 04:56:20 steve
|
||||
* laborate reduction gates into LPM_RED_ nodes.
|
||||
*
|
||||
* Revision 1.81 2005/01/24 05:28:30 steve
|
||||
* Remove the NetEBitSel and combine all bit/part select
|
||||
* behavior into the NetESelect node and IVL_EX_SELECT
|
||||
* ivl_target expression type.
|
||||
*
|
||||
* Revision 1.80 2005/01/22 01:06:55 steve
|
||||
* Change case compare from logic to an LPM node.
|
||||
*
|
||||
* Revision 1.79 2004/12/29 23:55:43 steve
|
||||
* Unify elaboration of l-values for all proceedural assignments,
|
||||
* including assing, cassign and force.
|
||||
*
|
||||
* Generate NetConcat devices for gate outputs that feed into a
|
||||
* vector results. Use this to hande gate arrays. Also let gate
|
||||
* arrays handle vectors of gates when the outputs allow for it.
|
||||
*
|
||||
* Revision 1.78 2004/12/11 02:31:26 steve
|
||||
* Rework of internals to carry vectors through nexus instead
|
||||
* of single bits. Make the ivl, tgt-vvp and vvp initial changes
|
||||
* down this path.
|
||||
*
|
||||
* Revision 1.77 2004/10/04 01:10:53 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.76 2004/05/31 23:34:37 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.75 2003/09/13 01:30:07 steve
|
||||
* Missing case warnings.
|
||||
*
|
||||
* Revision 1.74 2003/05/30 02:55:32 steve
|
||||
* Support parameters in real expressions and
|
||||
* as real expressions, and fix multiply and
|
||||
@@ -521,131 +600,5 @@ bool emit(const Design*des, const char*type)
|
||||
* Revision 1.71 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.70 2002/11/03 20:36:10 steve
|
||||
* Error message for mising code generator type.
|
||||
*
|
||||
* Revision 1.69 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.68 2002/06/05 03:44:25 steve
|
||||
* Add support for memory words in l-value of
|
||||
* non-blocking assignments, and remove the special
|
||||
* NetAssignMem_ and NetAssignMemNB classes.
|
||||
*
|
||||
* Revision 1.67 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.66 2002/03/09 02:10:22 steve
|
||||
* Add the NetUserFunc netlist node.
|
||||
*
|
||||
* Revision 1.65 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.64 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.63 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.62 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.61 2001/07/27 04:51:44 steve
|
||||
* Handle part select expressions as variants of
|
||||
* NetESignal/IVL_EX_SIGNAL objects, instead of
|
||||
* creating new and useless temporary signals.
|
||||
*
|
||||
* Revision 1.60 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.59 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.58 2001/04/06 02:28:02 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
*
|
||||
* Revision 1.57 2001/04/02 02:28:12 steve
|
||||
* Generate code for task calls.
|
||||
*
|
||||
* Revision 1.56 2001/03/27 03:31:06 steve
|
||||
* Support error code from target_t::end_design method.
|
||||
*
|
||||
* Revision 1.55 2000/11/04 01:54:01 steve
|
||||
* Modifications in support of gcc 2.96
|
||||
*
|
||||
* Revision 1.54 2000/09/26 01:35:42 steve
|
||||
* Remove the obsolete NetEIdent class.
|
||||
*
|
||||
* Revision 1.53 2000/09/17 21:26:15 steve
|
||||
* Add support for modulus (Eric Aardoom)
|
||||
*
|
||||
* Revision 1.52 2000/09/02 20:54:20 steve
|
||||
* Rearrange NetAssign to make NetAssign_ separate.
|
||||
*
|
||||
* Revision 1.51 2000/08/14 04:39:56 steve
|
||||
* add th t-dll functions for net_const, net_bufz and processes.
|
||||
*
|
||||
* Revision 1.50 2000/08/09 03:43:45 steve
|
||||
* Move all file manipulation out of target class.
|
||||
*
|
||||
* Revision 1.49 2000/08/08 01:50:42 steve
|
||||
* target methods need not take a file stream.
|
||||
*
|
||||
* Revision 1.48 2000/07/30 18:25:43 steve
|
||||
* Rearrange task and function elaboration so that the
|
||||
* NetTaskDef and NetFuncDef functions are created during
|
||||
* signal enaboration, and carry these objects in the
|
||||
* NetScope class instead of the extra, useless map in
|
||||
* the Design class.
|
||||
*
|
||||
* Revision 1.47 2000/07/29 16:21:08 steve
|
||||
* Report code generation errors through proc_delay.
|
||||
*
|
||||
* Revision 1.46 2000/07/27 05:13:44 steve
|
||||
* Support elaboration of disable statements.
|
||||
*
|
||||
* Revision 1.45 2000/05/11 23:37:27 steve
|
||||
* Add support for procedural continuous assignment.
|
||||
*
|
||||
* Revision 1.44 2000/05/04 03:37:58 steve
|
||||
* Add infrastructure for system functions, move
|
||||
* $time to that structure and add $random.
|
||||
*
|
||||
* Revision 1.43 2000/05/02 03:13:31 steve
|
||||
* Move memories to the NetScope object.
|
||||
*
|
||||
* Revision 1.42 2000/05/02 00:58:12 steve
|
||||
* Move signal tables to the NetScope class.
|
||||
*
|
||||
* Revision 1.41 2000/04/23 03:45:24 steve
|
||||
* Add support for the procedural release statement.
|
||||
*
|
||||
* Revision 1.40 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.39 2000/04/12 04:23:58 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.
|
||||
*/
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval.cc,v 1.36 2003/06/21 01:21:43 steve Exp $"
|
||||
#ident "$Id: eval.cc,v 1.47 2007/06/04 19:14:06 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -26,14 +26,15 @@
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "compiler.h"
|
||||
|
||||
verinum* PExpr::eval_const(const Design*, const NetScope*) const
|
||||
verinum* PExpr::eval_const(Design*, NetScope*) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||
verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
|
||||
{
|
||||
verinum*l = left_->eval_const(des, scope);
|
||||
if (l == 0) return 0;
|
||||
@@ -142,16 +143,51 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||
delete r;
|
||||
return res;
|
||||
}
|
||||
verinum* PEConcat::eval_const(Design*des, NetScope*scope) const
|
||||
{
|
||||
verinum*accum = parms_[0]->eval_const(des, scope);
|
||||
if (accum == 0)
|
||||
return 0;
|
||||
|
||||
for (unsigned idx = 1 ; idx < parms_.count() ; idx += 1) {
|
||||
|
||||
verinum*tmp = parms_[idx]->eval_const(des, scope);
|
||||
if (tmp == 0) {
|
||||
delete accum;
|
||||
return 0;
|
||||
}
|
||||
assert(tmp);
|
||||
|
||||
*accum = concat(*accum, *tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
return accum;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 NetScope*scope) const
|
||||
verinum* PEIdent::eval_const(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope);
|
||||
const NetExpr*expr = des->find_parameter(scope, path_);
|
||||
NetNet*net;
|
||||
NetEvent*eve;
|
||||
const NetExpr*expr;
|
||||
|
||||
const name_component_t&name_tail = path_.back();
|
||||
|
||||
// Handle the special case that this ident is a genvar
|
||||
// variable name. In that case, the genvar meaning preempts
|
||||
// everything and we just return that value immediately.
|
||||
if (scope->genvar_tmp
|
||||
&& strcmp(name_tail.name,scope->genvar_tmp) == 0) {
|
||||
return new verinum(scope->genvar_tmp_val);
|
||||
}
|
||||
|
||||
symbol_search(des, scope, path_, net, expr, eve);
|
||||
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
@@ -166,30 +202,30 @@ verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
|
||||
|
||||
assert(eval);
|
||||
|
||||
if (msb_ || lsb_)
|
||||
if (!name_tail.index.empty())
|
||||
return 0;
|
||||
|
||||
|
||||
return new verinum(eval->value());
|
||||
}
|
||||
|
||||
verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
|
||||
verinum* PEFNumber::eval_const(Design*, NetScope*) const
|
||||
{
|
||||
long val = value_->as_long();
|
||||
return new verinum(val);
|
||||
}
|
||||
|
||||
verinum* PENumber::eval_const(const Design*, const NetScope*) const
|
||||
verinum* PENumber::eval_const(Design*, NetScope*) const
|
||||
{
|
||||
return new verinum(value());
|
||||
}
|
||||
|
||||
verinum* PEString::eval_const(const Design*, const NetScope*) const
|
||||
verinum* PEString::eval_const(Design*, NetScope*) const
|
||||
{
|
||||
return new verinum(string(text_));
|
||||
}
|
||||
|
||||
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
|
||||
verinum* PETernary::eval_const(Design*des, NetScope*scope) const
|
||||
{
|
||||
verinum*test = expr_->eval_const(des, scope);
|
||||
if (test == 0)
|
||||
@@ -209,7 +245,7 @@ verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
|
||||
}
|
||||
}
|
||||
|
||||
verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
|
||||
verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
|
||||
{
|
||||
verinum*val = expr_->eval_const(des, scope);
|
||||
if (val == 0)
|
||||
@@ -223,7 +259,7 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
|
||||
/* 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);
|
||||
verinum tmp ((uint64_t)0, val->len()+1);
|
||||
for (unsigned idx = 0 ; idx < val->len() ; idx += 1)
|
||||
tmp.set(idx, val->get(idx));
|
||||
|
||||
@@ -240,6 +276,43 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: eval.cc,v $
|
||||
* Revision 1.47 2007/06/04 19:14:06 steve
|
||||
* Build errors in picky GCC compilers.
|
||||
*
|
||||
* Revision 1.46 2007/05/24 04:07:12 steve
|
||||
* Rework the heirarchical identifier parse syntax and pform
|
||||
* to handle more general combinations of heirarch and bit selects.
|
||||
*
|
||||
* Revision 1.45 2007/03/07 00:38:15 steve
|
||||
* Lint fixes.
|
||||
*
|
||||
* Revision 1.44 2007/01/16 05:44:15 steve
|
||||
* Major rework of array handling. Memories are replaced with the
|
||||
* more general concept of arrays. The NetMemory and NetEMemory
|
||||
* classes are removed from the ivl core program, and the IVL_LPM_RAM
|
||||
* lpm type is removed from the ivl_target API.
|
||||
*
|
||||
* Revision 1.43 2006/08/08 05:11:37 steve
|
||||
* Handle 64bit delay constants.
|
||||
*
|
||||
* Revision 1.42 2006/05/19 04:07:24 steve
|
||||
* eval_const is not strict.
|
||||
*
|
||||
* Revision 1.41 2006/05/17 16:49:30 steve
|
||||
* Error message if concat expression cannot evaluate.
|
||||
*
|
||||
* Revision 1.40 2006/04/10 00:37:42 steve
|
||||
* Add support for generate loops w/ wires and gates.
|
||||
*
|
||||
* Revision 1.39 2005/12/07 04:04:23 steve
|
||||
* Allow constant concat expressions.
|
||||
*
|
||||
* Revision 1.38 2005/11/27 17:01:57 steve
|
||||
* Fix for stubborn compiler.
|
||||
*
|
||||
* Revision 1.37 2005/11/27 05:56:20 steve
|
||||
* Handle bit select of parameter with ranges.
|
||||
*
|
||||
* Revision 1.36 2003/06/21 01:21:43 steve
|
||||
* Harmless fixup of warnings.
|
||||
*
|
||||
|
||||
+14
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval_attrib.cc,v 1.6 2003/01/27 05:09:17 steve Exp $"
|
||||
#ident "$Id: eval_attrib.cc,v 1.9 2007/06/04 19:14:06 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -33,10 +33,9 @@
|
||||
* for passing to netlist devices.
|
||||
*/
|
||||
|
||||
attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
|
||||
attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
|
||||
unsigned&natt,
|
||||
const Design*des,
|
||||
const NetScope*scope)
|
||||
Design*des, NetScope*scope)
|
||||
{
|
||||
natt = att.size();
|
||||
if (natt == 0)
|
||||
@@ -46,7 +45,7 @@ attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
|
||||
|
||||
unsigned idx = 0;
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator iter_t;
|
||||
typedef map<perm_string,PExpr*>::const_iterator iter_t;
|
||||
for (iter_t cur = att.begin() ; cur != att.end() ; cur ++, idx++) {
|
||||
table[idx].key = (*cur).first;
|
||||
PExpr*exp = (*cur).second;
|
||||
@@ -74,6 +73,15 @@ attrib_list_t* evaluate_attributes(const map<string,PExpr*>&att,
|
||||
|
||||
/*
|
||||
* $Log: eval_attrib.cc,v $
|
||||
* Revision 1.9 2007/06/04 19:14:06 steve
|
||||
* Build errors in picky GCC compilers.
|
||||
*
|
||||
* Revision 1.8 2005/11/27 17:01:57 steve
|
||||
* Fix for stubborn compiler.
|
||||
*
|
||||
* Revision 1.7 2004/02/20 18:53:35 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.6 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
|
||||
+494
-227
File diff suppressed because it is too large
Load Diff
+8
-8
@@ -218,11 +218,11 @@ output [1:48] k;
|
||||
wire [1:56] YY;
|
||||
|
||||
assign YY[1:28]=c; assign YY[29:56]=d;
|
||||
|
||||
|
||||
assign k[1]=YY[14]; assign k[2]=YY[17]; assign k[3]=YY[11]; assign k[4]=YY[24]; assign k[5]=YY[1]; assign k[6]=YY[5];
|
||||
assign k[7]=YY[3]; assign k[8]=YY[28]; assign k[9]=YY[15]; assign k[10]=YY[6]; assign k[11]=YY[21]; assign k[12]=YY[10];
|
||||
assign k[13]=YY[23]; assign k[14]=YY[19]; assign k[15]=YY[12]; assign k[16]=YY[4]; assign k[17]=YY[26]; assign k[18]=YY[8];
|
||||
assign k[19]=YY[16]; assign k[20]=YY[7]; assign k[21]=YY[27]; assign k[22]=YY[20]; assign k[23]=YY[13]; assign k[24]=YY[2];
|
||||
assign k[13]=YY[23]; assign k[14]=YY[19]; assign k[15]=YY[12]; assign k[16]=YY[4]; assign k[17]=YY[26]; assign k[18]=YY[8];
|
||||
assign k[19]=YY[16]; assign k[20]=YY[7]; assign k[21]=YY[27]; assign k[22]=YY[20]; assign k[23]=YY[13]; assign k[24]=YY[2];
|
||||
assign k[25]=YY[41]; assign k[26]=YY[52]; assign k[27]=YY[31]; assign k[28]=YY[37]; assign k[29]=YY[47]; assign k[30]=YY[55];
|
||||
assign k[31]=YY[30]; assign k[32]=YY[40]; assign k[33]=YY[51]; assign k[34]=YY[45]; assign k[35]=YY[33]; assign k[36]=YY[48];
|
||||
assign k[37]=YY[44]; assign k[38]=YY[49]; assign k[39]=YY[39]; assign k[40]=YY[56]; assign k[41]=YY[34]; assign k[42]=YY[53];
|
||||
@@ -252,13 +252,13 @@ input [1:64] key;
|
||||
output [1:48] k1x,k2x,k3x,k4x,k5x,k6x,k7x,k8x,k9x,k10x,k11x,k12x,k13x,k14x,k15x,k16x;
|
||||
wire [1:28] c0x,c1x,c2x,c3x,c4x,c5x,c6x,c7x,c8x,c9x,c10x,c11x,c12x,c13x,c14x,c15x,c16x;
|
||||
wire [1:28] d0x,d1x,d2x,d3x,d4x,d5x,d6x,d7x,d8x,d9x,d10x,d11x,d12x,d13x,d14x,d15x,d16x;
|
||||
|
||||
|
||||
pc1 pc1(key, c0x, d0x);
|
||||
|
||||
rol1 rc1(c1x, c0x); rol1 rd1(d1x, d0x);
|
||||
rol1 rc2(c2x, c1x); rol1 rd2(d2x, d1x);
|
||||
rol2 rc3(c3x, c2x); rol2 rd3(d3x, d2x);
|
||||
rol2 rc4(c4x, c3x); rol2 rd4(d4x, d3x);
|
||||
rol2 rc4(c4x, c3x); rol2 rd4(d4x, d3x);
|
||||
rol2 rc5(c5x, c4x); rol2 rd5(d5x, d4x);
|
||||
rol2 rc6(c6x, c5x); rol2 rd6(d6x, d5x);
|
||||
rol2 rc7(c7x, c6x); rol2 rd7(d7x, d6x);
|
||||
@@ -272,7 +272,7 @@ rol2 rce(c14x, c13x); rol2 rde(d14x, d13x);
|
||||
rol2 rcf(c15x, c14x); rol2 rdf(d15x, d14x);
|
||||
rol1 rcg(c16x, c15x); rol1 rdg(d16x, d15x);
|
||||
|
||||
|
||||
|
||||
pc2 pc2x1(c1x,d1x,k1x);
|
||||
pc2 pc2x2(c2x,d2x,k2x);
|
||||
pc2 pc2x3(c3x,d3x,k3x);
|
||||
@@ -913,7 +913,7 @@ assign l0x[17]=pt[62]; assign l0x[18]=pt[54]; assign l0x[19]=pt[46
|
||||
assign l0x[21]=pt[30]; assign l0x[22]=pt[22]; assign l0x[23]=pt[14]; assign l0x[24]=pt[6];
|
||||
assign l0x[25]=pt[64]; assign l0x[26]=pt[56]; assign l0x[27]=pt[48]; assign l0x[28]=pt[40];
|
||||
assign l0x[29]=pt[32]; assign l0x[30]=pt[24]; assign l0x[31]=pt[16]; assign l0x[32]=pt[8];
|
||||
|
||||
|
||||
assign r0x[1]=pt[57]; assign r0x[2]=pt[49]; assign r0x[3]=pt[41]; assign r0x[4]=pt[33];
|
||||
assign r0x[5]=pt[25]; assign r0x[6]=pt[17]; assign r0x[7]=pt[9]; assign r0x[8]=pt[1];
|
||||
assign r0x[9]=pt[59]; assign r0x[10]=pt[51]; assign r0x[11]=pt[43]; assign r0x[12]=pt[35];
|
||||
@@ -935,7 +935,7 @@ assign e[9]=ri[6]; assign e[10]=ri[7]; assign e[11]=ri[8]; assign e[12]=r
|
||||
assign e[17]=ri[12]; assign e[18]=ri[13]; assign e[19]=ri[12]; assign e[20]=ri[13]; assign e[21]=ri[14]; assign e[22]=ri[15]; assign e[23]=ri[16]; assign e[24]=ri[17];
|
||||
assign e[25]=ri[16]; assign e[26]=ri[17]; assign e[27]=ri[18]; assign e[28]=ri[19]; assign e[29]=ri[20]; assign e[30]=ri[21]; assign e[31]=ri[20]; assign e[32]=ri[21];
|
||||
assign e[33]=ri[22]; assign e[34]=ri[23]; assign e[35]=ri[24]; assign e[36]=ri[25]; assign e[37]=ri[24]; assign e[38]=ri[25]; assign e[39]=ri[26]; assign e[40]=ri[27];
|
||||
assign e[41]=ri[28]; assign e[42]=ri[29]; assign e[43]=ri[28]; assign e[44]=ri[29]; assign e[45]=ri[30]; assign e[46]=ri[31]; assign e[47]=ri[32]; assign e[48]=ri[1];
|
||||
assign e[41]=ri[28]; assign e[42]=ri[29]; assign e[43]=ri[28]; assign e[44]=ri[29]; assign e[45]=ri[30]; assign e[46]=ri[31]; assign e[47]=ri[32]; assign e[48]=ri[1];
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
+5
-5
@@ -26,21 +26,21 @@
|
||||
* Compile this program with the command:
|
||||
*
|
||||
* iverilog -ohello hello.vl
|
||||
*
|
||||
*
|
||||
* After churning for a little while, the program will create the output
|
||||
* file "hello" which is compiled, linked and ready to run. Run this
|
||||
* program like so:
|
||||
*
|
||||
*
|
||||
* vvp hello
|
||||
*
|
||||
*
|
||||
* and the program will print the message to its output. Easy! For
|
||||
* more on how to make the iverilog command work, see the iverilog
|
||||
* manual page.
|
||||
*/
|
||||
|
||||
module main();
|
||||
|
||||
initial
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hello, World");
|
||||
$finish ;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* 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 $"
|
||||
#ident "$Id: hello_vpi.c,v 1.5 2007/01/17 05:35:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
# include <vpi_user.h>
|
||||
|
||||
static int my_hello_calltf(char *xx)
|
||||
static PLI_INT32 my_hello_calltf(char *xx)
|
||||
{
|
||||
vpi_printf("Hello World, from VPI.\n");
|
||||
return 0;
|
||||
@@ -62,6 +62,12 @@ void (*vlog_startup_routines[])() = {
|
||||
};
|
||||
/*
|
||||
* $Log: hello_vpi.c,v $
|
||||
* Revision 1.5 2007/01/17 05:35:48 steve
|
||||
* Fix typo is hello_vpi.c example.
|
||||
*
|
||||
* Revision 1.4 2006/10/30 22:46:25 steve
|
||||
* Updates for Cygwin portability (pr1585922)
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
@@ -26,21 +26,21 @@
|
||||
* 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
|
||||
|
||||
initial
|
||||
begin
|
||||
$my_hello;
|
||||
$finish ;
|
||||
|
||||
+11
-11
@@ -20,36 +20,36 @@
|
||||
/*
|
||||
* This example program simulates a 16x1 ram, and is used as an
|
||||
* example for using VCD output and waveform viewers.
|
||||
*
|
||||
*
|
||||
* Like any other Verilog simulation, compile this program with the
|
||||
* command:
|
||||
*
|
||||
*
|
||||
* iverilog show_vcd.vl
|
||||
*
|
||||
*
|
||||
* This will generate the show_vcd command in the current directory.
|
||||
* When you run the command, you will see the output from all the
|
||||
* calls to $display, but also there will be a dump file ``show_vcd.vcd''.
|
||||
* The name of this file is set by the statement:
|
||||
*
|
||||
* $dumpfile("show_vcd.vcd");
|
||||
*
|
||||
*
|
||||
* in the main module. The output file uses the standard VCD file format
|
||||
* so can be viewed using off-the-shelf waveform viewers. The remaining
|
||||
* steps describe how to use GTKWave to view the file. If you are using
|
||||
* a different viewer, see the documentation for that tool.
|
||||
*
|
||||
*
|
||||
* To view the output generated by running show_vcd, start the GTKWave
|
||||
* viewer with the command:
|
||||
*
|
||||
*
|
||||
* gtkwave show_vcd.vcd
|
||||
*
|
||||
*
|
||||
* The GTKWave program will display its main window, and show in a small
|
||||
* status box (upper left corner) that it succeeded in loading the dump
|
||||
* file. However, there are no waveforms displayed yet. Select signals to
|
||||
* add to the waveform display using the menu selection:
|
||||
*
|
||||
* "Search --> Signal Search Tree"
|
||||
*
|
||||
*
|
||||
* This will bring up a dialog box that shows in directory tree format
|
||||
* the signals of the program. Select the signals you wish to view, and
|
||||
* click one of the buttons on the bottom of the dialog box to display
|
||||
@@ -60,7 +60,7 @@
|
||||
* $dumpvars system tasks. The $dumpfile task tells the simulation where
|
||||
* to write the VCD output. This task must be called once before the
|
||||
* $dumpvars task is called.
|
||||
*
|
||||
*
|
||||
* The $dumpvars task tells the simulation what variables to write to
|
||||
* the VCD output. The first parameter is how far to descend while
|
||||
* scanning a scope, and the remaining paramters are signals or scope
|
||||
@@ -77,7 +77,7 @@ module ram16x1 (q, d, a, we, wclk);
|
||||
input wclk;
|
||||
|
||||
reg mem[15:0];
|
||||
|
||||
|
||||
assign q = mem[a];
|
||||
always @(posedge wclk) if (we) mem[a] = d;
|
||||
|
||||
@@ -88,7 +88,7 @@ module main;
|
||||
reg d;
|
||||
reg [3:0] a;
|
||||
reg we, wclk;
|
||||
|
||||
|
||||
ram16x1 r1 (q, d, a, we, wclk);
|
||||
|
||||
initial begin
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $Id: sqrt-virtex.v,v 1.3 2003/07/05 20:22:18 steve Exp $"
|
||||
* $Id: sqrt-virtex.v,v 1.5 2007/03/22 16:08:18 steve Exp $"
|
||||
*/
|
||||
|
||||
/*
|
||||
* This module is a synthesizeable square-root function. It is also a
|
||||
* detailed example of how to target Xilinx Virtex parts using
|
||||
* Icarus Verilog. In fact, for no particular reason other then to
|
||||
* Icarus Verilog. In fact, for no particular reason other than to
|
||||
* be excessively specific, I will step through the process of
|
||||
* generating a design for a Spartan-II XC2S15-VQ100, and also how to
|
||||
* generate a generic library part for larger Virtex designs.
|
||||
@@ -129,7 +129,7 @@
|
||||
* This command creates from the chip.ngd the file "chip_root.v" that
|
||||
* contains Verilog code that simulates the mapped design. This output
|
||||
* Verilog has the single root module "chip_root", which came from the
|
||||
* name of the root module when we were making hte EDIF file in the
|
||||
* name of the root module when we were making the EDIF file in the
|
||||
* first place. The module has ports named just line the ports of the
|
||||
* chip_root module below.
|
||||
*
|
||||
@@ -183,7 +183,7 @@
|
||||
* where sqrt(y) is the exact square root of y and floor(N) is the
|
||||
* largest integer <= N.
|
||||
*
|
||||
* For 32bit numbers, this will never run more then 16 iterations,
|
||||
* For 32 bit numbers, this will never run more than 16 iterations,
|
||||
* which amounts to 16 clocks.
|
||||
*/
|
||||
|
||||
@@ -269,6 +269,7 @@ module main;
|
||||
task reset_dut;
|
||||
begin
|
||||
reset = 1;
|
||||
@(posedge clk) ;
|
||||
#1 reset = 0;
|
||||
@(negedge clk) ;
|
||||
end
|
||||
|
||||
+6
-6
@@ -16,7 +16,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $Id: sqrt.vl,v 1.3 2000/11/04 01:53:24 steve Exp $"
|
||||
* $Id: sqrt.vl,v 1.5 2007/03/22 16:08:18 steve Exp $"
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -50,7 +50,7 @@
|
||||
* where sqrt(y) is the exact square root of y and floor(N) is the
|
||||
* largest integer <= N.
|
||||
*
|
||||
* For 32bit numbers, this will never run more then 16 iterations,
|
||||
* For 32 bit numbers, this will never run more than 16 iterations,
|
||||
* which amounts to 16 clocks.
|
||||
*/
|
||||
|
||||
@@ -97,8 +97,8 @@ module sqrt32(clk, rdy, reset, x, .y(acc));
|
||||
bitl = 15;
|
||||
end
|
||||
endtask
|
||||
|
||||
initial clear;
|
||||
|
||||
initial clear;
|
||||
|
||||
always @(reset or posedge clk)
|
||||
if (reset)
|
||||
@@ -121,14 +121,14 @@ module main;
|
||||
wire rdy;
|
||||
|
||||
sqrt32 root(.clk(clk), .rdy(rdy), .reset(reset), .x(value), .y(result));
|
||||
|
||||
|
||||
always #5 clk = ~clk;
|
||||
|
||||
always @(posedge rdy) begin
|
||||
$display("sqrt(%d) --> %d", value, result);
|
||||
$finish;
|
||||
end
|
||||
|
||||
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ module main;
|
||||
// This can be done to wires and registers, as internally both
|
||||
// are treated as named signals. It doesn't work (yet) on vectors,
|
||||
// though, so break out the vectors with scalar assignments.
|
||||
|
||||
|
||||
assign a[0] = a0;
|
||||
assign a[1] = a1;
|
||||
assign a[2] = a2;
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ module ram16x1 (q, d, a, we, wclk);
|
||||
input wclk;
|
||||
|
||||
reg mem[15:0];
|
||||
|
||||
|
||||
assign q = mem[a];
|
||||
always @(posedge wclk) if (we) mem[a] = d;
|
||||
|
||||
@@ -39,7 +39,7 @@ module main;
|
||||
reg d;
|
||||
reg [3:0] a;
|
||||
reg we, wclk;
|
||||
|
||||
|
||||
ram16x1 r1 (q, d, a, we, wclk);
|
||||
|
||||
initial begin
|
||||
|
||||
+490
-302
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
|
||||
Icarus Verilog Extensions
|
||||
|
||||
Icarus Verilog supports certain extensions to the baseline IEEE1364
|
||||
standard. Some of these are picked from extended variants of the
|
||||
language, such as SystemVerilog, and some are expressions of internal
|
||||
behavior of Icarus Verilog, made available as a tool debugging aid.
|
||||
|
||||
* Builtin System Functions
|
||||
|
||||
** Extended Verilog Data Types
|
||||
|
||||
This feature is turned off if the generation flag "-g" is set to other
|
||||
then the default "2x". For example, "iverilog -g2x" enables extended
|
||||
data types, and "iverilog -g2" disables them.
|
||||
|
||||
Icarus Verilog adds support for extended data types. This extended
|
||||
type syntax is based on a proposal by Cadence Design Systems,
|
||||
originally as an update to the IEEE1364. That original proposal has
|
||||
apparently been absorbed by the IEEE1800 SystemVerilog
|
||||
standard. Icarus Verilog currently only takes the new primitive types
|
||||
from the proposal.
|
||||
|
||||
Extended data types separates the concept of net/variable from the
|
||||
data type. Both nets and variables can declared with any data
|
||||
type. The primitive types available are:
|
||||
|
||||
logic - The familiar 0, 1, x and z, optionally with strength.
|
||||
bool - Limited to only 0 and 1
|
||||
real - 64bit real values
|
||||
|
||||
Nets with logic type may have multiple drivers with strength, and the
|
||||
value is resolved the usual way. Only logic values may be driven to
|
||||
logic nets, so bool values driven onto logic nets are implicitly
|
||||
converted to logic.
|
||||
|
||||
Nets with any other type may not have multiple drivers. The compiler
|
||||
should detect the multiple drivers and report an error.
|
||||
|
||||
- Declarations
|
||||
|
||||
The declaration of a net is extended to include the type of the wire,
|
||||
with the syntax:
|
||||
|
||||
wire <type> <wire-assignment-list>... ;
|
||||
|
||||
The <type>, if omitted, is taken to be logic. The "wire" can be any of
|
||||
the net keywords. Wires can be logic, bool, real, or vectors of logic
|
||||
or bool. Some valid examples:
|
||||
|
||||
wire real foo = 1.0;
|
||||
tri logic bus[31:0];
|
||||
wire bool addr[23:0];
|
||||
... and so on.
|
||||
|
||||
The declarations of variables is similar. The "reg" keyword is used to
|
||||
specify that this is a variable. Variables can have the same data
|
||||
types as nets.
|
||||
|
||||
- Ports
|
||||
|
||||
Module and task ports in standard verilog are restricted to logic
|
||||
types. This extension removes that restriction, allowing any type to
|
||||
pass through the port consistent with the continuous assignment
|
||||
connectivity that is implied by the type.
|
||||
|
||||
- Expressions
|
||||
|
||||
Expressions in the face of real values is covered by the baseline
|
||||
Verilog standard.
|
||||
|
||||
The bool type supports the same operators as the logic type, with the
|
||||
obvious differences imposed by the limited domain.
|
||||
|
||||
Comparison operators (not case compare) return logic if either of
|
||||
their operands is logic. If both are bool or real (including mix of
|
||||
bool and real) then the result is bool. This is because comparison of
|
||||
bools and reals always return exactly true or false.
|
||||
|
||||
Case comparison returns bool. This differs from baseline Verilog,
|
||||
which strictly speaking returns a logic, but only 0 or 1 values.
|
||||
|
||||
All the arithmetic operators return bool if both of their operands are
|
||||
bool or real. Otherwise, they return logic.
|
||||
+42
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2002 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2005 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,7 +17,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: functor.cc,v 1.31 2002/08/16 05:18:27 steve Exp $"
|
||||
#ident "$Id: functor.cc,v 1.35 2005/07/07 16:22:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -59,6 +59,10 @@ void functor_t::lpm_divide(class Design*, class NetDivide*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_literal(class Design*, class NetLiteral*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_modulo(class Design*, class NetModulo*)
|
||||
{
|
||||
}
|
||||
@@ -79,6 +83,14 @@ void functor_t::lpm_mux(class Design*, class NetMux*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::sign_extend(class Design*, class NetSignExtend*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_ureduce(class Design*, class NetUReduce*)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void NetScope::run_functor(Design*des, functor_t*fun)
|
||||
{
|
||||
@@ -114,7 +126,7 @@ void NetScope::run_functor(Design*des, functor_t*fun)
|
||||
void Design::functor(functor_t*fun)
|
||||
{
|
||||
// Scan the scopes
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->run_functor(this, fun);
|
||||
|
||||
@@ -186,6 +198,11 @@ void NetFF::functor_node(Design*des, functor_t*fun)
|
||||
fun->lpm_ff(des, this);
|
||||
}
|
||||
|
||||
void NetLiteral::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_literal(des, this);
|
||||
}
|
||||
|
||||
void NetLogic::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_logic(des, this);
|
||||
@@ -206,6 +223,16 @@ void NetMux::functor_node(Design*des, functor_t*fun)
|
||||
fun->lpm_mux(des, this);
|
||||
}
|
||||
|
||||
void NetSignExtend::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->sign_extend(des, this);
|
||||
}
|
||||
|
||||
void NetUReduce::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_ureduce(des, this);
|
||||
}
|
||||
|
||||
proc_match_t::~proc_match_t()
|
||||
{
|
||||
}
|
||||
@@ -267,6 +294,18 @@ int proc_match_t::event_wait(NetEvWait*)
|
||||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.35 2005/07/07 16:22:49 steve
|
||||
* Generalize signals to carry types.
|
||||
*
|
||||
* Revision 1.34 2005/05/24 01:44:27 steve
|
||||
* Do sign extension of structuran nets.
|
||||
*
|
||||
* Revision 1.33 2005/02/03 04:56:20 steve
|
||||
* laborate reduction gates into LPM_RED_ nodes.
|
||||
*
|
||||
* Revision 1.32 2004/10/04 01:10:53 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.31 2002/08/16 05:18:27 steve
|
||||
* Fix intermix of node functors and node delete.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __functor_H
|
||||
#define __functor_H
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2005 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: functor.h,v 1.20 2002/08/12 01:34:59 steve Exp $"
|
||||
#ident "$Id: functor.h,v 1.23 2005/07/07 16:22:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -63,6 +63,9 @@ struct functor_t {
|
||||
/* This method is called for each structural constant. */
|
||||
virtual void lpm_divide(class Design*des, class NetDivide*);
|
||||
|
||||
/* Constant literals. */
|
||||
virtual void lpm_literal(class Design*des, class NetLiteral*);
|
||||
|
||||
/* This method is called for each structural constant. */
|
||||
virtual void lpm_modulo(class Design*des, class NetModulo*);
|
||||
|
||||
@@ -77,6 +80,11 @@ struct functor_t {
|
||||
|
||||
/* This method is called for each MUX. */
|
||||
virtual void lpm_mux(class Design*des, class NetMux*);
|
||||
|
||||
/* This method is called for each unary reduction gate. */
|
||||
virtual void lpm_ureduce(class Design*des, class NetUReduce*);
|
||||
|
||||
virtual void sign_extend(class Design*des, class NetSignExtend*);
|
||||
};
|
||||
|
||||
struct proc_match_t {
|
||||
@@ -92,6 +100,15 @@ struct proc_match_t {
|
||||
|
||||
/*
|
||||
* $Log: functor.h,v $
|
||||
* Revision 1.23 2005/07/07 16:22:49 steve
|
||||
* Generalize signals to carry types.
|
||||
*
|
||||
* Revision 1.22 2005/05/24 01:44:27 steve
|
||||
* Do sign extension of structuran nets.
|
||||
*
|
||||
* Revision 1.21 2005/02/03 04:56:20 steve
|
||||
* laborate reduction gates into LPM_RED_ nodes.
|
||||
*
|
||||
* Revision 1.20 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
|
||||
+11
-2
@@ -1,4 +1,7 @@
|
||||
|
||||
NOTE: THE CONTENTS OF THIS FILE ARE BEING MOVED TO THE DOCUMENTATION
|
||||
WIKI AT http://iverilog.wikia.com. PLEASE ADD NEW ENTRIES THERE.
|
||||
|
||||
Icarus Verilog vs. IEEE1364
|
||||
Copyright 2000 Stephen Williams
|
||||
|
||||
@@ -249,7 +252,7 @@ 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
|
||||
is accepted. Further testing shows that any expression other than a
|
||||
simple unsized constant is accepted there, even if all the operands of
|
||||
all the operators that make up the expression are unsized integers.
|
||||
|
||||
@@ -498,8 +501,14 @@ of 4-value behavior in the dead zone, and appears more user friendly
|
||||
when viewed by reasonable viewers.
|
||||
|
||||
|
||||
$Id: ieee1364-notes.txt,v 1.17 2003/07/15 03:49:22 steve Exp $
|
||||
$Id: ieee1364-notes.txt,v 1.19 2007/04/18 02:36:13 steve Exp $
|
||||
$Log: ieee1364-notes.txt,v $
|
||||
Revision 1.19 2007/04/18 02:36:13 steve
|
||||
Put to iverilog wiki for further notes.
|
||||
|
||||
Revision 1.18 2007/03/22 16:08:16 steve
|
||||
Spelling fixes from Larry
|
||||
|
||||
Revision 1.17 2003/07/15 03:49:22 steve
|
||||
Spelling fixes.
|
||||
|
||||
|
||||
+8
-8
@@ -103,7 +103,7 @@ fi
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
@@ -112,7 +112,7 @@ if [ x"$dir_arg" != x ]; then
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
@@ -122,7 +122,7 @@ else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
@@ -150,7 +150,7 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
@@ -189,17 +189,17 @@ else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
@@ -230,7 +230,7 @@ else
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
+52
-2
@@ -1,4 +1,4 @@
|
||||
.TH iverilog-vpi 1 "$Date: 2003/07/15 03:49:22 $" Version "$Date: 2003/07/15 03:49:22 $"
|
||||
.TH iverilog-vpi 1 "$Date: 2004/10/04 01:10:53 $" Version "$Date: 2004/10/04 01:10:53 $"
|
||||
.SH NAME
|
||||
iverilog-vpi - Compile front end for VPI modules
|
||||
|
||||
@@ -33,6 +33,12 @@ Normally, the output VPI module will be named after the first source
|
||||
file passed to the command. This flag sets the name (without the .vpi
|
||||
suffix) of the output vpi module.
|
||||
|
||||
.TP 8
|
||||
.B --install-dir
|
||||
This flag causes the program to print the install directory for VPI
|
||||
modules, then exit. It is a convenience for makefiles or automated
|
||||
plug-in installers.
|
||||
|
||||
.SH "PC-ONLY OPTIONS"
|
||||
|
||||
The PC port of \fIiverilog-vpi\fP includes two special flags needed to
|
||||
@@ -55,6 +61,50 @@ install. This is the place where you installed Icarus Verilog when you
|
||||
ran the installer. This flag is also only needed once, and the path is
|
||||
stored in the registry for future use.
|
||||
|
||||
.SH "UNIX-ONLY OPTIONS"
|
||||
|
||||
The UNIX version of \fIiverilog-vpi\fP includes additional flags to
|
||||
let Makefile gurus peek at the configuration of the \fIiverilog\fP
|
||||
installation. This way, Makefiles can be written that handle complex VPI
|
||||
builds natively, and without hard-coding values that depend on the
|
||||
system and installation. If used at all, these options must be
|
||||
used one at a time, and without any other options or directives.
|
||||
|
||||
.TP 8
|
||||
.B --cflags
|
||||
Print the compiler flags (CFLAGS or CXXFLAGS) needed to compile source
|
||||
code destined for a VPI module.
|
||||
|
||||
.TP 8
|
||||
.B --ldflags
|
||||
Print the linker flags (LDFLAGS) needed to link a VPI module.
|
||||
|
||||
.TP 8
|
||||
.B --ldlibs
|
||||
Print the libraries (LDLIBS) needed to link a VPI module.
|
||||
|
||||
.TP 8
|
||||
.B -m32
|
||||
On 64bit systems that support it (and support vvp32) this flag
|
||||
requests a 32bit vpi binary instead of the default 64bit binary.
|
||||
|
||||
.P
|
||||
Example GNU makefile that takes advantage of these flags:
|
||||
.IP "" 4
|
||||
CFLAGS = -Wall -O $(CFLAGS_$@)
|
||||
.br
|
||||
VPI_CFLAGS := $(shell iverilog-vpi --cflags)
|
||||
.br
|
||||
CFLAGS_messagev.o = $(VPI_CFLAGS)
|
||||
.br
|
||||
CFLAGS_fifo.o = $(VPI_CFLAGS)
|
||||
.br
|
||||
messagev.o fifo.o: transport.h
|
||||
.br
|
||||
messagev.vpi: messagev.o fifo.o
|
||||
.br
|
||||
iverilog-vpi $^
|
||||
|
||||
.SH "AUTHOR"
|
||||
.nf
|
||||
Steve Williams ([email protected])
|
||||
@@ -68,5 +118,5 @@ iverilog(1), vvp(1),
|
||||
.nf
|
||||
Copyright \(co 2002 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
||||
+57
-9
@@ -17,23 +17,35 @@
|
||||
# 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 $"
|
||||
#ident "$Id: iverilog-vpi.sh,v 1.17 2007/02/06 05:07:31 steve Exp $"
|
||||
|
||||
# These are the variables used for compiling files
|
||||
CC=gcc
|
||||
CXX=gcc
|
||||
CFLAGS="@PIC@ -O -I@INCLUDEDIR@"
|
||||
CC=@IVCC@
|
||||
CXX=@IVCXX@
|
||||
CFLAGS="@PIC@ @IVCFLAGS@ -I@INCLUDEDIR@"
|
||||
|
||||
# These are used for linking...
|
||||
LD=gcc
|
||||
LDFLAGS="@SHARED@"
|
||||
LDLIBS="-L@LIBDIR@ -lveriuser -lvpi"
|
||||
LDFLAGS32="@SHARED@ -L@LIBDIR@"
|
||||
LDFLAGS64="@SHARED@ -L@LIBDIR64@"
|
||||
LDFLAGS="$LDFLAGS64"
|
||||
LDLIBS="-lveriuser -lvpi"
|
||||
|
||||
INSTDIR64="@VPIDIR1@"
|
||||
INSTDIR32="@VPIDIR2@"
|
||||
if test x$INSTDIR32 = x
|
||||
then
|
||||
INSTDIR32=$INSTDIR64
|
||||
fi
|
||||
|
||||
INSTDIR="$INSTDIR64"
|
||||
|
||||
CCSRC=
|
||||
CXSRC=
|
||||
OBJ=
|
||||
LIB=
|
||||
OUT=
|
||||
INCOPT=
|
||||
|
||||
# --
|
||||
# parse the command line switches. This collects the source files
|
||||
@@ -51,11 +63,19 @@ do
|
||||
;;
|
||||
|
||||
*.cc) CXSRC="$CXSRC $parm"
|
||||
LD=$CXX
|
||||
if [ x$OUT = x ]; then
|
||||
OUT=`basename $parm .cc`
|
||||
fi
|
||||
;;
|
||||
|
||||
*.cpp) CXSRC="$CXSRC $parm"
|
||||
LD=$CXX
|
||||
if [ x$OUT = x ]; then
|
||||
OUT=`basename $parm .cpp`
|
||||
fi
|
||||
;;
|
||||
|
||||
*.o) OBJ="$OBJ $parm"
|
||||
if [ x$OUT = x ]; then
|
||||
OUT=`basename $parm .o`
|
||||
@@ -69,12 +89,40 @@ do
|
||||
-l*) LIB="$LIB $parm"
|
||||
;;
|
||||
|
||||
-I*) INCOPT="$INCOPT $parm"
|
||||
echo "$parm"
|
||||
;;
|
||||
|
||||
-m32) LDFLAGS="-m32 $LDFLAGS32"
|
||||
CFLAGS="-m32 $CFLAGS"
|
||||
INSTDIR="$INSTDIR32"
|
||||
;;
|
||||
|
||||
--cflags)
|
||||
echo "$CFLAGS"
|
||||
exit;
|
||||
;;
|
||||
|
||||
--ldflags)
|
||||
echo "$LDFLAGS"
|
||||
exit;
|
||||
;;
|
||||
|
||||
--ldlibs)
|
||||
echo "$LDLIBS"
|
||||
exit;
|
||||
;;
|
||||
|
||||
--install-dir)
|
||||
echo "@LIBDIR@/ivl/$INSTDIR"
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
|
||||
done
|
||||
|
||||
if [ x$OUT = x ]; then
|
||||
echo "Usage: $0 [src and obj files]..."
|
||||
echo "Usage: $0 [src and obj files]..." 1>&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -90,7 +138,7 @@ do
|
||||
obj=$base".o"
|
||||
|
||||
echo "Compiling $src..."
|
||||
$CC -c -o $obj $CFLAGS $src || compile_errors=`expr $compile_errors + 1`
|
||||
$CC -c -o $obj $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1`
|
||||
OBJ="$OBJ $obj"
|
||||
done
|
||||
|
||||
@@ -100,7 +148,7 @@ do
|
||||
obj=$base".o"
|
||||
|
||||
echo "Compiling $src..."
|
||||
$CXX -c -o $obj $CFLAGS $src || compile_errors=`expr $compile_errors + 1`
|
||||
$CXX -c -o $obj $CFLAGS $INCOPT $src || compile_errors=`expr $compile_errors + 1`
|
||||
OBJ="$OBJ $obj"
|
||||
done
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
|
||||
# The iverilog.conf configuration file provides to the iverilog driver
|
||||
# strings based on switches that are passed by the user on the command
|
||||
# line.
|
||||
#
|
||||
# Comments start from the hash (#) character and run to the end of the
|
||||
# line.
|
||||
#
|
||||
# Conditions are a list of requirements between [] characters. For the
|
||||
# set of patterns following a string to b activated, all the
|
||||
# conditions must be true. Valid conditions are:
|
||||
#
|
||||
# -S -- The -S flag is passed to iverilog
|
||||
# -t<string> -- The -t<string> parameters is passed to iverilog
|
||||
#
|
||||
#
|
||||
# Patterns have a name and text. The name has the form <key> where the
|
||||
# key is some key value that is required by iverilog. The commonly
|
||||
# used keys are:
|
||||
#
|
||||
# <ivl>
|
||||
# The string here is the command line needed to take the
|
||||
# preprocessor output (ivlpp) and compile it with the
|
||||
# target. All target types use this key.
|
||||
#
|
||||
# The pattern text includes %<code> substitutions. iverilog
|
||||
# substitutes values for the %<code> sequences within the text.
|
||||
#
|
||||
# %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 Substitute 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
|
||||
# output path if there is no -o flag.
|
||||
#
|
||||
# %T Substitute min, typ or max depending on the -T flag from the
|
||||
# command line.
|
||||
#
|
||||
#
|
||||
# %W Substitute the ivl warning flags.
|
||||
#
|
||||
# %[<c><text>]
|
||||
# This substitution pattern is magical, and is the only
|
||||
# multicharacter pattern. This tests the code <c>, and
|
||||
# substitutes <text> into the output only if <c> is true.
|
||||
# The <text> may include further substitution strings, and is
|
||||
# terminated by a ``]'' character.
|
||||
|
||||
|
||||
# This is the null (no op) target. There is a synthesis version and a
|
||||
# non-synthesis version. Normally, this does not matter, but this can
|
||||
# be useful and interesting if the -N flag is included.
|
||||
|
||||
[-tnull -S]
|
||||
<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 %[v-v] -C%C %g %W %s %[M-M%M] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- -
|
||||
|
||||
# --
|
||||
# The vvp target generates code that the vvp simulation engine can execute.
|
||||
# These rules support synthesized and non-synthesized variants.
|
||||
|
||||
[-tvvp -S]
|
||||
<ivl>%B/ivl %[v-v] -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 -- -
|
||||
|
||||
# This is the XNF code generator.
|
||||
|
||||
[-txnf]
|
||||
<ivl>%B/ivl -C%C %[v-v] %g %s %[M-M%M] %[N-N%N] %[T-T%T] -txnf -Fsynth -Fsyn-rules -Fxnfio -Fcprop -Fnodangle -o%o -- -
|
||||
|
||||
# And this is another XNF code generator, under development.
|
||||
[-tfpga]
|
||||
<ivl>%B/ivl -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 -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 -- -
|
||||
@@ -9,9 +9,10 @@ ivl_design_roots
|
||||
ivl_design_time_precision
|
||||
|
||||
ivl_const_bits
|
||||
ivl_const_pin
|
||||
ivl_const_pins
|
||||
ivl_const_real
|
||||
ivl_const_signed
|
||||
ivl_const_type
|
||||
ivl_const_width
|
||||
|
||||
ivl_event_any
|
||||
ivl_event_basename
|
||||
@@ -21,14 +22,13 @@ ivl_event_neg
|
||||
ivl_event_nneg
|
||||
ivl_event_npos
|
||||
ivl_event_pos
|
||||
ivl_event_scope
|
||||
|
||||
ivl_expr_type
|
||||
ivl_expr_bits
|
||||
ivl_expr_def
|
||||
ivl_expr_dvalue
|
||||
ivl_expr_event
|
||||
ivl_expr_lsi
|
||||
ivl_expr_memory
|
||||
ivl_expr_name
|
||||
ivl_expr_opcode
|
||||
ivl_expr_oper1
|
||||
@@ -44,33 +44,34 @@ ivl_expr_signed
|
||||
ivl_expr_string
|
||||
ivl_expr_uvalue
|
||||
ivl_expr_value
|
||||
ivl_expr_variable
|
||||
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_delay
|
||||
ivl_logic_drive0
|
||||
ivl_logic_drive1
|
||||
ivl_logic_name
|
||||
ivl_logic_pin
|
||||
ivl_logic_pins
|
||||
ivl_logic_scope
|
||||
ivl_logic_type
|
||||
ivl_logic_udp
|
||||
ivl_logic_width
|
||||
|
||||
ivl_lpm_array
|
||||
ivl_lpm_aset_value
|
||||
ivl_lpm_async_clr
|
||||
ivl_lpm_async_set
|
||||
ivl_lpm_base
|
||||
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
|
||||
@@ -78,23 +79,18 @@ ivl_lpm_select
|
||||
ivl_lpm_selects
|
||||
ivl_lpm_signed
|
||||
ivl_lpm_size
|
||||
ivl_lpm_sset_value
|
||||
ivl_lpm_string
|
||||
ivl_lpm_sync_clr
|
||||
ivl_lpm_sync_set
|
||||
ivl_lpm_type
|
||||
ivl_lpm_width
|
||||
|
||||
ivl_lval_idx
|
||||
ivl_lval_mem
|
||||
ivl_lval_mux
|
||||
ivl_lval_part_off
|
||||
ivl_lval_pin
|
||||
ivl_lval_pins
|
||||
ivl_lval_sig
|
||||
ivl_lval_var
|
||||
|
||||
ivl_memory_basename
|
||||
ivl_memory_root
|
||||
ivl_memory_scope
|
||||
ivl_memory_size
|
||||
ivl_memory_width
|
||||
ivl_lval_width
|
||||
|
||||
ivl_nexus_get_private
|
||||
ivl_nexus_name
|
||||
@@ -113,6 +109,12 @@ ivl_nexus_ptr_sig
|
||||
ivl_parameter_basename
|
||||
ivl_parameter_expr
|
||||
|
||||
ivl_path_condit
|
||||
ivl_path_delay
|
||||
ivl_path_source
|
||||
ivl_path_source_negedge
|
||||
ivl_path_source_posedge
|
||||
|
||||
ivl_scope_attr_cnt
|
||||
ivl_scope_attr_val
|
||||
ivl_scope_basename
|
||||
@@ -124,8 +126,6 @@ ivl_scope_logs
|
||||
ivl_scope_log
|
||||
ivl_scope_lpms
|
||||
ivl_scope_lpm
|
||||
ivl_scope_mem
|
||||
ivl_scope_mems
|
||||
ivl_scope_name
|
||||
ivl_scope_param
|
||||
ivl_scope_params
|
||||
@@ -137,21 +137,30 @@ ivl_scope_sig
|
||||
ivl_scope_time_units
|
||||
ivl_scope_type
|
||||
ivl_scope_tname
|
||||
ivl_scope_var
|
||||
ivl_scope_vars
|
||||
|
||||
ivl_signal_array_base
|
||||
ivl_signal_array_count
|
||||
ivl_signal_attr
|
||||
ivl_signal_attr_cnt
|
||||
ivl_signal_attr_val
|
||||
ivl_signal_basename
|
||||
ivl_signal_data_type
|
||||
ivl_signal_dimensions
|
||||
ivl_signal_integer
|
||||
ivl_signal_local
|
||||
ivl_signal_pin
|
||||
ivl_signal_pins
|
||||
ivl_signal_lsb
|
||||
ivl_signal_msb
|
||||
ivl_signal_name
|
||||
ivl_signal_nex
|
||||
ivl_signal_npath
|
||||
ivl_signal_path
|
||||
ivl_signal_port
|
||||
ivl_signal_signed
|
||||
ivl_signal_type
|
||||
ivl_signal_name
|
||||
ivl_signal_basename
|
||||
ivl_signal_width
|
||||
|
||||
ivl_path_delay
|
||||
ivl_path_source
|
||||
|
||||
ivl_process_attr_cnt
|
||||
ivl_process_attr_val
|
||||
@@ -173,13 +182,12 @@ ivl_stmt_cond_false
|
||||
ivl_stmt_cond_true
|
||||
ivl_stmt_delay_expr
|
||||
ivl_stmt_delay_val
|
||||
ivl_stmt_event
|
||||
ivl_stmt_events
|
||||
ivl_stmt_lval
|
||||
ivl_stmt_lvals
|
||||
ivl_stmt_lwidth
|
||||
ivl_stmt_name
|
||||
ivl_stmt_nexus
|
||||
ivl_stmt_nexus_count
|
||||
ivl_stmt_nevent
|
||||
ivl_stmt_parm
|
||||
ivl_stmt_parm_count
|
||||
ivl_stmt_rval
|
||||
@@ -191,6 +199,3 @@ ivl_udp_nin
|
||||
ivl_udp_row
|
||||
ivl_udp_rows
|
||||
ivl_udp_sequ
|
||||
|
||||
ivl_variable_name
|
||||
ivl_variable_type
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2007 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: ivl_assert.h,v 1.1 2007/01/31 04:21:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifndef __ivl_assert_h
|
||||
#define __ivl_assert_h
|
||||
|
||||
# include <assert.h>
|
||||
|
||||
#define ivl_assert(tok, expression) \
|
||||
do { \
|
||||
if (! (expression)) \
|
||||
__ivl_assert(#expression, tok, __FILE__, __LINE__); \
|
||||
} while(0)
|
||||
|
||||
#define __ivl_assert(expression, tok, file, line) \
|
||||
do { \
|
||||
cerr << (tok).get_line() << ": assert: " \
|
||||
<< file << ":" << line \
|
||||
<< ": failed assertion " << (expression) << endl; \
|
||||
abort(); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#endif
|
||||
+779
-191
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user