mirror of https://github.com/YosysHQ/abc.git
Compare commits
1405 Commits
yosys-0.14
...
yosys-expe
| Author | SHA1 | Date |
|---|---|---|
|
|
a51bf4a7bb | |
|
|
89b0b366a2 | |
|
|
5ea3464324 | |
|
|
324081b6a4 | |
|
|
371e53f93e | |
|
|
89bef47d8d | |
|
|
fe862d3647 | |
|
|
1d28820170 | |
|
|
25b0e5399c | |
|
|
a954df2892 | |
|
|
094c1ca741 | |
|
|
12eb48b476 | |
|
|
d389f88285 | |
|
|
ebd3e31a8d | |
|
|
0bd9c3ea60 | |
|
|
e4383a8d67 | |
|
|
e69c02c3f2 | |
|
|
d4e3670e21 | |
|
|
6c51a92385 | |
|
|
5cbfa76dc3 | |
|
|
0f5951ab2c | |
|
|
4473e39efc | |
|
|
4d504f20ba | |
|
|
8e224cd794 | |
|
|
2a9e9c2a00 | |
|
|
85770ba29d | |
|
|
842a265d82 | |
|
|
bd52945300 | |
|
|
2918589334 | |
|
|
e76768b9d3 | |
|
|
4e1b34d744 | |
|
|
77cd6f4b04 | |
|
|
c1f9a942ca | |
|
|
57ad5cd47b | |
|
|
3ed7e4179a | |
|
|
c130edd5e8 | |
|
|
e026ed5380 | |
|
|
bcfdf59228 | |
|
|
a082d1ba3a | |
|
|
523af52dd4 | |
|
|
0a297ad527 | |
|
|
f8faf4379e | |
|
|
a01df4b82c | |
|
|
f7c7cf0099 | |
|
|
b4ca3e7f52 | |
|
|
79f1e0b41d | |
|
|
a35f806b8c | |
|
|
9794114a68 | |
|
|
b89ccd36bc | |
|
|
0e32819325 | |
|
|
5100825c51 | |
|
|
476b31cac5 | |
|
|
feaf7a773d | |
|
|
3ce53c361f | |
|
|
2eb8f38cd1 | |
|
|
7d253d7cb2 | |
|
|
68bf7cba8e | |
|
|
70a92ee63f | |
|
|
29c59ab009 | |
|
|
cfd526afd0 | |
|
|
4c08da846a | |
|
|
d79133b567 | |
|
|
f1d6c364cf | |
|
|
334ae5d1b7 | |
|
|
61e74a1033 | |
|
|
2d835aabf0 | |
|
|
e00a2fe834 | |
|
|
a4b7912895 | |
|
|
30c47da5c9 | |
|
|
8783dcfd73 | |
|
|
f1ec6d32d8 | |
|
|
cd9d9fcc13 | |
|
|
1e130338f0 | |
|
|
1e85fff18d | |
|
|
26ca14e4c6 | |
|
|
d3d218eee2 | |
|
|
b73fcb78ed | |
|
|
304481b68a | |
|
|
3df13d9aad | |
|
|
59896d6ec8 | |
|
|
9749046cd6 | |
|
|
8149daf921 | |
|
|
b7ee7a5f70 | |
|
|
cd33ba563f | |
|
|
66f5d7c7a2 | |
|
|
21b2d8959a | |
|
|
749bc49826 | |
|
|
0497d4708a | |
|
|
7b0a6cbb58 | |
|
|
a917c1af9f | |
|
|
cd6e9b582b | |
|
|
70c42b7292 | |
|
|
9e02a87c1d | |
|
|
f4d870e109 | |
|
|
ffb0ff63fc | |
|
|
07e38ef030 | |
|
|
7bf1177d39 | |
|
|
26567123a7 | |
|
|
2827348459 | |
|
|
5d51a5e420 | |
|
|
3d2af6345c | |
|
|
c61f1a04e9 | |
|
|
9d410e8163 | |
|
|
97b15a29a0 | |
|
|
8c9e66205e | |
|
|
60b3991a0e | |
|
|
98967c9f3a | |
|
|
d55ae1421c | |
|
|
d54cbda229 | |
|
|
cf5da03652 | |
|
|
f3157272ae | |
|
|
eaa8496b42 | |
|
|
d217b35192 | |
|
|
fc4cfc0c35 | |
|
|
84b78d570c | |
|
|
6d9c88d7e8 | |
|
|
298bcee98a | |
|
|
5611ca0bbb | |
|
|
9ac97c7c4c | |
|
|
ec4faae74a | |
|
|
db8e5d9988 | |
|
|
ff00f67063 | |
|
|
60e091d993 | |
|
|
d07ce81c91 | |
|
|
153d6b7f82 | |
|
|
b413eb90de | |
|
|
b2a0cabf29 | |
|
|
c20832627f | |
|
|
8e6b287674 | |
|
|
1056de3239 | |
|
|
d74b33eba6 | |
|
|
817d542c45 | |
|
|
2b9920e6a5 | |
|
|
405511f850 | |
|
|
ada8fb2e87 | |
|
|
5096a78fbe | |
|
|
1ddb7a2352 | |
|
|
fa042e42ed | |
|
|
8762d6c667 | |
|
|
2db6ae7848 | |
|
|
0f6ca59029 | |
|
|
6a52468604 | |
|
|
8aa7e12dab | |
|
|
180a6adb68 | |
|
|
80c8a9a192 | |
|
|
ca2a410095 | |
|
|
cd2998b5c7 | |
|
|
bef23270f8 | |
|
|
b8059c310a | |
|
|
de0ebae1c5 | |
|
|
6aaf0db1e1 | |
|
|
60e0303e3a | |
|
|
7a28b20d8e | |
|
|
3881f2de37 | |
|
|
ceebb2d167 | |
|
|
24917213df | |
|
|
ca0fc3ed29 | |
|
|
cf5aef3889 | |
|
|
fa5029da95 | |
|
|
b4a657e75b | |
|
|
55f552b454 | |
|
|
7ae0f4966a | |
|
|
a745d5ec81 | |
|
|
ba69519d73 | |
|
|
c92cfab80b | |
|
|
7553ef9760 | |
|
|
d10a0d41a3 | |
|
|
ee40e40d09 | |
|
|
8e401543d3 | |
|
|
f3a17d343a | |
|
|
41c28e541a | |
|
|
4e5c5e62af | |
|
|
c1937d12ac | |
|
|
d5c1f2cfe1 | |
|
|
ef54c1daea | |
|
|
ea6be8a51c | |
|
|
2b0e38c067 | |
|
|
ce559b169e | |
|
|
e90839fcf1 | |
|
|
ec8b45add3 | |
|
|
0433d6e327 | |
|
|
3b5036a1e1 | |
|
|
2c6089fff5 | |
|
|
771e70381c | |
|
|
8a856ce23f | |
|
|
71c24a4812 | |
|
|
c7ea67b7df | |
|
|
6c8b2cfa3b | |
|
|
3dd086febe | |
|
|
62d05a8832 | |
|
|
3cdb1c4c3b | |
|
|
8475386dfa | |
|
|
2726f0e470 | |
|
|
3285adaf32 | |
|
|
c18b835ef1 | |
|
|
90be4816ce | |
|
|
6339de7296 | |
|
|
b60994e143 | |
|
|
8573cb98f6 | |
|
|
ccafa23e40 | |
|
|
b50fd7a10a | |
|
|
734f64d5b9 | |
|
|
367b407fba | |
|
|
5899aa5df1 | |
|
|
70a12750c1 | |
|
|
5fd7c57407 | |
|
|
b6105230bf | |
|
|
f2ae808236 | |
|
|
79010216cb | |
|
|
ade1882ffc | |
|
|
29656286cf | |
|
|
6fcdfdbc5e | |
|
|
9dcae29da3 | |
|
|
71e163571a | |
|
|
dd21791031 | |
|
|
d1157cae39 | |
|
|
5f3a4fec83 | |
|
|
8e93af4589 | |
|
|
cdcfb2febf | |
|
|
01ad37aada | |
|
|
ad267aca8a | |
|
|
57544eb9ca | |
|
|
41e73dbd8b | |
|
|
7f6aba463a | |
|
|
c1ed182d38 | |
|
|
799ba63223 | |
|
|
c18b9a24de | |
|
|
f833c265ce | |
|
|
db9275bfbc | |
|
|
7721495458 | |
|
|
59bb87e28e | |
|
|
ab1e50bcd5 | |
|
|
7bf910315b | |
|
|
ef74590ebd | |
|
|
3b36aa1573 | |
|
|
91e806ffb6 | |
|
|
1f13c88bfd | |
|
|
291e0a2c83 | |
|
|
8d3ba7bd7d | |
|
|
0ff43a13cb | |
|
|
28cc76119c | |
|
|
8b79876f17 | |
|
|
8d42237589 | |
|
|
99ca3e4428 | |
|
|
95b8d57331 | |
|
|
997619d33e | |
|
|
52741b9123 | |
|
|
2accf61bcd | |
|
|
d2c15a04db | |
|
|
00cee5f2f5 | |
|
|
645d8667c3 | |
|
|
a38d012563 | |
|
|
5cdded372a | |
|
|
84fca2c3f0 | |
|
|
60f52cc082 | |
|
|
58023c97b7 | |
|
|
c0ea0cf4d0 | |
|
|
87395e54f5 | |
|
|
6ff6a382df | |
|
|
050bab8314 | |
|
|
bd7fb12e18 | |
|
|
3d32b8b2ad | |
|
|
b822d47fcf | |
|
|
fd04a1c073 | |
|
|
f9e4430535 | |
|
|
c8d4592453 | |
|
|
e57bd52127 | |
|
|
bc0f65cbfc | |
|
|
7a4d8ec907 | |
|
|
c0e252846e | |
|
|
a625ef2edc | |
|
|
e7c304d3d1 | |
|
|
35d19a9f33 | |
|
|
9182a8048d | |
|
|
6c34efdc2b | |
|
|
11732d3082 | |
|
|
860b49dd80 | |
|
|
c6966aa907 | |
|
|
64637b8395 | |
|
|
c327b83127 | |
|
|
99bde47c57 | |
|
|
1e9cc528be | |
|
|
993f30ffae | |
|
|
f8726e5e97 | |
|
|
9a2cf907da | |
|
|
15abe445f4 | |
|
|
ee04349aee | |
|
|
a8a58c63ba | |
|
|
94d0b0dbbb | |
|
|
85a0039b78 | |
|
|
362661f00d | |
|
|
bd05a6454e | |
|
|
b816c2d1bb | |
|
|
e67af0ad9e | |
|
|
33001946f0 | |
|
|
eaa204829c | |
|
|
e58a28b73b | |
|
|
49efc5bb45 | |
|
|
ef1a3d0f42 | |
|
|
b7f8df0941 | |
|
|
5e58e34f6c | |
|
|
c4b2b5c180 | |
|
|
9b0786fe89 | |
|
|
53edce3382 | |
|
|
b9074a754b | |
|
|
7691e2ed3c | |
|
|
131a50dd77 | |
|
|
ee899284b8 | |
|
|
7f64516f23 | |
|
|
ba852596b4 | |
|
|
845de6f368 | |
|
|
6d2bedd609 | |
|
|
c956f02eb0 | |
|
|
148f0e9cac | |
|
|
fade76f70b | |
|
|
48d09e7f93 | |
|
|
bde60f2a20 | |
|
|
4bba0356fb | |
|
|
d72b93c168 | |
|
|
6aaca6a1af | |
|
|
51c5ff3b81 | |
|
|
6490bd7da3 | |
|
|
bb52782941 | |
|
|
8c27e4bc90 | |
|
|
281204f938 | |
|
|
d8219265fc | |
|
|
309282601e | |
|
|
b319f57dde | |
|
|
6f5c46632d | |
|
|
6534475fa1 | |
|
|
b1c73c160c | |
|
|
5ade9e9dfb | |
|
|
28f4ad8281 | |
|
|
9e90e6086d | |
|
|
ec70146d5d | |
|
|
3bd528c0bf | |
|
|
38c2bec1ff | |
|
|
3d281a1907 | |
|
|
91d2f3d7e8 | |
|
|
169e288fc4 | |
|
|
1b7912a247 | |
|
|
677299a52f | |
|
|
0a650c18cf | |
|
|
6cab944535 | |
|
|
3109172462 | |
|
|
cb971e07a3 | |
|
|
1c5ed1ce37 | |
|
|
7e961f4f3e | |
|
|
474e7fbec2 | |
|
|
f8981d48f5 | |
|
|
8f06ce9112 | |
|
|
f897673f68 | |
|
|
800c274cc2 | |
|
|
5273eab9f7 | |
|
|
aac6190208 | |
|
|
f808e2c68b | |
|
|
7c6b779327 | |
|
|
a9d62d845d | |
|
|
6034f6621b | |
|
|
56a7c049ae | |
|
|
18f6464ec7 | |
|
|
3a1efd48f7 | |
|
|
4c6b082463 | |
|
|
6fb4f739b0 | |
|
|
f39b84a4a1 | |
|
|
93f3791fbe | |
|
|
1d7c05988f | |
|
|
a1f5e4541b | |
|
|
fa186342ba | |
|
|
7fbcde9d22 | |
|
|
c8eac7595d | |
|
|
9596162b4a | |
|
|
4c25599cce | |
|
|
613fa4f5eb | |
|
|
b28e042afd | |
|
|
08230e0c31 | |
|
|
745376d505 | |
|
|
8827bafb7f | |
|
|
9478c17288 | |
|
|
5adfd0030d | |
|
|
4dfa49774f | |
|
|
b84382b5db | |
|
|
4f29be9046 | |
|
|
3455f423d0 | |
|
|
279217b73d | |
|
|
0e4a080779 | |
|
|
192c161f93 | |
|
|
c5ceff2bee | |
|
|
e29dcd9f32 | |
|
|
e7d360811f | |
|
|
15151c58ed | |
|
|
00910e36ff | |
|
|
a5715bc32d | |
|
|
5e09cca964 | |
|
|
1a18c9a3d8 | |
|
|
fd74cb8e8a | |
|
|
260fa85161 | |
|
|
c738ed6e86 | |
|
|
fa7fa163da | |
|
|
0218e3e4cb | |
|
|
aeef2c6692 | |
|
|
3aa8a4a639 | |
|
|
c69e45916a | |
|
|
fcd8ac34d6 | |
|
|
052a365823 | |
|
|
705a3da338 | |
|
|
4ccacb1e5b | |
|
|
ff56eed4b3 | |
|
|
a511d753a6 | |
|
|
d0118d3917 | |
|
|
c4c401b7a5 | |
|
|
990abc4349 | |
|
|
f1eebf78f4 | |
|
|
0dc5524b80 | |
|
|
13205ccbb3 | |
|
|
5e03f9fefa | |
|
|
6e130c15a3 | |
|
|
9ea1aaa3cf | |
|
|
a5156f257e | |
|
|
beff7f1b34 | |
|
|
83824878e3 | |
|
|
da52efecdc | |
|
|
e9845e534a | |
|
|
f443db4a24 | |
|
|
6463f11625 | |
|
|
44f3265e8b | |
|
|
afae379366 | |
|
|
5cf5a8d9f5 | |
|
|
d4358ec80c | |
|
|
a4064b8b73 | |
|
|
0a55186553 | |
|
|
1f98c28011 | |
|
|
301b46e3c1 | |
|
|
04161dfda8 | |
|
|
0ae04514cd | |
|
|
716314d835 | |
|
|
32fe49b6d1 | |
|
|
e1a1994292 | |
|
|
0c155952bf | |
|
|
3bd7bac552 | |
|
|
e20c484ee1 | |
|
|
c5edc566ff | |
|
|
29c8d3eacf | |
|
|
9bb736acee | |
|
|
c398b06740 | |
|
|
240bf58f90 | |
|
|
916f70058e | |
|
|
0b1d7c6d0f | |
|
|
5daa0c347e | |
|
|
57966de4b4 | |
|
|
d34821e768 | |
|
|
078debff4e | |
|
|
d245305393 | |
|
|
9545b79e0e | |
|
|
c85f007f75 | |
|
|
490bb92a8c | |
|
|
a42e6ecd23 | |
|
|
9dc7ade063 | |
|
|
71b60a9830 | |
|
|
4560597b31 | |
|
|
49d9252f90 | |
|
|
5e54ef3aff | |
|
|
f9e4d06806 | |
|
|
692b0c6908 | |
|
|
75adf123f6 | |
|
|
1c2b935a77 | |
|
|
391a767c16 | |
|
|
6a031620fe | |
|
|
59bb4de39f | |
|
|
5305d93037 | |
|
|
eaf974dec1 | |
|
|
b1734ac297 | |
|
|
b1b1023285 | |
|
|
5ea1240990 | |
|
|
0ab176d7c9 | |
|
|
01bfd8fbad | |
|
|
3a063c5901 | |
|
|
1626a337a1 | |
|
|
b454511936 | |
|
|
6c37cc9ac3 | |
|
|
dcf9079507 | |
|
|
47ac9f75ca | |
|
|
1a1bdbe4c8 | |
|
|
1177cfabfb | |
|
|
2179034f23 | |
|
|
43d12f6c31 | |
|
|
08ccd6d0b9 | |
|
|
d271403514 | |
|
|
c5fdfb3835 | |
|
|
83150e6549 | |
|
|
5700bff205 | |
|
|
e55d316cc9 | |
|
|
20416c1a7b | |
|
|
1cdaaadf53 | |
|
|
44a2996f7f | |
|
|
68c576cc56 | |
|
|
3846c193f2 | |
|
|
27f2429d76 | |
|
|
c0be439b45 | |
|
|
1b6b553922 | |
|
|
3f479dc84f | |
|
|
5c604949af | |
|
|
0b68f06172 | |
|
|
8db417597c | |
|
|
96c28881a8 | |
|
|
e3b96c784f | |
|
|
fa80e30eca | |
|
|
a4d6775b7c | |
|
|
2c003f8865 | |
|
|
29706ebede | |
|
|
80becaf2e2 | |
|
|
9cdbb79338 | |
|
|
dc72d1e120 | |
|
|
4656ae10e0 | |
|
|
6d6a5accb4 | |
|
|
4ac014db41 | |
|
|
db2b52ca03 | |
|
|
2b5f102bdb | |
|
|
bb11cc4c46 | |
|
|
2442720528 | |
|
|
938ae9428b | |
|
|
f5ac2d4bd3 | |
|
|
e320888191 | |
|
|
da5f1e1579 | |
|
|
8ffca32372 | |
|
|
e7dd9151b1 | |
|
|
2078b3945b | |
|
|
30c952ed22 | |
|
|
59a7cc5c9c | |
|
|
e20cbd6120 | |
|
|
80a43cce9e | |
|
|
e937e82cc6 | |
|
|
c63cf09660 | |
|
|
67d8095515 | |
|
|
c3b76b1712 | |
|
|
0ebc9dbbae | |
|
|
839f3e18dd | |
|
|
aaba1b9a5f | |
|
|
d55735df2b | |
|
|
27fdbe0162 | |
|
|
2361a02c99 | |
|
|
feefa0f513 | |
|
|
5ef9c3c50b | |
|
|
f2d68d590f | |
|
|
504f604d2a | |
|
|
5ecc7c333c | |
|
|
43b9a4defe | |
|
|
02f3727d87 | |
|
|
b09305204d | |
|
|
2c45f9dce2 | |
|
|
40ea8a7598 | |
|
|
9390a74c54 | |
|
|
bd9fb45808 | |
|
|
ecc27e80dc | |
|
|
120f30a89e | |
|
|
9665696a94 | |
|
|
67fdd8d244 | |
|
|
0e117760e2 | |
|
|
c62bf1b89c | |
|
|
3dc77bbe1c | |
|
|
38ba7d78aa | |
|
|
f058e15f87 | |
|
|
383c16b690 | |
|
|
cab003b277 | |
|
|
db4a3005e3 | |
|
|
14b451b52f | |
|
|
f544165a88 | |
|
|
8fb9fc5d0f | |
|
|
f168f2f286 | |
|
|
fbd19056e7 | |
|
|
7364002c39 | |
|
|
f3ae349cf2 | |
|
|
8005405ed7 | |
|
|
2126cb3ca1 | |
|
|
b9b8ff47e3 | |
|
|
e7cd9a3b66 | |
|
|
3f6171127a | |
|
|
664d285fcb | |
|
|
a7476c65d8 | |
|
|
c25bf73466 | |
|
|
e462caed8f | |
|
|
1b96863505 | |
|
|
adbeffc145 | |
|
|
d0d1721bbe | |
|
|
083d3884dd | |
|
|
5632bb8892 | |
|
|
75ef06017d | |
|
|
6046bbee4e | |
|
|
e9c7059274 | |
|
|
45c250fb5b | |
|
|
a9d959acbe | |
|
|
c4a10c728e | |
|
|
4f1b961d00 | |
|
|
9e35825e6b | |
|
|
e5e1f76b21 | |
|
|
0cbc9a851a | |
|
|
57e504db7b | |
|
|
ee8e0370d5 | |
|
|
a2c6cb8fd4 | |
|
|
4b6c35bd4d | |
|
|
8a96d02e33 | |
|
|
a2e4c153c9 | |
|
|
80eecea409 | |
|
|
7bd782382e | |
|
|
f51543457d | |
|
|
775dee4de9 | |
|
|
20a57ef343 | |
|
|
23c632f113 | |
|
|
b0153e0f57 | |
|
|
d1d861f703 | |
|
|
6e3b38c7d3 | |
|
|
aa9630e169 | |
|
|
c4f8e8e88b | |
|
|
b7bf6c20b6 | |
|
|
2227d6d4e7 | |
|
|
964170d8dc | |
|
|
8912d3aabe | |
|
|
3e86444510 | |
|
|
303907ec0c | |
|
|
adf9b4e7fb | |
|
|
8700bb58ee | |
|
|
013023f1bf | |
|
|
a75d0cb0ad | |
|
|
910a66a372 | |
|
|
a03c126a13 | |
|
|
c1ac7d8153 | |
|
|
8c7c9d0ccf | |
|
|
d5e1a5d445 | |
|
|
350dcd3ea4 | |
|
|
71b3daf0f6 | |
|
|
73742a7ec2 | |
|
|
b59b475d6a | |
|
|
7d247a08f7 | |
|
|
0dff4dbc4b | |
|
|
7a5a0ad8b3 | |
|
|
f7c5241dee | |
|
|
47e4e23bc5 | |
|
|
17652cfda6 | |
|
|
ef8230d9be | |
|
|
a74da1c50b | |
|
|
64e8bb02b9 | |
|
|
5961231ed1 | |
|
|
7c6d1ffd2d | |
|
|
37979dbd94 | |
|
|
699c8c4c88 | |
|
|
0ba2b7dae9 | |
|
|
1a89f7ff63 | |
|
|
463cf6a7df | |
|
|
14d46bfef8 | |
|
|
733fec328c | |
|
|
cc894c5905 | |
|
|
b81df1744f | |
|
|
e21399f3bc | |
|
|
943bc0191c | |
|
|
01c6102ca7 | |
|
|
733d2cd390 | |
|
|
fdd66a8963 | |
|
|
42c2c54969 | |
|
|
207cfddaa8 | |
|
|
df4d847bbf | |
|
|
ef8c35f95d | |
|
|
8a1c28bf0f | |
|
|
f407156de6 | |
|
|
bd80d2e459 | |
|
|
a6de82377d | |
|
|
c104d9cb72 | |
|
|
b999084ade | |
|
|
30af6f9868 | |
|
|
87a3cafa44 | |
|
|
0ea9929e65 | |
|
|
91dcfae020 | |
|
|
cbd4456805 | |
|
|
070ae52a46 | |
|
|
99648e132f | |
|
|
a8c65f1343 | |
|
|
8ba3d9b91c | |
|
|
6754da13f2 | |
|
|
7391a297bb | |
|
|
c315d9e149 | |
|
|
01c9a65a47 | |
|
|
14168eb509 | |
|
|
1f3cf0aad9 | |
|
|
3aff0af0c5 | |
|
|
b5a76d8ba3 | |
|
|
f2e4ceb0e3 | |
|
|
aeb977286f | |
|
|
c787e32f86 | |
|
|
091ff4e7a9 | |
|
|
ecd948027e | |
|
|
cb2140dc0c | |
|
|
743f3a7bdd | |
|
|
498ec539e6 | |
|
|
a239dd8c0b | |
|
|
f1773bd612 | |
|
|
74e7c64662 | |
|
|
baf4ddb16a | |
|
|
d1f78b36cb | |
|
|
52c842b648 | |
|
|
46f2300b7b | |
|
|
707442e091 | |
|
|
cac8f99eaa | |
|
|
2e3384390a | |
|
|
745ea92718 | |
|
|
af1de4fa9c | |
|
|
a78d358e1c | |
|
|
6004b7b21e | |
|
|
4369321167 | |
|
|
9539306436 | |
|
|
3f7a30828f | |
|
|
35a8768c50 | |
|
|
8179c73e62 | |
|
|
5bd52161cd | |
|
|
ee5acbbc01 | |
|
|
db735b632f | |
|
|
db245f59bd | |
|
|
4c4e298fad | |
|
|
0a5057f8d3 | |
|
|
9c152b71e9 | |
|
|
0d10253bd0 | |
|
|
3ddd46131c | |
|
|
3de73f2756 | |
|
|
03d92930fa | |
|
|
ad8f8a2aab | |
|
|
cd711089d7 | |
|
|
5d6a568c9e | |
|
|
786a39a294 | |
|
|
9371696a7b | |
|
|
cb294bbebc | |
|
|
252afb1521 | |
|
|
bcf292fdeb | |
|
|
64ed5b81a4 | |
|
|
034492b0e2 | |
|
|
d93a12ebee | |
|
|
49a489554b | |
|
|
af77b80194 | |
|
|
5e35510e25 | |
|
|
03b786af99 | |
|
|
732abf5b48 | |
|
|
2055b1b490 | |
|
|
c099e62032 | |
|
|
1a62954eb8 | |
|
|
e2b7750d3b | |
|
|
c2391686ea | |
|
|
324ceeaa08 | |
|
|
81fcf8494e | |
|
|
de8620d777 | |
|
|
39f6fbb052 | |
|
|
ec8419c84b | |
|
|
807f6ddacf | |
|
|
e824cca0ca | |
|
|
71c4e23f97 | |
|
|
35a1bbbdb4 | |
|
|
4156a88dbb | |
|
|
71b409b778 | |
|
|
762a123edc | |
|
|
dce6e4899b | |
|
|
0129b4c60a | |
|
|
e6b36cb5da | |
|
|
2188bc7122 | |
|
|
57f93e6627 | |
|
|
95f1837960 | |
|
|
2d267786d7 | |
|
|
2a8ea11ce0 | |
|
|
f0b070ef70 | |
|
|
afbeccb79e | |
|
|
5444cf281c | |
|
|
c8d64b8682 | |
|
|
e62e8ac528 | |
|
|
e334586ae4 | |
|
|
3e65b25942 | |
|
|
eef8c01340 | |
|
|
1383c76464 | |
|
|
68c99247bd | |
|
|
adbcb914b2 | |
|
|
57c3bd36f2 | |
|
|
6d52a1e449 | |
|
|
15ec302095 | |
|
|
23435fc8bf | |
|
|
10b9da7acb | |
|
|
a692c0da48 | |
|
|
f5f317d7d2 | |
|
|
fe0bb59baa | |
|
|
bf64a92253 | |
|
|
b23f998b81 | |
|
|
43adbc77e8 | |
|
|
e0a9c29e5a | |
|
|
1963422c10 | |
|
|
037971d9c9 | |
|
|
43426f0a94 | |
|
|
b25d9c482a | |
|
|
7d88bf21e9 | |
|
|
3286179c48 | |
|
|
1ac5f6467b | |
|
|
8f0cbbdf38 | |
|
|
1954e2fcaa | |
|
|
ab858c5435 | |
|
|
53c25250a4 | |
|
|
9f864ebe76 | |
|
|
c62bfec2fd | |
|
|
3491773f2a | |
|
|
a06dde4cf0 | |
|
|
279a909a05 | |
|
|
35d67f6c90 | |
|
|
4f68f08a7b | |
|
|
9062ed964c | |
|
|
572b80b230 | |
|
|
70563cd441 | |
|
|
2011cbced9 | |
|
|
96edf40d60 | |
|
|
3e1979f3c6 | |
|
|
93388c0d26 | |
|
|
849adb2fcb | |
|
|
b5f4afa73b | |
|
|
f8a6432d75 | |
|
|
fe3b5bf5fe | |
|
|
6262dcffa9 | |
|
|
d036ba520e | |
|
|
5450779250 | |
|
|
d7a623c151 | |
|
|
c7ac6be504 | |
|
|
ae2e3f90f7 | |
|
|
13998baf97 | |
|
|
28d955ca97 | |
|
|
6c6260465e | |
|
|
04f50406fd | |
|
|
2d70debd07 | |
|
|
7beda11621 | |
|
|
24d420370a | |
|
|
a6bf51111f | |
|
|
806a996b88 | |
|
|
17b1ec7655 | |
|
|
fb4988bb13 | |
|
|
1e58dc6b00 | |
|
|
34c2ed73a2 | |
|
|
161963a32b | |
|
|
6e459faa0e | |
|
|
795fee8d57 | |
|
|
23f351c7c6 | |
|
|
111867432c | |
|
|
0cb945ebcd | |
|
|
8ec95e85c6 | |
|
|
c64f927828 | |
|
|
3616fd8fb5 | |
|
|
9a89447de4 | |
|
|
3fd42912ad | |
|
|
5fc62b881f | |
|
|
d9a08eb44b | |
|
|
2c02ae89a0 | |
|
|
c906dfb748 | |
|
|
6ad6539c0f | |
|
|
daf3313ce6 | |
|
|
554da94ea6 | |
|
|
66c7f67b96 | |
|
|
f04f9c4353 | |
|
|
c194c112ae | |
|
|
3c56ccb8fb | |
|
|
237d81397f | |
|
|
ae92ea0214 | |
|
|
d109372fb7 | |
|
|
fb97997991 | |
|
|
4865b58b19 | |
|
|
16ba7ed883 | |
|
|
08301d00ed | |
|
|
8afc83874f | |
|
|
9ccb28ebc1 | |
|
|
0fc549d8b8 | |
|
|
246337cdbe | |
|
|
5708841672 | |
|
|
714ab458b7 | |
|
|
39ed8b36d4 | |
|
|
516c38bb44 | |
|
|
b7c7a6d98d | |
|
|
848dc0da1b | |
|
|
402c2579db | |
|
|
03da96f12f | |
|
|
043a2ffcc6 | |
|
|
c14d5f3906 | |
|
|
6699c07b92 | |
|
|
b502f00222 | |
|
|
e6a3dc602c | |
|
|
208b48667f | |
|
|
ac9cfc766a | |
|
|
2c52e3f969 | |
|
|
864f96b11e | |
|
|
8a174ee865 | |
|
|
de060a26ad | |
|
|
bc725b85de | |
|
|
2d6b5c9adc | |
|
|
99e0e37da6 | |
|
|
682480e5e9 | |
|
|
935c6a875d | |
|
|
1d90cafd54 | |
|
|
b10d000c7a | |
|
|
045803dcb8 | |
|
|
0c905f873b | |
|
|
6052d10fde | |
|
|
e8924e5534 | |
|
|
5b49724fcc | |
|
|
1446b7549f | |
|
|
078afe9faa | |
|
|
ccc02c4400 | |
|
|
ca78f5e6e5 | |
|
|
32bc1d4ab2 | |
|
|
64fea5c4c2 | |
|
|
6b5ebb3e76 | |
|
|
8f3447800c | |
|
|
accf50468a | |
|
|
316eec6d3f | |
|
|
6e1653426f | |
|
|
a2cb5eb4e3 | |
|
|
1f72ffce79 | |
|
|
b0d2ff1c63 | |
|
|
1107634fa6 | |
|
|
d7fc8fe98f | |
|
|
fda490235e | |
|
|
b83985c25b | |
|
|
6aacf524aa | |
|
|
8a314db8dc | |
|
|
783a5404a2 | |
|
|
2c0943ff62 | |
|
|
5d3d77fcfe | |
|
|
c32f36af08 | |
|
|
b31ab1960b | |
|
|
c0989e93f0 | |
|
|
914b3e980f | |
|
|
4f0d09261b | |
|
|
db72df7a63 | |
|
|
3737a69d8d | |
|
|
210474b08c | |
|
|
3040b8ddd5 | |
|
|
b7884aaf2b | |
|
|
015dd2a367 | |
|
|
a16a0f1027 | |
|
|
0cd90d0d2c | |
|
|
8bfd49880e | |
|
|
c607fc3101 | |
|
|
524699d6ab | |
|
|
d87b1cd543 | |
|
|
bfbec71211 | |
|
|
bcf04fadb6 | |
|
|
ecce27ce1d | |
|
|
a747f46292 | |
|
|
eb24d29777 | |
|
|
b73f1030a6 | |
|
|
b627aa7cb5 | |
|
|
ce44eda85a | |
|
|
f6f542c873 | |
|
|
4de4605836 | |
|
|
a1159d98df | |
|
|
390a0e8ef3 | |
|
|
23654254e1 | |
|
|
f5f4dca013 | |
|
|
cd407e2ba3 | |
|
|
9bec2afd60 | |
|
|
6f5656c188 | |
|
|
1fd79c8430 | |
|
|
fa8a277765 | |
|
|
48b5f3b399 | |
|
|
75abcd376b | |
|
|
c832967200 | |
|
|
44a65c23ed | |
|
|
d3f140f1df | |
|
|
f72000f5ae | |
|
|
eba56b088f | |
|
|
13fd0d55c7 | |
|
|
0cd548f1cb | |
|
|
0e471e3ff8 | |
|
|
7b74810047 | |
|
|
acbe1b1f03 | |
|
|
17afd93c78 | |
|
|
9eb32f0766 | |
|
|
3f80b202cd | |
|
|
2afaeac823 | |
|
|
2d9af6c9a4 | |
|
|
f63471bdf5 | |
|
|
52e0a10bf7 | |
|
|
e9a0bf6bf9 | |
|
|
d7ef3cc030 | |
|
|
62a22c7574 | |
|
|
c74144c6eb | |
|
|
6d1d52deaa | |
|
|
d6555f48dd | |
|
|
5fa9192412 | |
|
|
8da884de85 | |
|
|
922ee4f93d | |
|
|
234af64a8c | |
|
|
d140535d64 | |
|
|
9bdb8a7133 | |
|
|
5a00bbaa8f | |
|
|
d223898f3d | |
|
|
67aab70cff | |
|
|
5bc99574fc | |
|
|
38e632a954 | |
|
|
8c7327b8df | |
|
|
dc68fe27f9 | |
|
|
7dcc10a254 | |
|
|
7f0a319564 | |
|
|
5978ccdb52 | |
|
|
706112ebd8 | |
|
|
7fe92148cc | |
|
|
284b9d6a9c | |
|
|
16a3c5fc30 | |
|
|
9bb5333f62 | |
|
|
b3d2419d9a | |
|
|
6097fd4349 | |
|
|
23cfcc1e1f | |
|
|
43f4dccb4f | |
|
|
a316847341 | |
|
|
acdd08fd9b | |
|
|
d10d450f38 | |
|
|
219d6d86d6 | |
|
|
672fd1b629 | |
|
|
f7a520b957 | |
|
|
1d7dfd25c6 | |
|
|
3d602e2f00 | |
|
|
1ca7a3a353 | |
|
|
b77bdeeb17 | |
|
|
8aa57c5d54 | |
|
|
548fd6afb2 | |
|
|
b32bbdfef3 | |
|
|
dcc960beba | |
|
|
c07080f818 | |
|
|
66cdd36d20 | |
|
|
1632dc0d4e | |
|
|
6ca7eab466 | |
|
|
eb264c5d22 | |
|
|
67a2b97cf0 | |
|
|
04dba9eed9 | |
|
|
50010139ef | |
|
|
ba64d6118b | |
|
|
5de12aa6b3 | |
|
|
1bf21626c0 | |
|
|
76e8d21aaf | |
|
|
538ecb4515 | |
|
|
01ad71b26f | |
|
|
8dbf8965fd | |
|
|
652a0aaef7 | |
|
|
72b423ba14 | |
|
|
896e5e7ded | |
|
|
c2fdb86a4d | |
|
|
fb6a4722c2 | |
|
|
3c4c558656 | |
|
|
65ccd3cc69 | |
|
|
d971e3ecff | |
|
|
cc636a0d83 | |
|
|
6836863e55 | |
|
|
ecf6255985 | |
|
|
0f11580fce | |
|
|
3781c1df61 | |
|
|
4d1618f600 | |
|
|
73dac01c15 | |
|
|
31ad17fa1a | |
|
|
7fd4b01fb3 | |
|
|
09b0295c1a | |
|
|
eae19f7a62 | |
|
|
05c897a753 | |
|
|
e1db615384 | |
|
|
7ec8f17094 | |
|
|
9399faac48 | |
|
|
da635a2995 | |
|
|
2f5b81119b | |
|
|
4222921d61 | |
|
|
6e1323caa2 | |
|
|
136bae27d8 | |
|
|
d91a2a049a | |
|
|
475c8dad8e | |
|
|
2800847a16 | |
|
|
1261f71248 | |
|
|
318d5cb54b | |
|
|
57cc2bd089 | |
|
|
09013f3a6e | |
|
|
7d80ea5cf9 | |
|
|
daad9ede01 | |
|
|
89a5395fc6 | |
|
|
6b66b81722 | |
|
|
79456fadde | |
|
|
3a53a950aa | |
|
|
7fe7449685 | |
|
|
9537f391fd | |
|
|
20f9095cf2 | |
|
|
1153b3b6b9 | |
|
|
1ffdbbbebe | |
|
|
588122dc72 | |
|
|
6d866dab6b | |
|
|
a4755a37cb | |
|
|
55aba1731c | |
|
|
f844fb1057 | |
|
|
0c719ab69e | |
|
|
00fa1e3714 | |
|
|
1f0c51533f | |
|
|
4c718f7b50 | |
|
|
7f22cc07b8 | |
|
|
17c9075ba8 | |
|
|
e3feb5c44a | |
|
|
0e88e2739f | |
|
|
1cd5a2ce04 | |
|
|
3daa630a03 | |
|
|
7df17e3c5e | |
|
|
167fceac37 | |
|
|
301469432d | |
|
|
a13dae7a4a | |
|
|
1cdb2dacee | |
|
|
1a525c57a6 | |
|
|
b8f5708ec1 | |
|
|
3488a35472 | |
|
|
855976c61d | |
|
|
0fe977a33c | |
|
|
b7d1435db1 | |
|
|
3309ccabd4 | |
|
|
750f8f174e | |
|
|
01f4eb9b43 | |
|
|
756e21a81d | |
|
|
0971429b56 | |
|
|
0d579a430d | |
|
|
aae3a39914 | |
|
|
5405d4787a | |
|
|
503c4a34b0 | |
|
|
0fab82384a | |
|
|
c4839c92a8 | |
|
|
c2517679d6 | |
|
|
42683a7370 | |
|
|
a7aa3deac9 | |
|
|
a603186d8e | |
|
|
0fa51fd627 | |
|
|
e387ddf849 | |
|
|
3daecc0ea8 | |
|
|
039f05cb56 | |
|
|
74157fc0ab | |
|
|
edb7fb100d | |
|
|
c51c081d90 | |
|
|
a3942996e7 | |
|
|
d9f6af51af | |
|
|
19eaa55c2a | |
|
|
683882f2bb | |
|
|
0108175c6c | |
|
|
a620c09c40 | |
|
|
0f7d05d531 | |
|
|
3592078ddb | |
|
|
55ed1e6698 | |
|
|
623d0f3c9f | |
|
|
0828ac28a0 | |
|
|
354d302fef | |
|
|
82c84387fa | |
|
|
927b60b7a0 | |
|
|
59cfcd2240 | |
|
|
9c2cac9e25 | |
|
|
5bb7fb76a7 | |
|
|
766f64e221 | |
|
|
c70de10002 | |
|
|
e61194bbed | |
|
|
a82bbaa91d | |
|
|
373c5eccf3 | |
|
|
bb64142b07 | |
|
|
1bd088d027 | |
|
|
01b1bd1046 | |
|
|
62b85322ea | |
|
|
bbdfe37bf9 | |
|
|
1de4eafb0d | |
|
|
0b361354b3 | |
|
|
a5a6254db1 | |
|
|
cf25d25dd0 | |
|
|
ea40a95830 | |
|
|
4f0cdd2167 | |
|
|
80c1c01641 | |
|
|
5a9a902044 | |
|
|
ed7de06726 | |
|
|
3d35624be6 | |
|
|
16894c56ee | |
|
|
96e1de436e | |
|
|
bb4378934d | |
|
|
3af039d7c3 | |
|
|
a3fb930e44 | |
|
|
7e501b9b02 | |
|
|
41a2b2a0ef | |
|
|
1f16d8bc90 | |
|
|
26edc73b04 | |
|
|
2c9937e0dd | |
|
|
7c04730a24 | |
|
|
233680f286 | |
|
|
fd5c1d2421 | |
|
|
36b357175a | |
|
|
875ef73275 | |
|
|
38cd47b46c | |
|
|
3b946e76e3 | |
|
|
920f4dbb7d | |
|
|
ec626957b5 | |
|
|
d1ceefee82 | |
|
|
323229a438 | |
|
|
ce3843ec8c | |
|
|
13b0d17169 | |
|
|
6e985705fc | |
|
|
eff805a644 | |
|
|
d785775f64 | |
|
|
dfd8fabdd7 | |
|
|
cc6834d4cc | |
|
|
b417061535 | |
|
|
65a756bf01 | |
|
|
1a91797316 | |
|
|
9f4ab5a2c1 | |
|
|
b633363f06 | |
|
|
eaa9da53cd | |
|
|
36a83acf3c | |
|
|
08d25f39f2 | |
|
|
41c01e4fb7 | |
|
|
6694add40f | |
|
|
1229d1ff07 | |
|
|
a5f4841486 | |
|
|
6d9c8daece | |
|
|
8ffb7811c7 | |
|
|
c1b2a64c2e | |
|
|
7bc6f3396e | |
|
|
953970e73a | |
|
|
9d0e828b85 | |
|
|
3370370101 | |
|
|
a79dc18eb2 | |
|
|
8742534db8 | |
|
|
91aaff2575 | |
|
|
667326b18e | |
|
|
622d142794 | |
|
|
b57b546494 | |
|
|
0d0063f7de | |
|
|
2c1c83f75b | |
|
|
0551ef2a68 | |
|
|
f89df8087d | |
|
|
581c58b9c4 | |
|
|
3f9b46591c | |
|
|
38ad178e9e | |
|
|
bbd0640db2 | |
|
|
1aecc3373c | |
|
|
aa4cada268 | |
|
|
688be5719e | |
|
|
ea0f22de4d | |
|
|
110bac4394 | |
|
|
c899a4cb3b | |
|
|
fa58597321 | |
|
|
e7ecaee92d | |
|
|
a8f0ef2368 | |
|
|
18b9c612f4 | |
|
|
086321a232 | |
|
|
acdb94d1d3 | |
|
|
70a07869c6 | |
|
|
66a5fe7aec | |
|
|
aefbac6b04 | |
|
|
27b8cce3fe | |
|
|
091c589301 | |
|
|
c20f1dcc73 | |
|
|
6e6c728b65 | |
|
|
2c7a456c37 | |
|
|
4e6946ce70 | |
|
|
acc9fbbf1d | |
|
|
3bcc4fc386 | |
|
|
b0518173b1 | |
|
|
74740dc894 | |
|
|
2f0f638007 | |
|
|
5a9f37cd93 | |
|
|
7eff43de41 | |
|
|
be9a35c036 | |
|
|
70cb339f86 | |
|
|
336b41a063 | |
|
|
813a0f1ff1 | |
|
|
4f4bba2a47 | |
|
|
5fb4912559 | |
|
|
fdd5656599 | |
|
|
1bd7550378 | |
|
|
6325e41681 | |
|
|
4d183efe48 | |
|
|
47c153629f | |
|
|
fa6cdf9b48 | |
|
|
124e750e9a | |
|
|
6c8c6aafc5 | |
|
|
2df7443317 | |
|
|
a6c9e997bd | |
|
|
c65e08f9b5 | |
|
|
b69f439609 | |
|
|
96b9ef2ce5 | |
|
|
ab5b16ede2 | |
|
|
7543778f2c | |
|
|
aa21961c24 | |
|
|
0ed81b34f1 | |
|
|
138c381f76 | |
|
|
34d571a562 | |
|
|
c3c643820e | |
|
|
1b0439d128 | |
|
|
af0ac88266 | |
|
|
1368a920b9 | |
|
|
99b33e5dbf | |
|
|
30ddf14c90 | |
|
|
20f970f569 | |
|
|
feedbc7449 | |
|
|
8c923ad492 | |
|
|
21cccea072 | |
|
|
89e1ee8bc9 | |
|
|
132b893921 | |
|
|
a9237f50ea | |
|
|
66449e8033 | |
|
|
ddb22f3bed | |
|
|
7cc11f7f0c | |
|
|
4e89fc7ccb | |
|
|
b6c0b36c8a | |
|
|
c95d9499d9 | |
|
|
8f5c823fa4 | |
|
|
5f40c4704f | |
|
|
f159bef6c3 | |
|
|
163af36fee | |
|
|
1863430528 | |
|
|
69ffaa0912 | |
|
|
65590d0e17 | |
|
|
c23cd0a7c5 | |
|
|
adcc398bc3 | |
|
|
8cf3f54208 | |
|
|
25455d358f | |
|
|
8888e8e82e | |
|
|
8eb651c3d3 | |
|
|
ae0f03f4a9 | |
|
|
3241a595ba | |
|
|
7bda1d4bfb | |
|
|
617eb759ae | |
|
|
aebf1e7b9c | |
|
|
94ab17c39e | |
|
|
5a3e0a1f15 | |
|
|
4f7bf91003 | |
|
|
21922e3e9f | |
|
|
67247b7209 | |
|
|
3d19d411b2 | |
|
|
09a7e6dac7 | |
|
|
6234e18df7 | |
|
|
c84323b5a5 | |
|
|
61f2f3db6f | |
|
|
f6758079f7 | |
|
|
daa4eaf2af | |
|
|
5999b5a516 | |
|
|
0fc56e7199 | |
|
|
c68fcae445 | |
|
|
9e164ec52d | |
|
|
7693ce6a6c | |
|
|
dd81af8170 | |
|
|
ca6dd4ed17 | |
|
|
1abd0457ab | |
|
|
cb30ea0516 | |
|
|
1f56f20e1b | |
|
|
8e13245ed0 | |
|
|
b79f37ae57 | |
|
|
3da935785f | |
|
|
43a15df951 | |
|
|
b29e8a777b | |
|
|
fdf08d2aad | |
|
|
e5e5e3545b | |
|
|
7ad8f9548c | |
|
|
547de09670 | |
|
|
5405003a5e | |
|
|
480aaa6464 | |
|
|
a24b15d03a | |
|
|
4f2cd590bc | |
|
|
b44a8f927b | |
|
|
00b674d5b3 | |
|
|
ee228339e5 | |
|
|
d86e8d9ed8 | |
|
|
32693e9857 | |
|
|
d7ecb23eee | |
|
|
f36724e301 | |
|
|
6606c18c70 | |
|
|
3186a82f65 | |
|
|
bcf21e4677 | |
|
|
31519bd6d6 | |
|
|
34fe762d36 | |
|
|
b442c749e3 | |
|
|
c93c4053d3 | |
|
|
33fb7a809d | |
|
|
ea5648db3f | |
|
|
b4790a64fa | |
|
|
57ef73b205 | |
|
|
cea4130350 | |
|
|
db7ebfb434 | |
|
|
1aeff0325e | |
|
|
6345832dba | |
|
|
faa5947278 | |
|
|
a6f8625d64 | |
|
|
6097ac1d1a | |
|
|
0b4350a0ee | |
|
|
0a536417f6 | |
|
|
2ccb0f7834 | |
|
|
df1f7198e0 | |
|
|
fd975af159 | |
|
|
5fc7e6aac5 | |
|
|
554a1693ac | |
|
|
5b8fa41ba9 | |
|
|
d892e63256 | |
|
|
79f04c6653 | |
|
|
48498af818 | |
|
|
41c4d3c09c | |
|
|
491e0e833f | |
|
|
f288c4d7f6 | |
|
|
85b74f68f1 | |
|
|
25b1a0d81c | |
|
|
f1b64be840 | |
|
|
fb248e1ca1 | |
|
|
8e72ac36d7 | |
|
|
b7176ee3e5 | |
|
|
03b9f41786 | |
|
|
dfa34cc2e4 | |
|
|
f26ea1eaea | |
|
|
96bdcd2bb2 | |
|
|
b10f6bd899 | |
|
|
264dfc7ed4 | |
|
|
87a0a718c9 |
|
|
@ -1,39 +0,0 @@
|
|||
version: '{build}'
|
||||
|
||||
environment:
|
||||
|
||||
matrix:
|
||||
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
|
||||
VCVARS_SCRIPT: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat"
|
||||
VCVARS_PLATFORM: x86
|
||||
|
||||
init:
|
||||
|
||||
- cmd: '"%VCVARS_SCRIPT%" %VCVARS_PLATFORM%'
|
||||
|
||||
build_script:
|
||||
|
||||
- cmd: |
|
||||
sed -i 's#ABC_USE_PTHREADS"#ABC_DONT_USE_PTHREADS" /D "_XKEYCHECK_H"#g' *.dsp
|
||||
awk 'BEGIN { del=0; } /# Begin Group "uap"/ { del=1; } /# End Group/ { if( del > 0 ) {del=0; next;} } del==0 {print;} ' abclib.dsp > tmp.dsp
|
||||
copy tmp.dsp abclib.dsp
|
||||
del tmp.dsp
|
||||
unix2dos *.dsp
|
||||
|
||||
- cmd: |
|
||||
appveyor PushArtifact abcspace.dsw
|
||||
appveyor PushArtifact abclib.dsp
|
||||
appveyor PushArtifact abcexe.dsp
|
||||
|
||||
- cmd: |
|
||||
devenv abcspace.dsw /upgrade || dir
|
||||
appveyor PushArtifact UpgradeLog.htm
|
||||
msbuild abcspace.sln /m /nologo /p:Configuration=Release
|
||||
|
||||
- cmd: |
|
||||
_TEST\abc.exe -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec"
|
||||
|
||||
- cmd: |
|
||||
appveyor PushArtifact _TEST/abc.exe
|
||||
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
/.gitcommit export-subst
|
||||
* text=auto
|
||||
|
||||
*.c text
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
$Format:%H$
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<ProjectGuid>{6B6D7E0F-1234-4567-89AB-CDEF01234568}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>abcexe</RootNamespace>
|
||||
<TargetName>abc</TargetName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>_TEST\</OutDir>
|
||||
<IntDir>ReleaseExe\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DisableSpecificWarnings>4146;4334;4996;4703;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<TreatSpecificWarningsAsErrors>4013</TreatSpecificWarningsAsErrors>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;WINDOWS;NDEBUG;_CONSOLE;ABC_DLL=ABC_DLLEXPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ABC_USE_PTHREADS;ABC_USE_CUDD;HAVE_STRUCT_TIMESPEC;_WINSOCKAPI_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>src</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/Zc:strictStrings- %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;lib\x86\pthreadVC2.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\base\main\main.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="abclib.vcxproj">
|
||||
<Project>{6B6D7E0F-1234-4567-89AB-CDEF01234567}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<ProjectGuid>{6B6D7E0F-1234-4567-89AB-CDEF01234567}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>abclib</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>lib\</OutDir>
|
||||
<IntDir>ReleaseLib\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DisableSpecificWarnings>4146;4334;4996;4703;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<TreatSpecificWarningsAsErrors>4013</TreatSpecificWarningsAsErrors>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;WINDOWS;NDEBUG;_LIB;ABC_DLL=ABC_DLLEXPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ABC_USE_PTHREADS;ABC_USE_CUDD;HAVE_STRUCT_TIMESPEC;_WINSOCKAPI_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>src</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/Zc:strictStrings- %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<OutputFile>$(OutDir)abcr.lib</OutputFile>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
{{SOURCE_FILES}}
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abclib", "abclib.vcxproj", "{6B6D7E0F-1234-4567-89AB-CDEF01234567}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abcexe", "abcexe.vcxproj", "{6B6D7E0F-1234-4567-89AB-CDEF01234568}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6B6D7E0F-1234-4567-89AB-CDEF01234567} = {6B6D7E0F-1234-4567-89AB-CDEF01234567}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6B6D7E0F-1234-4567-89AB-CDEF01234567}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6B6D7E0F-1234-4567-89AB-CDEF01234567}.Release|Win32.Build.0 = Release|Win32
|
||||
{6B6D7E0F-1234-4567-89AB-CDEF01234568}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6B6D7E0F-1234-4567-89AB-CDEF01234568}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
name: Build Posix CMake
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
|
||||
build-posix-cmake:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
use_namespace: [false, true]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
env:
|
||||
CMAKE_ARGS: ${{ matrix.use_namespace && '-DABC_USE_NAMESPACE=xxx' || '' }}
|
||||
DEMO_ARGS: ${{ matrix.use_namespace && '-DABC_NAMESPACE=xxx' || '' }}
|
||||
DEMO_GCC: ${{ matrix.use_namespace && 'g++ -x c++' || 'gcc' }}
|
||||
|
||||
steps:
|
||||
|
||||
- name: Git Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install brew dependencies
|
||||
run: |
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install readline ninja
|
||||
if: ${{ contains(matrix.os, 'macos') }}
|
||||
|
||||
- name: Install APT dependencies
|
||||
run: |
|
||||
sudo apt install -y libreadline-dev ninja-build
|
||||
if: ${{ !contains(matrix.os, 'macos') }}
|
||||
|
||||
- name: Configure CMake
|
||||
run: |
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ${CMAKE_ARGS} -B build
|
||||
|
||||
- name: Build CMake
|
||||
run: |
|
||||
cmake --build build
|
||||
|
||||
- name: Run Unit Tests
|
||||
run: |
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: Test Executable
|
||||
run: |
|
||||
./build/abc -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec"
|
||||
|
||||
- name: Test Library
|
||||
run: |
|
||||
${DEMO_GCC} ${DEMO_ARGS} -Wall -c src/demo.c -o demo.o
|
||||
g++ -o demo demo.o build/libabc.a -lm -ldl -lreadline -lpthread
|
||||
./demo i10.aig
|
||||
|
||||
- name: Stage Executable
|
||||
run: |
|
||||
mkdir staging
|
||||
cp build/abc build/libabc.a staging/
|
||||
|
||||
- name: Upload pacakge artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: package-cmake-${{ matrix.os }}-${{ matrix.use_namespace }}
|
||||
path: staging/
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
name: Build Posix
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
|
||||
build-posix:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
use_namespace: [false, true]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
env:
|
||||
MAKE_ARGS: ${{ matrix.use_namespace && 'ABC_USE_NAMESPACE=xxx' || '' }}
|
||||
DEMO_ARGS: ${{ matrix.use_namespace && '-DABC_NAMESPACE=xxx' || '' }}
|
||||
DEMO_GCC: ${{ matrix.use_namespace && 'g++ -x c++' || 'gcc' }}
|
||||
|
||||
steps:
|
||||
|
||||
- name: Git Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install brew dependencies
|
||||
run: |
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install readline
|
||||
if: ${{ contains(matrix.os, 'macos') }}
|
||||
|
||||
- name: Install APT dependencies
|
||||
run: |
|
||||
sudo apt install -y libreadline-dev
|
||||
if: ${{ !contains(matrix.os, 'macos') }}
|
||||
|
||||
- name: Build Executable
|
||||
run: |
|
||||
make -j3 ${MAKE_ARGS} abc
|
||||
|
||||
- name: Test Executable
|
||||
run: |
|
||||
./abc -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec"
|
||||
|
||||
- name: Build Library
|
||||
run: |
|
||||
make -j3 ${MAKE_ARGS} libabc.a
|
||||
|
||||
- name: Test Library
|
||||
run: |
|
||||
${DEMO_GCC} ${DEMO_ARGS} -Wall -c src/demo.c -o demo.o
|
||||
g++ -o demo demo.o libabc.a -lm -ldl -lreadline -lpthread
|
||||
./demo i10.aig
|
||||
|
||||
- name: Stage Executable
|
||||
run: |
|
||||
mkdir staging
|
||||
cp abc libabc.a staging/
|
||||
|
||||
- name: Upload pacakge artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: package-posix-${{ matrix.os }}-${{ matrix.use_namespace }}
|
||||
path: staging/
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
name: Build Windows
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
|
||||
build-windows:
|
||||
|
||||
runs-on: windows-2025
|
||||
|
||||
steps:
|
||||
|
||||
- name: Git Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup MSVC
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x86
|
||||
|
||||
- name: Copy project files from scripts
|
||||
run: |
|
||||
copy .github\scripts\abcspace.sln .
|
||||
copy .github\scripts\abcexe.vcxproj .
|
||||
|
||||
- name: Generate abclib.vcxproj from dsp
|
||||
shell: powershell
|
||||
run: |
|
||||
# Parse source files from abclib.dsp
|
||||
$dspContent = Get-Content "abclib.dsp" -Raw
|
||||
$sourceFiles = [regex]::Matches($dspContent, 'SOURCE=\.\\([^\r\n]+)') | ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique
|
||||
|
||||
Write-Host "Found $($sourceFiles.Count) source files"
|
||||
|
||||
# Build source file items
|
||||
$sourceItems = ""
|
||||
foreach ($src in $sourceFiles) {
|
||||
if ($src -match '\.c$') {
|
||||
$sourceItems += " <ClCompile Include=`"$src`" />`r`n"
|
||||
} elseif ($src -match '\.(cpp|cc)$') {
|
||||
$sourceItems += " <ClCompile Include=`"$src`" />`r`n"
|
||||
} elseif ($src -match '\.h$') {
|
||||
$sourceItems += " <ClInclude Include=`"$src`" />`r`n"
|
||||
}
|
||||
}
|
||||
|
||||
# Read template and replace placeholder
|
||||
$template = Get-Content ".github\scripts\abclib.vcxproj.template" -Raw
|
||||
$vcxproj = $template -replace '\{\{SOURCE_FILES\}\}', $sourceItems
|
||||
Set-Content "abclib.vcxproj" $vcxproj -NoNewline
|
||||
|
||||
Write-Host "abclib.vcxproj generated successfully"
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
msbuild abcspace.sln /m /nologo /v:m /p:Configuration=Release /p:Platform=Win32 /p:UseMultiToolTask=true
|
||||
if ($LASTEXITCODE -ne 0) { throw "Build failed with exit code $LASTEXITCODE" }
|
||||
|
||||
- name: Test Executable
|
||||
run: |
|
||||
copy lib\x86\pthreadVC2.dll _TEST\
|
||||
.\_TEST\abc.exe -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec"
|
||||
if ($LASTEXITCODE -ne 0) { throw "Test failed with exit code $LASTEXITCODE" }
|
||||
|
||||
- name: Stage Executable
|
||||
run: |
|
||||
mkdir staging
|
||||
copy _TEST\abc.exe staging\
|
||||
|
||||
- name: Upload package artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: package-windows
|
||||
path: staging/
|
||||
|
|
@ -6,11 +6,16 @@ ReleaseLib/
|
|||
ReleaseExe/
|
||||
ReleaseExt/
|
||||
|
||||
_/
|
||||
_TEST/
|
||||
tools/
|
||||
temp/
|
||||
lib/abc*
|
||||
lib/m114*
|
||||
lib/bip*
|
||||
docs/
|
||||
.cache/
|
||||
.vscode/
|
||||
|
||||
src/ext*
|
||||
src/xxx/
|
||||
|
|
@ -28,13 +33,14 @@ src/aig/ddb/
|
|||
*.plg
|
||||
|
||||
*.zip
|
||||
*.DS_Store
|
||||
|
||||
abcspaceext.dsw
|
||||
abcext.dsp
|
||||
|
||||
abcexe.vcproj*
|
||||
abclib.vcproj*
|
||||
abcspace.sln
|
||||
/abcspace.sln
|
||||
abcspace.suo
|
||||
|
||||
*.pyc
|
||||
|
|
@ -59,3 +65,4 @@ tags
|
|||
|
||||
/cmake
|
||||
/cscope
|
||||
abc.history
|
||||
|
|
|
|||
36
.travis.yml
36
.travis.yml
|
|
@ -1,36 +0,0 @@
|
|||
language: cpp
|
||||
|
||||
matrix:
|
||||
include:
|
||||
|
||||
- os: linux
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libreadline-dev
|
||||
|
||||
- os: linux
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libreadline-dev
|
||||
env:
|
||||
MAKE_ARGS: ABC_USE_NAMESPACE=xxx
|
||||
DEMO_ARGS: -DABC_NAMESPACE=xxx
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
addons:
|
||||
homebrew:
|
||||
packages:
|
||||
- readline
|
||||
|
||||
script:
|
||||
|
||||
- make ${MAKE_ARGS} -j2 abc
|
||||
- ./abc -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec"
|
||||
|
||||
- make ${MAKE_ARGS} libabc.a
|
||||
- g++ ${DEMO_ARGS} -Wall -c src/demo.c -o demo.o
|
||||
- g++ -o demo demo.o libabc.a -lm -ldl -lreadline -lpthread
|
||||
- ./demo i10.aig
|
||||
|
|
@ -1,8 +1,14 @@
|
|||
cmake_minimum_required(VERSION 3.3.0)
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
|
||||
include(CMakeParseArguments)
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
# Generate compilation database compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Default c++ standard used unless otherwise specified in target_compile_features.
|
||||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "the C++ standard to use for this project")
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
function(addprefix var prefix)
|
||||
foreach( s ${ARGN} )
|
||||
|
|
@ -47,9 +53,14 @@ if(ABC_USE_NAMESPACE)
|
|||
set(ABC_USE_NAMESPACE_FLAGS "ABC_USE_NAMESPACE=${ABC_USE_NAMESPACE}")
|
||||
endif()
|
||||
|
||||
if( APPLE )
|
||||
set(make_env ${CMAKE_COMMAND} -E env SDKROOT=${CMAKE_OSX_SYSROOT})
|
||||
endif()
|
||||
|
||||
# run make to extract compiler options, linker options and list of source files
|
||||
execute_process(
|
||||
COMMAND
|
||||
${make_env}
|
||||
make
|
||||
${ABC_READLINE_FLAGS}
|
||||
${ABC_USE_NAMESPACE_FLAGS}
|
||||
|
|
@ -103,3 +114,17 @@ add_library(libabc-pic EXCLUDE_FROM_ALL ${ABC_SRC})
|
|||
abc_properties(libabc-pic PUBLIC)
|
||||
set_property(TARGET libabc-pic PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET libabc-pic PROPERTY OUTPUT_NAME abc-pic)
|
||||
|
||||
if(NOT DEFINED ABC_SKIP_TESTS)
|
||||
enable_testing()
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
# Specify the commit you depend on and update it regularly.
|
||||
URL "https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip"
|
||||
)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
include(GoogleTest)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
103
Makefile
103
Makefile
|
|
@ -4,13 +4,30 @@ CXX := g++
|
|||
AR := ar
|
||||
LD := $(CXX)
|
||||
|
||||
MSG_PREFIX ?=
|
||||
ABCSRC = .
|
||||
# Auto-enable ccache if available
|
||||
CCACHE := $(shell command -v ccache 2>/dev/null)
|
||||
ifneq ($(CCACHE),)
|
||||
CC := $(CCACHE) $(CC)
|
||||
CXX := $(CCACHE) $(CXX)
|
||||
endif
|
||||
|
||||
$(info $(MSG_PREFIX)Using CC=$(CC))
|
||||
$(info $(MSG_PREFIX)Using CXX=$(CXX))
|
||||
$(info $(MSG_PREFIX)Using AR=$(AR))
|
||||
$(info $(MSG_PREFIX)Using LD=$(LD))
|
||||
MSG_PREFIX ?=
|
||||
ABCSRC ?= .
|
||||
VPATH = $(ABCSRC)
|
||||
|
||||
# whether to print build options, tools, and echo commands while building
|
||||
ifdef ABC_MAKE_VERBOSE
|
||||
VERBOSE=
|
||||
abc_info = $(info $(1))
|
||||
else
|
||||
VERBOSE=@
|
||||
abc_info =
|
||||
endif
|
||||
|
||||
$(call abc_info,$(MSG_PREFIX)Using CC=$(CC))
|
||||
$(call abc_info,$(MSG_PREFIX)Using CXX=$(CXX))
|
||||
$(call abc_info,$(MSG_PREFIX)Using AR=$(AR))
|
||||
$(call abc_info,$(MSG_PREFIX)Using LD=$(LD))
|
||||
|
||||
PROG := abc
|
||||
OS := $(shell uname -s)
|
||||
|
|
@ -18,16 +35,16 @@ OS := $(shell uname -s)
|
|||
MODULES := \
|
||||
$(wildcard src/ext*) \
|
||||
src/base/abc src/base/abci src/base/cmd src/base/io src/base/main src/base/exor \
|
||||
src/base/ver src/base/wlc src/base/wln src/base/acb src/base/bac src/base/cba src/base/pla src/base/test \
|
||||
src/map/mapper src/map/mio src/map/super src/map/if \
|
||||
src/map/amap src/map/cov src/map/scl src/map/mpm \
|
||||
src/base/ver src/base/wlc src/base/wln src/base/sn src/base/acb src/base/pla src/base/test \
|
||||
src/map/mapper src/map/mio src/map/super src/map/if src/map/if/acd \
|
||||
src/map/amap src/map/cov src/map/scl src/map/mpm src/map/emap \
|
||||
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/nm \
|
||||
src/misc/vec src/misc/hash src/misc/tim src/misc/bzlib src/misc/zlib \
|
||||
src/misc/mem src/misc/bar src/misc/bbl src/misc/parse \
|
||||
src/misc/mem src/misc/bar src/misc/bbl src/misc/parse src/misc/btor \
|
||||
src/opt/cut src/opt/fxu src/opt/fxch src/opt/rwr src/opt/mfs src/opt/sim \
|
||||
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \
|
||||
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd \
|
||||
src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc src/sat/glucose src/sat/glucose2 \
|
||||
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt src/opt/rar \
|
||||
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd src/opt/eslim src/opt/ufar src/opt/untk src/opt/util \
|
||||
src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc src/sat/glucose src/sat/glucose2 src/sat/kissat src/sat/cadical \
|
||||
src/bool/bdc src/bool/deco src/bool/dec src/bool/kit src/bool/lucky \
|
||||
src/bool/rsb src/bool/rpo \
|
||||
src/proof/pdr src/proof/abs src/proof/live src/proof/ssc src/proof/int \
|
||||
|
|
@ -41,7 +58,7 @@ default: $(PROG)
|
|||
ARCHFLAGS_EXE ?= ./arch_flags
|
||||
|
||||
$(ARCHFLAGS_EXE) : arch_flags.c
|
||||
$(CC) arch_flags.c -o $(ARCHFLAGS_EXE)
|
||||
$(CC) $< -o $(ARCHFLAGS_EXE)
|
||||
|
||||
INCLUDES += -I$(ABCSRC)/src
|
||||
|
||||
|
|
@ -61,18 +78,18 @@ ifneq ($(findstring arm,$(shell uname -m)),)
|
|||
CFLAGS += -DABC_MEMALIGN=4
|
||||
endif
|
||||
|
||||
# compile ABC using the C++ comipler and put everything in the namespace $(ABC_NAMESPACE)
|
||||
# compile ABC using the C++ compiler and put everything in the namespace $(ABC_NAMESPACE)
|
||||
ifdef ABC_USE_NAMESPACE
|
||||
CFLAGS += -DABC_NAMESPACE=$(ABC_USE_NAMESPACE) -fpermissive
|
||||
CFLAGS += -DABC_NAMESPACE=$(ABC_USE_NAMESPACE) -fpermissive -x c++
|
||||
CC := $(CXX)
|
||||
$(info $(MSG_PREFIX)Compiling in namespace $(ABC_NAMESPACE))
|
||||
$(call abc_info,$(MSG_PREFIX)Compiling in namespace $(ABC_USE_NAMESPACE))
|
||||
endif
|
||||
|
||||
# compile CUDD with ABC
|
||||
ifndef ABC_USE_NO_CUDD
|
||||
CFLAGS += -DABC_USE_CUDD=1
|
||||
MODULES += src/bdd/cudd src/bdd/extrab src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/reo src/bdd/cas src/bdd/bbr src/bdd/llb
|
||||
$(info $(MSG_PREFIX)Compiling with CUDD)
|
||||
$(call abc_info,$(MSG_PREFIX)Compiling with CUDD)
|
||||
endif
|
||||
|
||||
ABC_READLINE_INCLUDES ?=
|
||||
|
|
@ -86,28 +103,21 @@ ifndef ABC_USE_NO_READLINE
|
|||
CFLAGS += -I/usr/local/include
|
||||
LDFLAGS += -L/usr/local/lib
|
||||
endif
|
||||
$(info $(MSG_PREFIX)Using libreadline)
|
||||
$(call abc_info,$(MSG_PREFIX)Using libreadline)
|
||||
endif
|
||||
|
||||
# whether to compile with thread support
|
||||
ifndef ABC_USE_NO_PTHREADS
|
||||
CFLAGS += -DABC_USE_PTHREADS
|
||||
LIBS += -lpthread
|
||||
$(info $(MSG_PREFIX)Using pthreads)
|
||||
$(call abc_info,$(MSG_PREFIX)Using pthreads)
|
||||
endif
|
||||
|
||||
# whether to compile into position independent code
|
||||
ifdef ABC_USE_PIC
|
||||
CFLAGS += -fPIC
|
||||
LIBS += -fPIC
|
||||
$(info $(MSG_PREFIX)Compiling position independent code)
|
||||
endif
|
||||
|
||||
# whether to echo commands while building
|
||||
ifdef ABC_MAKE_VERBOSE
|
||||
VERBOSE=
|
||||
else
|
||||
VERBOSE=@
|
||||
$(call abc_info,$(MSG_PREFIX)Compiling position independent code)
|
||||
endif
|
||||
|
||||
# Set -Wno-unused-bug-set-variable for GCC 4.6.0 and greater only
|
||||
|
|
@ -119,16 +129,16 @@ GCC_VERSION=$(shell $(CC) -dumpversion)
|
|||
GCC_MAJOR=$(word 1,$(subst .,$(space),$(GCC_VERSION)))
|
||||
GCC_MINOR=$(word 2,$(subst .,$(space),$(GCC_VERSION)))
|
||||
|
||||
$(info $(MSG_PREFIX)Found GCC_VERSION $(GCC_VERSION))
|
||||
$(call abc_info,$(MSG_PREFIX)Found GCC_VERSION $(GCC_VERSION))
|
||||
ifeq ($(findstring $(GCC_MAJOR),0 1 2 3),)
|
||||
ifeq ($(GCC_MAJOR),4)
|
||||
$(info $(MSG_PREFIX)Found GCC_MAJOR==4)
|
||||
$(call abc_info,$(MSG_PREFIX)Found GCC_MAJOR==4)
|
||||
ifeq ($(findstring $(GCC_MINOR),0 1 2 3 4 5),)
|
||||
$(info $(MSG_PREFIX)Found GCC_MINOR>=6)
|
||||
$(call abc_info,$(MSG_PREFIX)Found GCC_MINOR>=6)
|
||||
CFLAGS += -Wno-unused-but-set-variable
|
||||
endif
|
||||
else
|
||||
$(info $(MSG_PREFIX)Found GCC_MAJOR>=5)
|
||||
$(call abc_info,$(MSG_PREFIX)Found GCC_MAJOR>=5)
|
||||
CFLAGS += -Wno-unused-but-set-variable
|
||||
endif
|
||||
endif
|
||||
|
|
@ -137,21 +147,21 @@ endif
|
|||
|
||||
# LIBS := -ldl -lrt
|
||||
LIBS += -lm
|
||||
ifneq ($(OS), FreeBSD)
|
||||
ifneq ($(OS), $(filter $(OS), FreeBSD OpenBSD NetBSD))
|
||||
LIBS += -ldl
|
||||
endif
|
||||
|
||||
ifneq ($(findstring Darwin, $(shell uname)), Darwin)
|
||||
ifneq ($(OS), $(filter $(OS), FreeBSD OpenBSD NetBSD Darwin))
|
||||
LIBS += -lrt
|
||||
endif
|
||||
|
||||
ifdef ABC_USE_LIBSTDCXX
|
||||
LIBS += -lstdc++
|
||||
$(info $(MSG_PREFIX)Using explicit -lstdc++)
|
||||
$(call abc_info,$(MSG_PREFIX)Using explicit -lstdc++)
|
||||
endif
|
||||
|
||||
$(info $(MSG_PREFIX)Using CFLAGS=$(CFLAGS))
|
||||
CXXFLAGS += $(CFLAGS)
|
||||
$(call abc_info,$(MSG_PREFIX)Using CFLAGS=$(CFLAGS))
|
||||
CXXFLAGS += $(CFLAGS) -std=c++17 -fno-exceptions
|
||||
|
||||
SRC :=
|
||||
GARBAGE := core core.* *.stackdump ./tags $(PROG) arch_flags
|
||||
|
|
@ -173,28 +183,34 @@ DEP := $(OBJ:.o=.d)
|
|||
# implicit rules
|
||||
|
||||
%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
@echo "$(MSG_PREFIX)\`\` Compiling:" $(LOCAL_PATH)/$<
|
||||
$(VERBOSE)$(CC) -c $(OPTFLAGS) $(INCLUDES) $(CFLAGS) $< -o $@
|
||||
$(VERBOSE)$(CC) -c $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $< -o $@
|
||||
|
||||
%.o: %.cc
|
||||
@mkdir -p $(dir $@)
|
||||
@echo "$(MSG_PREFIX)\`\` Compiling:" $(LOCAL_PATH)/$<
|
||||
$(VERBOSE)$(CXX) -c $(OPTFLAGS) $(INCLUDES) $(CXXFLAGS) $< -o $@
|
||||
$(VERBOSE)$(CXX) -c $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS) $< -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
@echo "$(MSG_PREFIX)\`\` Compiling:" $(LOCAL_PATH)/$<
|
||||
$(VERBOSE)$(CXX) -c $(OPTFLAGS) $(INCLUDES) $(CXXFLAGS) $< -o $@
|
||||
$(VERBOSE)$(CXX) -c $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS) $< -o $@
|
||||
|
||||
%.d: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
@echo "$(MSG_PREFIX)\`\` Generating dependency:" $(LOCAL_PATH)/$<
|
||||
$(VERBOSE)$(ABCSRC)/depends.sh "$(CC)" `dirname $*.c` $(OPTFLAGS) $(INCLUDES) $(CFLAGS) $< > $@
|
||||
$(VERBOSE)$(ABCSRC)/depends.sh "$(CC)" `dirname $*.c` $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $< > $@
|
||||
|
||||
%.d: %.cc
|
||||
@mkdir -p $(dir $@)
|
||||
@echo "$(MSG_PREFIX)\`\` Generating dependency:" $(LOCAL_PATH)/$<
|
||||
$(VERBOSE)$(ABCSRC)/depends.sh "$(CXX)" `dirname $*.cc` $(OPTFLAGS) $(INCLUDES) $(CXXFLAGS) $< > $@
|
||||
$(VERBOSE)$(ABCSRC)/depends.sh "$(CXX)" `dirname $*.cc` $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS) $< > $@
|
||||
|
||||
%.d: %.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
@echo "$(MSG_PREFIX)\`\` Generating dependency:" $(LOCAL_PATH)/$<
|
||||
$(VERBOSE)$(ABCSRC)/depends.sh "$(CXX)" `dirname $*.cpp` $(OPTFLAGS) $(INCLUDES) $(CXXFLAGS) $< > $@
|
||||
$(VERBOSE)$(ABCSRC)/depends.sh "$(CXX)" `dirname $*.cpp` $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS) $< > $@
|
||||
|
||||
ifndef ABC_MAKE_NO_DEPS
|
||||
-include $(DEP)
|
||||
|
|
@ -210,6 +226,7 @@ clean:
|
|||
$(VERBOSE)rm -rvf $(OBJ)
|
||||
$(VERBOSE)rm -rvf $(GARBAGE)
|
||||
$(VERBOSE)rm -rvf $(OBJ:.o=.d)
|
||||
@if [ -n "$(CCACHE)" ]; then echo "$(MSG_PREFIX)ccache available: $(CCACHE)"; fi
|
||||
|
||||
tags:
|
||||
etags `find . -type f -regex '.*\.\(c\|h\)'`
|
||||
|
|
|
|||
19
README.md
19
README.md
|
|
@ -1,9 +1,22 @@
|
|||
[](https://travis-ci.org/berkeley-abc/abc)
|
||||
[](https://ci.appveyor.com/project/berkeley-abc/abc)
|
||||
[](https://github.com/berkeley-abc/abc/actions/workflows/build-posix.yml)
|
||||
[](https://github.com/berkeley-abc/abc/actions/workflows/build-windows.yml)
|
||||
[](https://github.com/berkeley-abc/abc/actions/workflows/build-posix-cmake.yml)
|
||||
|
||||
# ABC: System for Sequential Logic Synthesis and Formal Verification
|
||||
|
||||
ABC is always changing but the current snapshot is believed to be stable.
|
||||
ABC is always changing but the current snapshot is believed to be stable.
|
||||
|
||||
## ABC fork with new features
|
||||
|
||||
Here is a [fork](https://github.com/yongshiwo/abc.git) of ABC containing Agdmap, a novel technology mapper for LUT-based FPGAs. Agdmap is based on a technology mapping algorithm with adaptive gate decomposition [1]. It is a cut enumeration based mapping algorithm with bin packing for simultaneous wide gate decomposition, which is a patent pending technology.
|
||||
|
||||
The mapper is developed and maintained by Longfei Fan and Prof. Chang Wu at Fudan University in Shanghai, China. The experimental results presented in [1] indicate that Agdmap can substantially improve area (by 10% or more) when compared against the best LUT mapping solutions in ABC, such as command "if".
|
||||
|
||||
The source code is provided for research and evaluation only. For commercial usage, please contact Prof. Chang Wu at wuchang@fudan.edu.cn.
|
||||
|
||||
References:
|
||||
|
||||
[1] L. Fan and C. Wu, "FPGA technology mapping with adaptive gate decompostion", ACM/SIGDA FPGA International Symposium on FPGAs, 2023.
|
||||
|
||||
## Compiling:
|
||||
|
||||
|
|
|
|||
4
abc.rc
4
abc.rc
|
|
@ -132,7 +132,11 @@ alias src_rw "st; rw -l; rwz -l; rwz -l"
|
|||
alias src_rs "st; rs -K 6 -N 2 -l; rs -K 9 -N 2 -l; rs -K 12 -N 2 -l"
|
||||
alias src_rws "st; rw -l; rs -K 6 -N 2 -l; rwz -l; rs -K 9 -N 2 -l; rwz -l; rs -K 12 -N 2 -l"
|
||||
alias resyn2rs "b; rs -K 6; rw; rs -K 6 -N 2; rf; rs -K 8; b; rs -K 8 -N 2; rw; rs -K 10; rwz; rs -K 10 -N 2; b; rs -K 12; rfz; rs -K 12 -N 2; rwz; b"
|
||||
alias r2rs "b; rs -K 6; rw; rs -K 6 -N 2; rf; rs -K 8; b; rs -K 8 -N 2; rw; rs -K 10; rwz; rs -K 10 -N 2; b; rs -K 12; rfz; rs -K 12 -N 2; rwz; b"
|
||||
alias compress2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l; b -l; rs -K 8 -N 2 -l; rw -l; rs -K 10 -l; rwz -l; rs -K 10 -N 2 -l; b -l; rs -K 12 -l; rfz -l; rs -K 12 -N 2 -l; rwz -l; b -l"
|
||||
alias c2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l; b -l; rs -K 8 -N 2 -l; rw -l; rs -K 10 -l; rwz -l; rs -K 10 -N 2 -l; b -l; rs -K 12 -l; rfz -l; rs -K 12 -N 2 -l; rwz -l; b -l"
|
||||
alias &resyn2rs "&put; resyn2rs; &get"
|
||||
alias &compress2rs "&put; compress2rs; &get"
|
||||
|
||||
# use this script to convert 1-valued and DC-valued flops for an AIG
|
||||
alias fix_aig "logic; undc; strash; zero"
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ RSC=rc.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "src" /D "WIN32" /D "WINDOWS" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /D "ABC_USE_CUDD" /FR /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "src" /D "WIN32" /D "WINDOWS" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /D "ABC_USE_CUDD" /D "HAVE_STRUCT_TIMESPEC" /D "_WINSOCKAPI_" /FR /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
|
@ -67,7 +67,7 @@ LINK32=link.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "src" /D "WIN32" /D "WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /D "ABC_USE_CUDD" /FR /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "src" /D "WIN32" /D "WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /D "ABC_USE_CUDD" /D "HAVE_STRUCT_TIMESPEC" /D "_WINSOCKAPI_" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
|
|
|||
1413
abclib.dsp
1413
abclib.dsp
File diff suppressed because it is too large
Load Diff
24
readmeaig
24
readmeaig
|
|
@ -45,3 +45,27 @@ Using GIA Package in ABC
|
|||
- For each object in the design annotated with the constructed AIG node (pNode), remember its AIG node ID by calling Gia_ObjId(pMan,pNode).
|
||||
- Quit the AIG package using Gia_ManStop().
|
||||
The above process should not produce memory leaks.
|
||||
|
||||
|
||||
|
||||
|
||||
Using MiniAIG Package
|
||||
|
||||
- Add #include "miniaig.h".
|
||||
- Start the AIG package using Mini_AigStart().
|
||||
- Assign primary inputs using Mini_AigCreatePi().
|
||||
- Assign flop outputs using Mini_AigCreatePi().
|
||||
(It is important to create all PIs first, before creating flop outputs.)
|
||||
(Flop control logic, if present, should be elaborated into AND gates. For example, to represent a flop enable, create the driver of enable signal, which can be a PI or an internal node, and then add logic for <flop_input_new> = MUX( <enable>, <flop_input>, <flop_output> ). The output of this logic feeds into the flop.
|
||||
- Construct AIG in a topological order using Mini_AigAnd(), Mini_AigOr(), etc.
|
||||
- If constant-0 or constant-1 functions are needed, use 0 or 1.
|
||||
- Create primary outputs using Mini_AigCreatePo().
|
||||
- Create flop inputs using Mini_AigCreatePo().
|
||||
(It is important to create all POs first, before creating register inputs.)
|
||||
- Set the number of flops by calling Mini_AigSetRegNum().
|
||||
- The AIG may contain internal nodes without fanout and/or internal nodes fed by constants.
|
||||
- Dump AIG in internal MiniAIG binary format using Mini_AigDump() and read it into ABC using "&read -m file.mini"
|
||||
- Dump AIG in standard AIGER format (https://fmv.jku.at/aiger/index.html) using Mini_AigerWrite() and read it into ABC using "&read file.aig"
|
||||
- For each object in the design represented using MiniAIG, it may be helpful to save the MiniAIG literal returned by Mini_AigAnd(), Mini_AigOr(), etc when constructing that object.
|
||||
- Quit the AIG package using Mini_AigStop().
|
||||
The above process should not produce memory leaks.
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ static inline Aig_Cut_t * Aig_CutNext( Aig_Cut_t * pCut ) { return
|
|||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline unsigned Aig_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); }
|
||||
static inline unsigned Aig_ObjCutSign( unsigned ObjId ) { return (1U << (ObjId & 31)); }
|
||||
static inline int Aig_WordCountOnes( unsigned uWord )
|
||||
{
|
||||
uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555);
|
||||
|
|
|
|||
|
|
@ -1154,7 +1154,7 @@ Aig_Man_t * Aig_ManDupOneOutput( Aig_Man_t * p, int iPoNum, int fAddRegs )
|
|||
Aig_Man_t * pNew;
|
||||
Aig_Obj_t * pObj = NULL;
|
||||
int i;
|
||||
assert( Aig_ManRegNum(p) > 0 );
|
||||
//assert( Aig_ManRegNum(p) > 0 );
|
||||
assert( iPoNum < Aig_ManCoNum(p)-Aig_ManRegNum(p) );
|
||||
// create the new manager
|
||||
pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ Aig_Obj_t * Aig_Miter( Aig_Man_t * p, Vec_Ptr_t * vPairs )
|
|||
Aig_Obj_t * Aig_MiterTwo( Aig_Man_t * p, Vec_Ptr_t * vNodes1, Vec_Ptr_t * vNodes2 )
|
||||
{
|
||||
int i;
|
||||
assert( vNodes1->nSize > 0 && vNodes1->nSize > 0 );
|
||||
assert( vNodes1->nSize > 0 && vNodes2->nSize > 0 );
|
||||
assert( vNodes1->nSize == vNodes2->nSize );
|
||||
for ( i = 0; i < vNodes1->nSize; i++ )
|
||||
vNodes1->pArray[i] = Aig_Not( Aig_Exor( p, (Aig_Obj_t *)vNodes1->pArray[i], (Aig_Obj_t *)vNodes2->pArray[i] ) );
|
||||
|
|
|
|||
|
|
@ -340,11 +340,11 @@ void Aig_WriteDotAig( Aig_Man_t * pMan, char * pFileName, int fHaig, Vec_Ptr_t *
|
|||
***********************************************************************/
|
||||
void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold )
|
||||
{
|
||||
extern void Abc_ShowFile( char * FileNameDot );
|
||||
extern void Abc_ShowFile( char * FileNameDot, int fKeepDot );
|
||||
char FileNameDot[200];
|
||||
FILE * pFile;
|
||||
// create the file name
|
||||
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") );
|
||||
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName ? pMan->pName : (char *)"unknown", ".dot") );
|
||||
// check that the file can be opened
|
||||
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
|
||||
{
|
||||
|
|
@ -355,7 +355,7 @@ void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold )
|
|||
// generate the file
|
||||
Aig_WriteDotAig( pMan, FileNameDot, fHaig, vBold );
|
||||
// visualize the file
|
||||
Abc_ShowFile( FileNameDot );
|
||||
Abc_ShowFile( FileNameDot, 0 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1169,8 +1169,13 @@ void Aig_ManRandomTest1()
|
|||
***********************************************************************/
|
||||
unsigned Aig_ManRandom( int fReset )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
static unsigned int m_z = NUMBER1;
|
||||
static unsigned int m_w = NUMBER2;
|
||||
#else
|
||||
static __thread unsigned int m_z = NUMBER1;
|
||||
static __thread unsigned int m_w = NUMBER2;
|
||||
#endif
|
||||
if ( fReset )
|
||||
{
|
||||
m_z = NUMBER1;
|
||||
|
|
@ -1333,7 +1338,7 @@ void Aig_ManCounterExampleValueStart( Aig_Man_t * pAig, Abc_Cex_t * pCex )
|
|||
pAig->pData2 = ABC_CALLOC( unsigned, Abc_BitWordNum( (pCex->iFrame + 1) * Aig_ManObjNumMax(pAig) ) );
|
||||
// the register values in the counter-example should be zero
|
||||
Saig_ManForEachLo( pAig, pObj, k )
|
||||
assert( Abc_InfoHasBit(pCex->pData, iBit++) == 0 );
|
||||
assert( Abc_InfoHasBit(pCex->pData, iBit) == 0 ), iBit++;
|
||||
// iterate through the timeframes
|
||||
nObjs = Aig_ManObjNumMax(pAig);
|
||||
for ( i = 0; i <= pCex->iFrame; i++ )
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ struct Gia_Man_t_
|
|||
void * pSatlutWinman; // windowing for SAT-based mapping
|
||||
Vec_Int_t * vPacking; // packing information
|
||||
Vec_Int_t * vConfigs; // cell configurations
|
||||
Vec_Str_t * vConfigs2; // cell configurations
|
||||
char * pCellStr; // cell description
|
||||
Vec_Int_t * vLutConfigs; // LUT configurations
|
||||
Vec_Int_t * vEdgeDelay; // special edge information
|
||||
|
|
@ -188,11 +189,13 @@ struct Gia_Man_t_
|
|||
Vec_Int_t * vCoNumsOrig; // original CO names
|
||||
Vec_Int_t * vIdsOrig; // original object IDs
|
||||
Vec_Int_t * vIdsEquiv; // original object IDs proved equivalent
|
||||
Vec_Int_t * vEquLitIds; // original object IDs proved equivalent
|
||||
Vec_Int_t * vCofVars; // cofactoring variables
|
||||
Vec_Vec_t * vClockDoms; // clock domains
|
||||
Vec_Flt_t * vTiming; // arrival/required/slack
|
||||
void * pManTime; // the timing manager
|
||||
void * pLutLib; // LUT library
|
||||
void * pCellLib; // cell library
|
||||
word nHashHit; // hash table hit
|
||||
word nHashMiss; // hash table miss
|
||||
void * pData; // various user data
|
||||
|
|
@ -241,6 +244,19 @@ struct Gia_Man_t_
|
|||
Vec_Int_t vSuppVars; // used variables
|
||||
Vec_Int_t vVarMap; // used variables
|
||||
Gia_Dat_t * pUData;
|
||||
// retiming data
|
||||
Vec_Str_t * vStopsF;
|
||||
Vec_Str_t * vStopsB;
|
||||
// iteration with boxes
|
||||
int iFirstNonPiId;
|
||||
int iFirstPoId;
|
||||
int iFirstAndObj;
|
||||
int iFirstPoObj;
|
||||
Vec_Str_t * vTTISOPs; // truth tables from ISOP computation
|
||||
Vec_Int_t * vTTLut; // truth tables from ISOP computation
|
||||
Vec_Int_t * vMFFCsInfo; // MFFC information
|
||||
Vec_Int_t * vMFFCsLuts; // MFFCs for each lut
|
||||
Vec_Ptr_t * vLutsRankings; // LUTs rankings of inputs
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -257,6 +273,7 @@ struct Gps_Par_t_
|
|||
int fSkipMap;
|
||||
int fSlacks;
|
||||
int fNoColor;
|
||||
int fMapOutStats;
|
||||
char * pDumpFile;
|
||||
};
|
||||
|
||||
|
|
@ -359,6 +376,7 @@ struct Jf_Par_t_
|
|||
int nCutNumMax;
|
||||
int nProcNumMax;
|
||||
int nLutSizeMux;
|
||||
int nMaxMatches;
|
||||
word Delay;
|
||||
word Area;
|
||||
word Edge;
|
||||
|
|
@ -374,6 +392,7 @@ struct Jf_Par_t_
|
|||
float Epsilon;
|
||||
float * pTimesArr;
|
||||
float * pTimesReq;
|
||||
char * ZFile;
|
||||
};
|
||||
|
||||
static inline unsigned Gia_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); }
|
||||
|
|
@ -527,24 +546,30 @@ static inline int Gia_ObjDiff1( Gia_Obj_t * pObj ) {
|
|||
static inline int Gia_ObjFaninC0( Gia_Obj_t * pObj ) { return pObj->fCompl0; }
|
||||
static inline int Gia_ObjFaninC1( Gia_Obj_t * pObj ) { return pObj->fCompl1; }
|
||||
static inline int Gia_ObjFaninC2( Gia_Man_t * p, Gia_Obj_t * pObj ) { return p->pMuxes && Abc_LitIsCompl(p->pMuxes[Gia_ObjId(p, pObj)]); }
|
||||
static inline int Gia_ObjFaninC( Gia_Obj_t * pObj, int n ) { return n ? Gia_ObjFaninC1(pObj) : Gia_ObjFaninC0(pObj); }
|
||||
static inline Gia_Obj_t * Gia_ObjFanin0( Gia_Obj_t * pObj ) { return pObj - pObj->iDiff0; }
|
||||
static inline Gia_Obj_t * Gia_ObjFanin1( Gia_Obj_t * pObj ) { return pObj - pObj->iDiff1; }
|
||||
static inline Gia_Obj_t * Gia_ObjFanin2( Gia_Man_t * p, Gia_Obj_t * pObj ) { return p->pMuxes ? Gia_ManObj(p, Abc_Lit2Var(p->pMuxes[Gia_ObjId(p, pObj)])) : NULL; }
|
||||
static inline Gia_Obj_t * Gia_ObjFanin( Gia_Obj_t * pObj, int n ) { return n ? Gia_ObjFanin1(pObj) : Gia_ObjFanin0(pObj); }
|
||||
static inline Gia_Obj_t * Gia_ObjChild0( Gia_Obj_t * pObj ) { return Gia_NotCond( Gia_ObjFanin0(pObj), Gia_ObjFaninC0(pObj) ); }
|
||||
static inline Gia_Obj_t * Gia_ObjChild1( Gia_Obj_t * pObj ) { return Gia_NotCond( Gia_ObjFanin1(pObj), Gia_ObjFaninC1(pObj) ); }
|
||||
static inline Gia_Obj_t * Gia_ObjChild2( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_NotCond( Gia_ObjFanin2(p, pObj), Gia_ObjFaninC2(p, pObj) ); }
|
||||
static inline int Gia_ObjFaninId0( Gia_Obj_t * pObj, int ObjId ) { return ObjId - pObj->iDiff0; }
|
||||
static inline int Gia_ObjFaninId1( Gia_Obj_t * pObj, int ObjId ) { return ObjId - pObj->iDiff1; }
|
||||
static inline int Gia_ObjFaninId2( Gia_Man_t * p, int ObjId ) { return (p->pMuxes && p->pMuxes[ObjId]) ? Abc_Lit2Var(p->pMuxes[ObjId]) : -1; }
|
||||
static inline int Gia_ObjFaninId( Gia_Obj_t * pObj, int ObjId, int n ){ return n ? Gia_ObjFaninId1(pObj, ObjId) : Gia_ObjFaninId0(pObj, ObjId); }
|
||||
static inline int Gia_ObjFaninId0p( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjFaninId0( pObj, Gia_ObjId(p, pObj) ); }
|
||||
static inline int Gia_ObjFaninId1p( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjFaninId1( pObj, Gia_ObjId(p, pObj) ); }
|
||||
static inline int Gia_ObjFaninId2p( Gia_Man_t * p, Gia_Obj_t * pObj ) { return (p->pMuxes && p->pMuxes[Gia_ObjId(p, pObj)]) ? Abc_Lit2Var(p->pMuxes[Gia_ObjId(p, pObj)]) : -1; }
|
||||
static inline int Gia_ObjFaninIdp( Gia_Man_t * p, Gia_Obj_t * pObj, int n){ return n ? Gia_ObjFaninId1p(p, pObj) : Gia_ObjFaninId0p(p, pObj); }
|
||||
static inline int Gia_ObjFaninLit0( Gia_Obj_t * pObj, int ObjId ) { return Abc_Var2Lit( Gia_ObjFaninId0(pObj, ObjId), Gia_ObjFaninC0(pObj) ); }
|
||||
static inline int Gia_ObjFaninLit1( Gia_Obj_t * pObj, int ObjId ) { return Abc_Var2Lit( Gia_ObjFaninId1(pObj, ObjId), Gia_ObjFaninC1(pObj) ); }
|
||||
static inline int Gia_ObjFaninLit2( Gia_Man_t * p, int ObjId ) { return (p->pMuxes && p->pMuxes[ObjId]) ? p->pMuxes[ObjId] : -1; }
|
||||
static inline int Gia_ObjFaninLit( Gia_Obj_t * pObj, int ObjId, int n ){ return n ? Gia_ObjFaninLit1(pObj, ObjId) : Gia_ObjFaninLit0(pObj, ObjId);}
|
||||
static inline int Gia_ObjFaninLit0p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Abc_Var2Lit( Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) ); }
|
||||
static inline int Gia_ObjFaninLit1p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Abc_Var2Lit( Gia_ObjFaninId1p(p, pObj), Gia_ObjFaninC1(pObj) ); }
|
||||
static inline int Gia_ObjFaninLit2p( Gia_Man_t * p, Gia_Obj_t * pObj) { return (p->pMuxes && p->pMuxes[Gia_ObjId(p, pObj)]) ? p->pMuxes[Gia_ObjId(p, pObj)] : -1; }
|
||||
static inline int Gia_ObjFaninLitp( Gia_Man_t * p, Gia_Obj_t * pObj, int n ){ return n ? Gia_ObjFaninLit1p(p, pObj) : Gia_ObjFaninLit0p(p, pObj);}
|
||||
static inline void Gia_ObjFlipFaninC0( Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); pObj->fCompl0 ^= 1; }
|
||||
static inline int Gia_ObjFaninNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsMux(p, pObj) ) return 3; if ( Gia_ObjIsAnd(pObj) ) return 2; if ( Gia_ObjIsCo(pObj) ) return 1; return 0; }
|
||||
static inline int Gia_ObjWhatFanin( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) { if ( Gia_ObjFanin0(pObj) == pFanin ) return 0; if ( Gia_ObjFanin1(pObj) == pFanin ) return 1; if ( Gia_ObjFanin2(p, pObj) == pFanin ) return 2; assert(0); return -1; }
|
||||
|
|
@ -1101,10 +1126,12 @@ static inline Gia_Obj_t * Gia_ObjFanout( Gia_Man_t * p, Gia_Obj_t * pObj, int i
|
|||
static inline void Gia_ObjSetFanout( Gia_Man_t * p, Gia_Obj_t * pObj, int i, Gia_Obj_t * pFan ) { Vec_IntWriteEntry( p->vFanout, Gia_ObjFoffset(p, pObj) + i, Gia_ObjId(p, pFan) ); }
|
||||
static inline void Gia_ObjSetFanoutInt( Gia_Man_t * p, Gia_Obj_t * pObj, int i, int x ) { Vec_IntWriteEntry( p->vFanout, Gia_ObjFoffset(p, pObj) + i, x ); }
|
||||
|
||||
#define Gia_ObjForEachFanoutStatic( p, pObj, pFanout, i ) \
|
||||
for ( i = 0; (i < Gia_ObjFanoutNum(p, pObj)) && (((pFanout) = Gia_ObjFanout(p, pObj, i)), 1); i++ )
|
||||
#define Gia_ObjForEachFanoutStaticId( p, Id, FanId, i ) \
|
||||
for ( i = 0; (i < Gia_ObjFanoutNumId(p, Id)) && (((FanId) = Gia_ObjFanoutId(p, Id, i)), 1); i++ )
|
||||
#define Gia_ObjForEachFanoutStatic( p, pObj, pFanout, i ) \
|
||||
for ( i = 0; (i < Gia_ObjFanoutNum(p, pObj)) && (((pFanout) = Gia_ObjFanout(p, pObj, i)), 1); i++ )
|
||||
#define Gia_ObjForEachFanoutStaticId( p, Id, FanId, i ) \
|
||||
for ( i = 0; (i < Gia_ObjFanoutNumId(p, Id)) && ((FanId = Gia_ObjFanoutId(p, Id, i)), 1); i++ )
|
||||
#define Gia_ObjForEachFanoutStaticIndex( p, Id, FanId, i, Index ) \
|
||||
for ( i = 0; (i < Gia_ObjFanoutNumId(p, Id)) && (Index = Vec_IntEntry(p->vFanout, Id)+i) && ((FanId = Vec_IntEntry(p->vFanout, Index)), 1); i++ )
|
||||
|
||||
static inline int Gia_ManHasMapping( Gia_Man_t * p ) { return p->vMapping != NULL; }
|
||||
static inline int Gia_ObjIsLut( Gia_Man_t * p, int Id ) { return Vec_IntEntry(p->vMapping, Id) != 0; }
|
||||
|
|
@ -1137,6 +1164,8 @@ static inline int Gia_ObjCellId( Gia_Man_t * p, int iLit ) { re
|
|||
for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsLut(p, i) ) {} else
|
||||
#define Gia_LutForEachFanin( p, i, iFan, k ) \
|
||||
for ( k = 0; k < Gia_ObjLutSize(p,i) && ((iFan = Gia_ObjLutFanins(p,i)[k]),1); k++ )
|
||||
#define Gia_LutForEachFaninIndex( p, i, iFan, k, Index ) \
|
||||
for ( k = 0; k < Gia_ObjLutSize(p,i) && (Index = Vec_IntEntry(p->vMapping, i)+1+k) && ((iFan = Vec_IntEntry(p->vMapping, Index)),1); k++ )
|
||||
#define Gia_LutForEachFaninObj( p, i, pFanin, k ) \
|
||||
for ( k = 0; k < Gia_ObjLutSize(p,i) && ((pFanin = Gia_ManObj(p, Gia_ObjLutFanins(p,i)[k])),1); k++ )
|
||||
|
||||
|
|
@ -1230,7 +1259,18 @@ static inline int Gia_ObjCellId( Gia_Man_t * p, int iLit ) { re
|
|||
for ( i = 0; (i < Gia_ManRegNum(p)) && ((pObj) = Gia_ManCo(p, Gia_ManPoNum(p)+i)); i++ )
|
||||
#define Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) \
|
||||
for ( i = 0; (i < Gia_ManRegNum(p)) && ((pObjRi) = Gia_ManCo(p, Gia_ManPoNum(p)+i)) && ((pObjRo) = Gia_ManCi(p, Gia_ManPiNum(p)+i)); i++ )
|
||||
|
||||
#define Gia_ManForEachRoToRiVec( vRoIds, p, pObj, i ) \
|
||||
for ( i = 0; (i < Vec_IntSize(vRoIds)) && ((pObj) = Gia_ObjRoToRi(p, Gia_ManObj(p, Vec_IntEntry(vRoIds, i)))); i++ )
|
||||
|
||||
#define Gia_ManForEachObjWithBoxes( p, pObj, i ) \
|
||||
for ( i = p->iFirstAndObj; (i < p->iFirstPoObj) && ((pObj) = Gia_ManObj(p, i)); i++ )
|
||||
#define Gia_ManForEachObjReverseWithBoxes( p, pObj, i ) \
|
||||
for ( i = p->iFirstPoObj - 1; (i >= p->iFirstAndObj) && ((pObj) = Gia_ManObj(p, i)); i-- )
|
||||
#define Gia_ManForEachCiIdWithBoxes( p, Id, i ) \
|
||||
for ( i = 0; (i < p->iFirstNonPiId) && ((Id) = Gia_ObjId(p, Gia_ManCi(p, i))); i++ )
|
||||
#define Gia_ManForEachCoWithBoxes( p, pObj, i ) \
|
||||
for ( i = p->iFirstPoId; (i < Vec_IntSize(p->vCos)) && ((pObj) = Gia_ManCo(p, i)); i++ )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1240,6 +1280,7 @@ extern int Gia_FileSize( char * pFileName );
|
|||
extern Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSimple, int fSkipStrash, int fCheck );
|
||||
extern Gia_Man_t * Gia_AigerRead( char * pFileName, int fGiaSimple, int fSkipStrash, int fCheck );
|
||||
extern void Gia_AigerWrite( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine );
|
||||
extern void Gia_AigerWriteS( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine, int fSkipComment );
|
||||
extern void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits );
|
||||
extern Vec_Str_t * Gia_AigerWriteIntoMemoryStr( Gia_Man_t * p );
|
||||
extern Vec_Str_t * Gia_AigerWriteIntoMemoryStrPart( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, int nRegs );
|
||||
|
|
@ -1271,10 +1312,14 @@ extern void Cbs_ManStop( Cbs_Man_t * p );
|
|||
extern int Cbs_ManSolve( Cbs_Man_t * p, Gia_Obj_t * pObj );
|
||||
extern int Cbs_ManSolve2( Cbs_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
|
||||
extern Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose );
|
||||
extern Vec_Int_t * Cbs_ManSolveMiterNcOutVals( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose, Vec_Int_t * vOutLits, Vec_Int_t ** pvOutVals );
|
||||
extern void Cbs_ManSyncCore( Cbs_Man_t * p );
|
||||
extern Vec_Int_t * Cbs_ManSolveRoots( Cbs_Man_t * p, Vec_Int_t * vRootLits, Vec_Str_t ** pvStatus, int fVerbose );
|
||||
extern void Cbs_ManSetConflictNum( Cbs_Man_t * p, int Num );
|
||||
extern Vec_Int_t * Cbs_ReadModel( Cbs_Man_t * p );
|
||||
/*=== giaCTas.c ============================================================*/
|
||||
extern Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose );
|
||||
extern Vec_Int_t * Tas_ManSolveMiterNcOutVals( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose, Vec_Int_t * vOutLits, Vec_Int_t ** pvOutVals );
|
||||
/*=== giaCof.c =============================================================*/
|
||||
extern void Gia_ManPrintFanio( Gia_Man_t * pGia, int nNodes );
|
||||
extern Gia_Man_t * Gia_ManDupCof( Gia_Man_t * p, int iVar );
|
||||
|
|
@ -1312,6 +1357,8 @@ extern Gia_Man_t * Gia_ManDupLastPis( Gia_Man_t * p, int nLastPis );
|
|||
extern Gia_Man_t * Gia_ManDupFlip( Gia_Man_t * p, int * pInitState );
|
||||
extern Gia_Man_t * Gia_ManDupCycled( Gia_Man_t * pAig, Abc_Cex_t * pCex, int nFrames );
|
||||
extern Gia_Man_t * Gia_ManDup( Gia_Man_t * p );
|
||||
extern Gia_Man_t * Gia_ManDupNoBuf( Gia_Man_t * p );
|
||||
extern Gia_Man_t * Gia_ManDupMap( Gia_Man_t * p, Vec_Int_t * vMap );
|
||||
extern Gia_Man_t * Gia_ManDup2( Gia_Man_t * p1, Gia_Man_t * p2 );
|
||||
extern Gia_Man_t * Gia_ManDupWithAttributes( Gia_Man_t * p );
|
||||
extern Gia_Man_t * Gia_ManDupRemovePis( Gia_Man_t * p, int nRemPis );
|
||||
|
|
@ -1319,7 +1366,7 @@ extern Gia_Man_t * Gia_ManDupZero( Gia_Man_t * p );
|
|||
extern Gia_Man_t * Gia_ManDupPerm( Gia_Man_t * p, Vec_Int_t * vPiPerm );
|
||||
extern Gia_Man_t * Gia_ManDupPermFlop( Gia_Man_t * p, Vec_Int_t * vFfPerm );
|
||||
extern Gia_Man_t * Gia_ManDupPermFlopGap( Gia_Man_t * p, Vec_Int_t * vFfPerm );
|
||||
extern void Gia_ManDupAppend( Gia_Man_t * p, Gia_Man_t * pTwo );
|
||||
extern void Gia_ManDupAppend( Gia_Man_t * p, Gia_Man_t * pTwo, int fShareCis );
|
||||
extern void Gia_ManDupAppendShare( Gia_Man_t * p, Gia_Man_t * pTwo );
|
||||
extern Gia_Man_t * Gia_ManDupAppendNew( Gia_Man_t * pOne, Gia_Man_t * pTwo );
|
||||
extern Gia_Man_t * Gia_ManDupAppendCones( Gia_Man_t * p, Gia_Man_t ** ppCones, int nCones, int fOnlyRegs );
|
||||
|
|
@ -1351,6 +1398,7 @@ extern Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int n
|
|||
extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p );
|
||||
extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose );
|
||||
extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int nInsDup, int fDualOut, int fSeq, int fImplic, int fVerbose );
|
||||
extern Gia_Man_t * Gia_ManMiterInverse( Gia_Man_t * pBot, Gia_Man_t * pTop, int fDualOut, int fVerbose );
|
||||
extern Gia_Man_t * Gia_ManDupAndOr( Gia_Man_t * p, int nOuts, int fUseOr, int fCompl );
|
||||
extern Gia_Man_t * Gia_ManDupZeroUndc( Gia_Man_t * p, char * pInit, int nNewPis, int fGiaSimple, int fVerbose );
|
||||
extern Gia_Man_t * Gia_ManMiter2( Gia_Man_t * p, char * pInit, int fVerbose );
|
||||
|
|
@ -1372,6 +1420,13 @@ extern Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose );
|
|||
extern Gia_Man_t * Gia_ManDemiterToDual( Gia_Man_t * p );
|
||||
extern int Gia_ManDemiterDual( Gia_Man_t * p, Gia_Man_t ** pp0, Gia_Man_t ** pp1 );
|
||||
extern int Gia_ManDemiterTwoWords( Gia_Man_t * p, Gia_Man_t ** pp0, Gia_Man_t ** pp1 );
|
||||
extern void Gia_ManProdAdderGen( int nArgA, int nArgB, int Seed, int fSigned, int fCla );
|
||||
typedef struct Gia_ChMan_t_ Gia_ChMan_t;
|
||||
extern Gia_ChMan_t * Gia_ManDupChoicesStart( Gia_Man_t * pGia );
|
||||
extern void Gia_ManDupChoicesAdd( Gia_ChMan_t * pMan, Gia_Man_t * pGia );
|
||||
extern Gia_Man_t * Gia_ManDupChoicesFinish( Gia_ChMan_t * pMan );
|
||||
extern Vec_Int_t * Gia_ManComputeMffc( Gia_Man_t * p, Vec_Int_t * vLits, Vec_Int_t * vOuts );
|
||||
extern Gia_Man_t * Gia_ManDupExtractMffc( Gia_Man_t * p, Vec_Int_t * vLits, Vec_Int_t * vAnds, Vec_Int_t * vCos );
|
||||
/*=== giaEdge.c ==========================================================*/
|
||||
extern void Gia_ManEdgeFromArray( Gia_Man_t * p, Vec_Int_t * vArray );
|
||||
extern Vec_Int_t * Gia_ManEdgeToArray( Gia_Man_t * p );
|
||||
|
|
@ -1397,6 +1452,7 @@ extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p );
|
|||
extern int Gia_ManCheckTopoOrder( Gia_Man_t * p );
|
||||
extern int * Gia_ManDeriveNexts( Gia_Man_t * p );
|
||||
extern void Gia_ManDeriveReprs( Gia_Man_t * p );
|
||||
extern void Gia_ManDeriveReprsFromSibls( Gia_Man_t *p );
|
||||
extern int Gia_ManEquivCountLits( Gia_Man_t * p );
|
||||
extern int Gia_ManEquivCountLitsAll( Gia_Man_t * p );
|
||||
extern int Gia_ManEquivCountClasses( Gia_Man_t * p );
|
||||
|
|
@ -1429,7 +1485,7 @@ extern void Gia_ManFanoutStart( Gia_Man_t * p );
|
|||
extern void Gia_ManFanoutStop( Gia_Man_t * p );
|
||||
extern void Gia_ManStaticFanoutStart( Gia_Man_t * p );
|
||||
extern void Gia_ManStaticFanoutStop( Gia_Man_t * p );
|
||||
extern void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p );
|
||||
extern void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p, Vec_Int_t ** pvIndex );
|
||||
/*=== giaForce.c =========================================================*/
|
||||
extern void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose );
|
||||
/*=== giaFrames.c =========================================================*/
|
||||
|
|
@ -1467,6 +1523,7 @@ extern int Gia_ManHashAndMulti( Gia_Man_t * p, Vec_Int_t * vLits
|
|||
extern int Gia_ManHashAndMulti2( Gia_Man_t * p, Vec_Int_t * vLits );
|
||||
extern int Gia_ManHashDualMiter( Gia_Man_t * p, Vec_Int_t * vOuts );
|
||||
/*=== giaIf.c ===========================================================*/
|
||||
extern void Gia_ManPrintOutputLutStats( Gia_Man_t * p );
|
||||
extern void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile );
|
||||
extern void Gia_ManPrintPackingStats( Gia_Man_t * p );
|
||||
extern void Gia_ManPrintLutStats( Gia_Man_t * p );
|
||||
|
|
@ -1513,7 +1570,8 @@ extern void Gia_ManPrintStatsMiter( Gia_Man_t * p, int fVerbose )
|
|||
extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs );
|
||||
extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew );
|
||||
extern void Gia_ManPrintNpnClasses( Gia_Man_t * p );
|
||||
extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs );
|
||||
extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter, int fInterComb, int fAssign, int fReverse );
|
||||
extern void Gia_ManDumpVerilogNand( Gia_Man_t * p, char * pFileName );
|
||||
/*=== giaMem.c ===========================================================*/
|
||||
extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax );
|
||||
extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose );
|
||||
|
|
@ -1541,6 +1599,9 @@ extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName, int fGiaSimple
|
|||
extern void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName );
|
||||
extern Gia_Man_t * Gia_ManReadMiniLut( char * pFileName );
|
||||
extern void Gia_ManWriteMiniLut( Gia_Man_t * pGia, char * pFileName );
|
||||
/*=== giaMinLut.c ===========================================================*/
|
||||
extern word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh, int fVerbose, int * pCare );
|
||||
extern Vec_Int_t * Gia_ManCollectSuppNew( Gia_Man_t * p, int iOut, int nOuts );
|
||||
/*=== giaMuxes.c ===========================================================*/
|
||||
extern void Gia_ManCountMuxXor( Gia_Man_t * p, int * pnMuxes, int * pnXors );
|
||||
extern void Gia_ManPrintMuxStats( Gia_Man_t * p );
|
||||
|
|
@ -1599,6 +1660,7 @@ extern Vec_Wrd_t * Gia_ManArray2SimOne( Vec_Int_t * vRes );
|
|||
extern Vec_Ptr_t * Gia_ManArray2Sim( Vec_Wec_t * vRes );
|
||||
extern void Gia_ManPtrWrdDumpBin( char * pFileName, Vec_Ptr_t * p, int fVerbose );
|
||||
extern Vec_Ptr_t * Gia_ManPtrWrdReadBin( char * pFileName, int fVerbose );
|
||||
extern Vec_Str_t * Gia_ManComputeRange( Gia_Man_t * p );
|
||||
/*=== giaSpeedup.c ============================================================*/
|
||||
extern float Gia_ManDelayTraceLut( Gia_Man_t * p );
|
||||
extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose );
|
||||
|
|
@ -1650,6 +1712,7 @@ extern int Gia_SweeperRun( Gia_Man_t * p, Vec_Int_t * vProbeIds,
|
|||
extern float Gia_ManEvaluateSwitching( Gia_Man_t * p );
|
||||
extern float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbOne );
|
||||
extern Vec_Int_t * Gia_ManComputeSwitchProbs( Gia_Man_t * pGia, int nFrames, int nPref, int fProbOne );
|
||||
extern Vec_Int_t * Gia_ManComputeSwitchProbs2( Gia_Man_t * pGia, int nFrames, int nPref, int fProbOne, int nRandPiFactor );
|
||||
extern Vec_Flt_t * Gia_ManPrintOutputProb( Gia_Man_t * p );
|
||||
/*=== giaTim.c ===========================================================*/
|
||||
extern int Gia_ManBoxNum( Gia_Man_t * p );
|
||||
|
|
@ -1672,7 +1735,8 @@ extern void * Gia_ManUpdateTimMan2( Gia_Man_t * p, Vec_Int_t * vBox
|
|||
extern Gia_Man_t * Gia_ManUpdateExtraAig( void * pTime, Gia_Man_t * pAig, Vec_Int_t * vBoxPres );
|
||||
extern Gia_Man_t * Gia_ManUpdateExtraAig2( void * pTime, Gia_Man_t * pAig, Vec_Int_t * vBoxesLeft );
|
||||
extern Gia_Man_t * Gia_ManDupCollapse( Gia_Man_t * p, Gia_Man_t * pBoxes, Vec_Int_t * vBoxPres, int fSeq );
|
||||
extern int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fSeq, int fDumpFiles, int fVerbose, char * pFileSpec );
|
||||
extern int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fSeq, int fNameMap, int fDumpFiles, int fVerbose, char * pFileSpec );
|
||||
extern Vec_Int_t * Gia_ManDeriveBoxMapping( Gia_Man_t * pGia );
|
||||
/*=== giaTruth.c ===========================================================*/
|
||||
extern word Gia_LutComputeTruth6( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTruths );
|
||||
extern word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp );
|
||||
|
|
@ -1691,6 +1755,7 @@ extern word Gia_ManRandomW( int fReset );
|
|||
extern void Gia_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int iWordStop );
|
||||
extern char * Gia_TimeStamp();
|
||||
extern char * Gia_FileNameGenericAppend( char * pBase, char * pSuffix );
|
||||
extern Vec_Ptr_t * Gia_GetFakeNames( int nNames, int fCaps );
|
||||
extern void Gia_ManIncrementTravId( Gia_Man_t * p );
|
||||
extern void Gia_ManCleanMark01( Gia_Man_t * p );
|
||||
extern void Gia_ManSetMark0( Gia_Man_t * p );
|
||||
|
|
@ -1717,6 +1782,7 @@ extern Vec_Int_t * Gia_ManReverseLevel( Gia_Man_t * p );
|
|||
extern Vec_Int_t * Gia_ManRequiredLevel( Gia_Man_t * p );
|
||||
extern void Gia_ManCreateValueRefs( Gia_Man_t * p );
|
||||
extern void Gia_ManCreateRefs( Gia_Man_t * p );
|
||||
extern void Gia_ManCreateLitRefs( Gia_Man_t * p );
|
||||
extern int * Gia_ManCreateMuxRefs( Gia_Man_t * p );
|
||||
extern int Gia_ManCrossCut( Gia_Man_t * p, int fReverse );
|
||||
extern Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p );
|
||||
|
|
@ -1751,6 +1817,17 @@ extern int Gia_ManCountPosWithNonZeroDrivers( Gia_Man_t * p );
|
|||
extern void Gia_ManUpdateCopy( Vec_Int_t * vCopy, Gia_Man_t * p );
|
||||
extern Vec_Int_t * Gia_ManComputeDistance( Gia_Man_t * p, int iObj, Vec_Int_t * vObjs, int fVerbose );
|
||||
|
||||
/*=== giaTtopt.cpp ===========================================================*/
|
||||
extern Gia_Man_t * Gia_ManTtopt( Gia_Man_t * p, int nIns, int nOuts, int nRounds );
|
||||
extern Gia_Man_t * Gia_ManTtoptCare( Gia_Man_t * p, int nIns, int nOuts, int nRounds, char * pFileName, int nRarity );
|
||||
|
||||
/*=== giaTransduction.cpp ===========================================================*/
|
||||
extern Gia_Man_t * Gia_ManTransductionBdd( Gia_Man_t * pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t * pExdc, int fNewLine, int nVerbose );
|
||||
extern Gia_Man_t * Gia_ManTransductionTt( Gia_Man_t * pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t * pExdc, int fNewLine, int nVerbose );
|
||||
|
||||
/*=== giaRrr.cpp ===========================================================*/
|
||||
extern Gia_Man_t * Gia_ManRrr( Gia_Man_t *pGia, int iSeed, int nWords, int nTimeout, int nSchedulerVerbose, int nPartitionerVerbose, int nOptimizerVerbose, int nAnalyzerVerbose, int nSimulatorVerbose, int nSatSolverVerbose, int fUseBddCspf, int fUseBddMspf, int nConflictLimit, int nSortType, int nOptimizerFlow, int nSchedulerFlow, int nPartitionType, int nDistance, int nJobs, int nThreads, int nPartitionSize, int nPartitionSizeMin, int fDeterministic, int nParallelPartitions, int fOptOnInsert, int fGreedy );
|
||||
|
||||
/*=== giaCTas.c ===========================================================*/
|
||||
typedef struct Tas_Man_t_ Tas_Man_t;
|
||||
extern Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit );
|
||||
|
|
@ -1759,7 +1836,48 @@ extern Vec_Int_t * Tas_ReadModel( Tas_Man_t * p );
|
|||
extern void Tas_ManSatPrintStats( Tas_Man_t * p );
|
||||
extern int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
|
||||
extern int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs );
|
||||
extern void Tas_ManSetConflictNum( Tas_Man_t * p, int Num );
|
||||
extern void Tas_ManSyncCore( Tas_Man_t * p );
|
||||
extern Vec_Int_t * Tas_ManSolveRoots( Tas_Man_t * p, Vec_Int_t * vRootLits, Vec_Str_t ** pvStatus, int fVerbose );
|
||||
|
||||
/*=== giaDecGraph.c ===========================================================*/
|
||||
extern Gia_Man_t* Gia_ManDecGraph( Gia_Man_t* p );
|
||||
extern Gia_Man_t* Gia_ManDecGraphFromFile( char* pFileName );
|
||||
|
||||
/*=== giaBound.c ===========================================================*/
|
||||
typedef struct Bnd_Man_t_ Bnd_Man_t;
|
||||
|
||||
extern Bnd_Man_t* Bnd_ManStart( Gia_Man_t *pSpec, Gia_Man_t *pImpl, int fVerbose );
|
||||
extern void Bnd_ManStop();
|
||||
|
||||
// getter
|
||||
extern int Bnd_ManGetNInternal();
|
||||
extern int Bnd_ManGetNExtra();
|
||||
|
||||
//for fraig
|
||||
extern void Bnd_ManMap( int iLit, int id, int spec );
|
||||
extern void Bnd_ManMerge( int id1, int id2, int phaseDiff );
|
||||
extern void Bnd_ManFinalizeMappings();
|
||||
extern void Bnd_ManPrintMappings();
|
||||
extern Gia_Man_t* Bnd_ManStackGias( Gia_Man_t *pSpec, Gia_Man_t *pImpl );
|
||||
extern int Bnd_ManCheckCoMerged( Gia_Man_t *p );
|
||||
|
||||
// for eco
|
||||
extern int Bnd_ManCheckBound( Gia_Man_t *p, int fVerbose );
|
||||
extern void Bnd_ManFindBound( Gia_Man_t *p, Gia_Man_t *pImpl );
|
||||
extern Gia_Man_t* Bnd_ManGenSpecOut( Gia_Man_t *p );
|
||||
extern Gia_Man_t* Bnd_ManGenImplOut( Gia_Man_t *p );
|
||||
extern Gia_Man_t* Bnd_ManGenPatched( Gia_Man_t *pOut, Gia_Man_t *pSpec, Gia_Man_t *pPatch );
|
||||
extern Gia_Man_t* Bnd_ManGenPatched1( Gia_Man_t *pOut, Gia_Man_t *pSpec );
|
||||
extern Gia_Man_t* Bnd_ManGenPatched2( Gia_Man_t *pImpl, Gia_Man_t *pPatch, int fSkiptStrash, int fVerbose );
|
||||
extern void Bnd_ManSetEqOut( int eq );
|
||||
extern void Bnd_ManSetEqRes( int eq );
|
||||
extern void Bnd_ManPrintStats();
|
||||
|
||||
// util
|
||||
extern Gia_Man_t* Bnd_ManCutBoundary( Gia_Man_t *p, Vec_Int_t* vEI, Vec_Int_t* vEO, Vec_Bit_t* vEI_phase, Vec_Bit_t* vEO_phase );
|
||||
|
||||
extern int Gia_ObjCheckMffc( Gia_Man_t * p, Gia_Obj_t * pRoot, int Limit, Vec_Int_t * vNodes, Vec_Int_t * vLeaves, Vec_Int_t * vInners );
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
|
@ -1769,4 +1887,3 @@ ABC_NAMESPACE_HEADER_END
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "giaAig.h"
|
||||
#include "aig/gia/gia.h"
|
||||
#include "proof/fra/fra.h"
|
||||
#include "proof/dch/dch.h"
|
||||
#include "opt/dar/dar.h"
|
||||
#include "opt/dau/dau.h"
|
||||
#include <assert.h>
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -191,6 +193,8 @@ Gia_Man_t * Gia_ManFromAigChoices( Aig_Man_t * p )
|
|||
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
|
||||
//assert( Gia_ManObjNum(pNew) == Aig_ManObjNum(p) );
|
||||
//Gia_ManCheckChoices( pNew );
|
||||
if ( pNew->pSibls )
|
||||
Gia_ManDeriveReprsFromSibls( pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
@ -611,6 +615,27 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManTestChoices( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Vec_Int_t * vPointed = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( Gia_ObjSibl(p, i) )
|
||||
Vec_IntWriteEntry( vPointed, Gia_ObjSibl(p, i), 1 );
|
||||
Gia_ManCreateRefs( p );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( Vec_IntEntry(vPointed, i) && Gia_ObjRefNumId(p, i) > 0 )
|
||||
{
|
||||
printf( "Gia_ManCheckChoices: Member %d", i );
|
||||
printf( " of a choice node has %d fanouts.\n", Gia_ObjRefNumId(p, i) );
|
||||
ABC_FREE( p->pRefs );
|
||||
Vec_IntFree( vPointed );
|
||||
return 0;
|
||||
}
|
||||
ABC_FREE( p->pRefs );
|
||||
Vec_IntFree( vPointed );
|
||||
return 1;
|
||||
}
|
||||
Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars )
|
||||
{
|
||||
int fUseMapping = 0;
|
||||
|
|
@ -628,6 +653,11 @@ Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars )
|
|||
// pGia = Gia_ManFromAig( pNew );
|
||||
pGia = Gia_ManFromAigChoices( pNew );
|
||||
Aig_ManStop( pNew );
|
||||
if ( !p->pManTime && !Gia_ManTestChoices(pGia) )
|
||||
{
|
||||
Gia_ManStop( pGia );
|
||||
pGia = Gia_ManDup( p );
|
||||
}
|
||||
Gia_ManTransferTiming( pGia, p );
|
||||
return pGia;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "gia.h"
|
||||
#include "misc/tim/tim.h"
|
||||
#include "base/main/main.h"
|
||||
#include "map/if/if.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -406,41 +407,38 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
if ( *pType == 'i' )
|
||||
{
|
||||
if ( vNamesIn == NULL )
|
||||
vNamesIn = Vec_PtrAlloc( nInputs + nLatches );
|
||||
if ( Vec_PtrSize(vNamesIn) != iTerm )
|
||||
vNamesIn = Vec_PtrStart( nInputs );
|
||||
if ( Vec_PtrSize(vNamesIn) <= iTerm )
|
||||
{
|
||||
fError = 1;
|
||||
break;
|
||||
}
|
||||
Vec_PtrPush( vNamesIn, Abc_UtilStrsav(pName) );
|
||||
Vec_PtrWriteEntry( vNamesIn, iTerm, Abc_UtilStrsav(pName) );
|
||||
}
|
||||
else if ( *pType == 'o' )
|
||||
{
|
||||
if ( vNamesOut == NULL )
|
||||
vNamesOut = Vec_PtrAlloc( nOutputs + nLatches );
|
||||
if ( Vec_PtrSize(vNamesOut) != iTerm )
|
||||
vNamesOut = Vec_PtrStart( nOutputs );
|
||||
if ( Vec_PtrSize(vNamesOut) <= iTerm )
|
||||
{
|
||||
fError = 1;
|
||||
break;
|
||||
}
|
||||
Vec_PtrPush( vNamesOut, Abc_UtilStrsav(pName) );
|
||||
Vec_PtrWriteEntry( vNamesOut, iTerm, Abc_UtilStrsav(pName) );
|
||||
}
|
||||
else if ( *pType == 'l' )
|
||||
{
|
||||
char Buffer[1000];
|
||||
assert( strlen(pName) < 995 );
|
||||
sprintf( Buffer, "%s_in", pName );
|
||||
if ( vNamesRegIn == NULL )
|
||||
vNamesRegIn = Vec_PtrAlloc( nLatches );
|
||||
vNamesRegIn = Vec_PtrStart( nLatches );
|
||||
if ( vNamesRegOut == NULL )
|
||||
vNamesRegOut = Vec_PtrAlloc( nLatches );
|
||||
if ( Vec_PtrSize(vNamesRegIn) != iTerm )
|
||||
vNamesRegOut = Vec_PtrStart( nLatches );
|
||||
if ( Vec_PtrSize(vNamesRegIn) <= iTerm )
|
||||
{
|
||||
fError = 1;
|
||||
break;
|
||||
}
|
||||
Vec_PtrPush( vNamesRegIn, Abc_UtilStrsav(Buffer) );
|
||||
Vec_PtrPush( vNamesRegOut, Abc_UtilStrsav(pName) );
|
||||
Vec_PtrWriteEntry( vNamesRegIn, iTerm, Abc_UtilStrsavTwo(pName, (char *)"_in") );
|
||||
Vec_PtrWriteEntry( vNamesRegOut, iTerm, Abc_UtilStrsav(pName) );
|
||||
}
|
||||
else if ( *pType == 'n' )
|
||||
{
|
||||
|
|
@ -648,6 +646,15 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
{
|
||||
pCur++;
|
||||
nInputs = Gia_AigerReadInt(pCur)/4; pCur += 4;
|
||||
int nPiFf = Gia_ManPiNum(pNew) + Gia_ManRegNum(pNew);
|
||||
if ( nInputs > nPiFf ) {
|
||||
printf( "Warning: Timing info size (%d) exceeds PIs+FFs (%d). Using first %d values.\n", nInputs, nPiFf, nPiFf );
|
||||
nInputs = nPiFf;
|
||||
}
|
||||
else if ( nInputs > Gia_ManPiNum(pNew) && nInputs < nPiFf ) {
|
||||
printf( "Warning: Timing info size (%d) is between PIs (%d) and PIs+FFs (%d). Using first %d values.\n", nInputs, Gia_ManPiNum(pNew), nPiFf, Gia_ManPiNum(pNew) );
|
||||
nInputs = Gia_ManPiNum(pNew);
|
||||
}
|
||||
pNew->vInArrs = Vec_FltStart( nInputs );
|
||||
memcpy( Vec_FltArray(pNew->vInArrs), pCur, (size_t)4*nInputs ); pCur += 4*nInputs;
|
||||
if ( fVerbose ) printf( "Finished reading extension \"i\".\n" );
|
||||
|
|
@ -656,28 +663,50 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
{
|
||||
pCur++;
|
||||
nOutputs = Gia_AigerReadInt(pCur)/4; pCur += 4;
|
||||
int nPoFf = Gia_ManPoNum(pNew) + Gia_ManRegNum(pNew);
|
||||
if ( nOutputs > nPoFf ) {
|
||||
printf( "Warning: Required time size (%d) exceeds POs+FFs (%d). Using first %d values.\n", nOutputs, nPoFf, nPoFf );
|
||||
nOutputs = nPoFf;
|
||||
}
|
||||
else if ( nOutputs > Gia_ManPoNum(pNew) && nOutputs < nPoFf ) {
|
||||
printf( "Warning: Required time size (%d) is between POs (%d) and POs+FFs (%d). Using first %d values.\n", nOutputs, Gia_ManPoNum(pNew), nPoFf, Gia_ManPoNum(pNew) );
|
||||
nOutputs = Gia_ManPoNum(pNew);
|
||||
}
|
||||
pNew->vOutReqs = Vec_FltStart( nOutputs );
|
||||
memcpy( Vec_FltArray(pNew->vOutReqs), pCur, (size_t)4*nOutputs ); pCur += 4*nOutputs;
|
||||
// Convert -1.0 back to TIM_ETERNITY for internal use
|
||||
{
|
||||
float * pArr = Vec_FltArray(pNew->vOutReqs);
|
||||
int i;
|
||||
for ( i = 0; i < nOutputs; i++ )
|
||||
if ( pArr[i] < 0 )
|
||||
pArr[i] = TIM_ETERNITY;
|
||||
}
|
||||
if ( fVerbose ) printf( "Finished reading extension \"o\".\n" );
|
||||
}
|
||||
// read equivalence classes
|
||||
else if ( *pCur == 'e' )
|
||||
{
|
||||
extern Gia_Rpr_t * Gia_AigerReadEquivClasses( unsigned char ** ppPos, int nSize );
|
||||
pCur++;
|
||||
pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
|
||||
pNew->pReprs = Gia_AigerReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );
|
||||
pNew->pNexts = Gia_ManDeriveNexts( pNew );
|
||||
assert( pCur == pCurTemp );
|
||||
if ( fVerbose ) printf( "Finished reading extension \"e\".\n" );
|
||||
}
|
||||
//else if ( *pCur == 'e' )
|
||||
//{
|
||||
// extern Gia_Rpr_t * Gia_AigerReadEquivClasses( unsigned char ** ppPos, int nSize );
|
||||
// pCur++;
|
||||
// pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
|
||||
// pNew->pReprs = Gia_AigerReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );
|
||||
// pNew->pNexts = Gia_ManDeriveNexts( pNew );
|
||||
// assert( pCur == pCurTemp );
|
||||
// if ( fVerbose ) printf( "Finished reading extension \"e\".\n" );
|
||||
//}
|
||||
// read flop classes
|
||||
else if ( *pCur == 'f' )
|
||||
{
|
||||
int i, nRegs;
|
||||
pCur++;
|
||||
assert( Gia_AigerReadInt(pCur) == 4*Gia_ManRegNum(pNew) ); pCur += 4;
|
||||
pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) );
|
||||
memcpy( Vec_IntArray(pNew->vFlopClasses), pCur, (size_t)4*Gia_ManRegNum(pNew) ); pCur += 4*Gia_ManRegNum(pNew);
|
||||
pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
|
||||
nRegs = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
//nRegs = (pCurTemp - pCur)/4;
|
||||
pNew->vFlopClasses = Vec_IntAlloc( nRegs );
|
||||
for ( i = 0; i < nRegs; i++ )
|
||||
Vec_IntPush( pNew->vFlopClasses, Gia_AigerReadInt(pCur) ), pCur += 4;
|
||||
assert( pCur == pCurTemp );
|
||||
if ( fVerbose ) printf( "Finished reading extension \"f\".\n" );
|
||||
}
|
||||
// read gate classes
|
||||
|
|
@ -800,6 +829,36 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
assert( pCur == pCurTemp );
|
||||
if ( fVerbose ) printf( "Finished reading extension \"b\".\n" );
|
||||
}
|
||||
// read configuration data for extension "j"
|
||||
else if ( *pCur == 'j' )
|
||||
{
|
||||
int nSize, Reserved, NumCellTypes, CellId, BytesPerInstance, TotalInstances;
|
||||
pCur++;
|
||||
nSize = Gia_AigerReadInt(pCur);
|
||||
pCurTemp = pCur + nSize + 4; pCur += 4;
|
||||
// Read reserved value (should be 0)
|
||||
Reserved = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
assert( Reserved == 0 );
|
||||
// Read number of cell types
|
||||
NumCellTypes = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
// Skip cell type definitions (we know them already)
|
||||
for ( i = 0; i < NumCellTypes; i++ )
|
||||
{
|
||||
CellId = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
// Skip function description string (null-terminated)
|
||||
while ( *pCur++ != '\0' );
|
||||
BytesPerInstance = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
}
|
||||
// Read total number of instances
|
||||
TotalInstances = Gia_AigerReadInt(pCur); pCur += 4;
|
||||
// Create byte vector for instance data
|
||||
pNew->vConfigs2 = Vec_StrAlloc( (int)(pCurTemp - pCur) );
|
||||
// Read instance data as bytes
|
||||
while ( pCur < pCurTemp )
|
||||
Vec_StrPush( pNew->vConfigs2, *pCur++ );
|
||||
assert( pCur == pCurTemp );
|
||||
if ( fVerbose ) printf( "Finished reading extension \"j\".\n" );
|
||||
}
|
||||
// read choices
|
||||
else if ( *pCur == 'q' )
|
||||
{
|
||||
|
|
@ -870,6 +929,25 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
printf( "Cannot read extension \"w\" because AIG is rehashed. Use \"&r -s <file.aig>\".\n" );
|
||||
Vec_IntFree( vPairs );
|
||||
}
|
||||
// read object ID mapping
|
||||
else if ( *pCur == 'y' )
|
||||
{
|
||||
pCur++;
|
||||
int nInts = Gia_AigerReadInt(pCur)/4; pCur += 4;
|
||||
if ( fSkipStrash ) {
|
||||
pNew->vEquLitIds = Vec_IntStart( nInts );
|
||||
memcpy( Vec_IntArray(pNew->vEquLitIds), pCur, (size_t)4*nInts );
|
||||
if ( Vec_IntSize(pNew->vEquLitIds) != Gia_ManObjNum(pNew) ) {
|
||||
printf( "Cannot read extension \"y\" because object count changed. Use \"&r -s <file.aig>\".\n" );
|
||||
Vec_IntFreeP( &pNew->vEquLitIds );
|
||||
}
|
||||
else if ( fVerbose ) printf( "Finished reading extension \"y\".\n" );
|
||||
}
|
||||
else {
|
||||
if ( fVerbose ) printf( "Cannot read extension \"y\" because AIG is rehashed. Use \"&r -s <file.aig>\".\n" );
|
||||
}
|
||||
pCur += 4*nInts;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
|
@ -914,6 +992,106 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
pNew->pAigExtra = pAigExtra;
|
||||
}
|
||||
|
||||
// Apply init state transformation for register boxes with init=1
|
||||
if ( pNew->vRegInits && Vec_IntCountEntry(pNew->vRegInits, 1) > 0 )
|
||||
{
|
||||
extern void Gia_ManFlipInit1( Gia_Man_t * p, Vec_Int_t * vInit );
|
||||
Tim_Man_t * pTimMan = (Tim_Man_t *)pNew->pManTime;
|
||||
|
||||
if ( pTimMan && Gia_ManRegBoxNum(pNew) > 0 )
|
||||
{
|
||||
// Handle register boxes: apply transformation to box inputs/outputs
|
||||
Gia_Obj_t * pObj;
|
||||
int i, curCo, curCi, nBoxIns, nBoxOuts;
|
||||
int iRegBox = 0;
|
||||
|
||||
assert( Vec_IntSize(pNew->vRegInits) == Gia_ManRegBoxNum(pNew) );
|
||||
|
||||
// Step 1: Mark register box outputs with init state 1
|
||||
curCi = Tim_ManPiNum(pTimMan);
|
||||
for ( i = 0; i < Gia_ManBoxNum(pNew); i++ )
|
||||
{
|
||||
nBoxIns = Tim_ManBoxInputNum(pTimMan, i);
|
||||
nBoxOuts = Tim_ManBoxOutputNum(pTimMan, i);
|
||||
// Check if this is a register box (1-input, 1-output)
|
||||
if ( nBoxIns == 1 && nBoxOuts == 1 )
|
||||
{
|
||||
if ( Vec_IntEntry(pNew->vRegInits, iRegBox) == 1 )
|
||||
{
|
||||
pObj = Gia_ManCi(pNew, curCi);
|
||||
pObj->fMark0 = 1;
|
||||
}
|
||||
iRegBox++;
|
||||
}
|
||||
curCi += nBoxOuts;
|
||||
}
|
||||
|
||||
// Step 2: Propagate complementation through AND gates
|
||||
Gia_ManForEachAnd( pNew, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjFanin0(pObj)->fMark0 )
|
||||
pObj->fCompl0 ^= 1;
|
||||
if ( Gia_ObjFanin1(pObj)->fMark0 )
|
||||
pObj->fCompl1 ^= 1;
|
||||
}
|
||||
|
||||
// Step 3: Complement CO fanins if needed
|
||||
Gia_ManForEachCo( pNew, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjFanin0(pObj)->fMark0 )
|
||||
pObj->fCompl0 ^= 1;
|
||||
}
|
||||
|
||||
// Step 4: Clear marks
|
||||
curCi = Tim_ManPiNum(pTimMan);
|
||||
iRegBox = 0;
|
||||
for ( i = 0; i < Gia_ManBoxNum(pNew); i++ )
|
||||
{
|
||||
nBoxIns = Tim_ManBoxInputNum(pTimMan, i);
|
||||
nBoxOuts = Tim_ManBoxOutputNum(pTimMan, i);
|
||||
if ( nBoxIns == 1 && nBoxOuts == 1 )
|
||||
{
|
||||
if ( Vec_IntEntry(pNew->vRegInits, iRegBox) == 1 )
|
||||
{
|
||||
pObj = Gia_ManCi(pNew, curCi);
|
||||
pObj->fMark0 = 0;
|
||||
}
|
||||
iRegBox++;
|
||||
}
|
||||
curCi += nBoxOuts;
|
||||
}
|
||||
|
||||
// Step 5: Complement register box inputs with init state 1
|
||||
curCo = Tim_ManPoNum(pTimMan);
|
||||
iRegBox = 0;
|
||||
for ( i = 0; i < Gia_ManBoxNum(pNew); i++ )
|
||||
{
|
||||
nBoxIns = Tim_ManBoxInputNum(pTimMan, i);
|
||||
nBoxOuts = Tim_ManBoxOutputNum(pTimMan, i);
|
||||
if ( nBoxIns == 1 && nBoxOuts == 1 )
|
||||
{
|
||||
if ( Vec_IntEntry(pNew->vRegInits, iRegBox) == 1 )
|
||||
{
|
||||
pObj = Gia_ManCo(pNew, curCo);
|
||||
pObj->fCompl0 ^= 1;
|
||||
}
|
||||
iRegBox++;
|
||||
}
|
||||
curCo += nBoxIns;
|
||||
}
|
||||
|
||||
// Clear all init states to 0 (transformation is now structural)
|
||||
Vec_IntFill( pNew->vRegInits, Vec_IntSize(pNew->vRegInits), 0 );
|
||||
}
|
||||
else if ( Gia_ManRegNum(pNew) > 0 )
|
||||
{
|
||||
// Handle regular flops (no boxes)
|
||||
Gia_ManFlipInit1( pNew, pNew->vRegInits );
|
||||
// Clear all init states to 0 (transformation is now structural)
|
||||
Vec_IntFill( pNew->vRegInits, Vec_IntSize(pNew->vRegInits), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fHieOnly )
|
||||
{
|
||||
// Tim_ManPrint( (Tim_Man_t *)pNew->pManTime );
|
||||
|
|
@ -953,9 +1131,12 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
}
|
||||
}
|
||||
pInit[i] = 0;
|
||||
pNew = Gia_ManDupZeroUndc( pTemp = pNew, pInit, 0, fGiaSimple, 1 );
|
||||
pNew->nConstrs = pTemp->nConstrs; pTemp->nConstrs = 0;
|
||||
Gia_ManStop( pTemp );
|
||||
if ( !fSkipStrash )
|
||||
{
|
||||
pNew = Gia_ManDupZeroUndc( pTemp = pNew, pInit, 0, fGiaSimple, 1 );
|
||||
pNew->nConstrs = pTemp->nConstrs; pTemp->nConstrs = 0;
|
||||
Gia_ManStop( pTemp );
|
||||
}
|
||||
ABC_FREE( pInit );
|
||||
}
|
||||
Vec_IntFreeP( &vInits );
|
||||
|
|
@ -1113,7 +1294,7 @@ Vec_Str_t * Gia_AigerWriteIntoMemoryStr( Gia_Man_t * p )
|
|||
Gia_AigerWriteUnsigned( vBuffer, uLit - uLit1 );
|
||||
Gia_AigerWriteUnsigned( vBuffer, uLit1 - uLit0 );
|
||||
}
|
||||
Vec_StrPrintStr( vBuffer, "c" );
|
||||
Vec_StrPrintStr( vBuffer, "c\n" );
|
||||
return vBuffer;
|
||||
}
|
||||
|
||||
|
|
@ -1214,7 +1395,7 @@ Vec_Str_t * Gia_AigerWriteIntoMemoryStrPart( Gia_Man_t * p, Vec_Int_t * vCis, Ve
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine )
|
||||
void Gia_AigerWriteS( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine, int fSkipComment )
|
||||
{
|
||||
int fVerbose = XAIG_VERBOSE;
|
||||
FILE * pFile;
|
||||
|
|
@ -1370,42 +1551,56 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
|
|||
if ( p->pManTime )
|
||||
{
|
||||
float * pTimes;
|
||||
pTimes = Tim_ManGetArrTimes( (Tim_Man_t *)p->pManTime );
|
||||
pTimes = Tim_ManGetArrTimes( (Tim_Man_t *)p->pManTime, Gia_ManRegNum(p) );
|
||||
if ( pTimes )
|
||||
{
|
||||
int nPis = Tim_ManPiNum((Tim_Man_t *)p->pManTime);
|
||||
int nFlops = Gia_ManRegNum(p);
|
||||
fprintf( pFile, "i" );
|
||||
Gia_FileWriteBufferSize( pFile, 4*Tim_ManPiNum((Tim_Man_t *)p->pManTime) );
|
||||
fwrite( pTimes, 1, 4*Tim_ManPiNum((Tim_Man_t *)p->pManTime), pFile );
|
||||
Gia_FileWriteBufferSize( pFile, 4*(nPis + nFlops) );
|
||||
fwrite( pTimes, 1, 4*(nPis + nFlops), pFile );
|
||||
ABC_FREE( pTimes );
|
||||
if ( fVerbose ) printf( "Finished writing extension \"i\".\n" );
|
||||
if ( fVerbose ) printf( "Finished writing extension \"i\" (PIs+Flops).\n" );
|
||||
}
|
||||
pTimes = Tim_ManGetReqTimes( (Tim_Man_t *)p->pManTime );
|
||||
pTimes = Tim_ManGetReqTimes( (Tim_Man_t *)p->pManTime, Gia_ManRegNum(p) );
|
||||
if ( pTimes )
|
||||
{
|
||||
int nPos = Tim_ManPoNum((Tim_Man_t *)p->pManTime);
|
||||
int nFlops = Gia_ManRegNum(p);
|
||||
// Convert TIM_ETERNITY sentinel to -1.0 per XAIG spec
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nPos + nFlops; i++ )
|
||||
if ( pTimes[i] >= TIM_ETERNITY )
|
||||
pTimes[i] = -1.0;
|
||||
}
|
||||
fprintf( pFile, "o" );
|
||||
Gia_FileWriteBufferSize( pFile, 4*Tim_ManPoNum((Tim_Man_t *)p->pManTime) );
|
||||
fwrite( pTimes, 1, 4*Tim_ManPoNum((Tim_Man_t *)p->pManTime), pFile );
|
||||
Gia_FileWriteBufferSize( pFile, 4*(nPos + nFlops) );
|
||||
fwrite( pTimes, 1, 4*(nPos + nFlops), pFile );
|
||||
ABC_FREE( pTimes );
|
||||
if ( fVerbose ) printf( "Finished writing extension \"o\".\n" );
|
||||
if ( fVerbose ) printf( "Finished writing extension \"o\" (POs+Flops).\n" );
|
||||
}
|
||||
}
|
||||
// write equivalences
|
||||
if ( p->pReprs && p->pNexts )
|
||||
{
|
||||
extern Vec_Str_t * Gia_WriteEquivClasses( Gia_Man_t * p );
|
||||
fprintf( pFile, "e" );
|
||||
vStrExt = Gia_WriteEquivClasses( p );
|
||||
Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
|
||||
fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
|
||||
Vec_StrFree( vStrExt );
|
||||
}
|
||||
//if ( p->pReprs && p->pNexts )
|
||||
//{
|
||||
// extern Vec_Str_t * Gia_WriteEquivClasses( Gia_Man_t * p );
|
||||
// fprintf( pFile, "e" );
|
||||
// vStrExt = Gia_WriteEquivClasses( p );
|
||||
// Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
|
||||
// fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
|
||||
// Vec_StrFree( vStrExt );
|
||||
//}
|
||||
// write flop classes
|
||||
if ( p->vFlopClasses )
|
||||
{
|
||||
int i;
|
||||
fprintf( pFile, "f" );
|
||||
Gia_FileWriteBufferSize( pFile, 4*Gia_ManRegNum(p) );
|
||||
assert( Vec_IntSize(p->vFlopClasses) == Gia_ManRegNum(p) );
|
||||
fwrite( Vec_IntArray(p->vFlopClasses), 1, 4*Gia_ManRegNum(p), pFile );
|
||||
Gia_FileWriteBufferSize( pFile, 4*(Vec_IntSize(p->vFlopClasses)+1) );
|
||||
Gia_FileWriteBufferSize( pFile, Vec_IntSize(p->vFlopClasses) );
|
||||
for ( i = 0; i < Vec_IntSize(p->vFlopClasses); i++ )
|
||||
Gia_FileWriteBufferSize( pFile, Vec_IntEntry(p->vFlopClasses, i) );
|
||||
if ( fVerbose ) printf( "Finished writing extension \"f\".\n" );
|
||||
}
|
||||
// write gate classes
|
||||
if ( p->vGateClasses )
|
||||
|
|
@ -1461,6 +1656,18 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
|
|||
Vec_StrFree( vStrExt );
|
||||
if ( fVerbose ) printf( "Finished writing extension \"m\".\n" );
|
||||
}
|
||||
// write cell mapping
|
||||
if ( Gia_ManHasCellMapping(p) )
|
||||
{
|
||||
extern Vec_Str_t * Gia_AigerWriteCellMappingDoc( Gia_Man_t * p );
|
||||
fprintf( pFile, "M" );
|
||||
vStrExt = Gia_AigerWriteCellMappingDoc( p );
|
||||
Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
|
||||
fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
|
||||
Vec_StrFree( vStrExt );
|
||||
if ( fVerbose ) printf( "Finished writing extension \"M\".\n" );
|
||||
|
||||
}
|
||||
// write placement
|
||||
if ( p->pPlacement )
|
||||
{
|
||||
|
|
@ -1477,6 +1684,7 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
|
|||
Gia_FileWriteBufferSize( pFile, Vec_IntSize(p->vRegClasses) );
|
||||
for ( i = 0; i < Vec_IntSize(p->vRegClasses); i++ )
|
||||
Gia_FileWriteBufferSize( pFile, Vec_IntEntry(p->vRegClasses, i) );
|
||||
if ( fVerbose ) printf( "Finished writing extension \"r\".\n" );
|
||||
}
|
||||
// write register inits
|
||||
if ( p->vRegInits )
|
||||
|
|
@ -1499,6 +1707,88 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
|
|||
for ( i = 0; i < Vec_IntSize(p->vConfigs); i++ )
|
||||
Gia_FileWriteBufferSize( pFile, Vec_IntEntry(p->vConfigs, i) );
|
||||
}
|
||||
// write configuration data for extension "j"
|
||||
if ( p->vConfigs2 )
|
||||
{
|
||||
int nTotalSize, nInstances = 0;
|
||||
If_LibCell_t * pLibCell = (If_LibCell_t *)Abc_FrameReadLibCell();
|
||||
char *pCell0, *pCell1, *pCell2;
|
||||
|
||||
// Get formulas from cell library or use defaults
|
||||
if ( pLibCell && pLibCell->nCellNum == 3 &&
|
||||
pLibCell->pCellNames[0] && pLibCell->pCellNames[1] && pLibCell->pCellNames[2] )
|
||||
{
|
||||
pCell0 = pLibCell->pCellNames[0];
|
||||
pCell1 = pLibCell->pCellNames[1];
|
||||
pCell2 = pLibCell->pCellNames[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !pLibCell )
|
||||
Abc_Print( 0, "Warning: Cell library is not loaded. Using generic formulas.\n" );
|
||||
else if ( pLibCell->nCellNum != 3 )
|
||||
Abc_Print( 0, "Warning: Cell library has %d cells (expected exactly 3). Using generic formulas.\n", pLibCell->nCellNum );
|
||||
else
|
||||
Abc_Print( 0, "Warning: Cell library does not contain all required cells. Using generic formulas.\n" );
|
||||
pCell0 = "Formula1";
|
||||
pCell1 = "Formula2";
|
||||
pCell2 = "Formula3";
|
||||
}
|
||||
// Count instances by scanning the byte data
|
||||
for ( i = 0; i < Vec_StrSize(p->vConfigs2); )
|
||||
{
|
||||
unsigned char CellId = (unsigned char)Vec_StrEntry(p->vConfigs2, i);
|
||||
if ( CellId == 0 )
|
||||
i += 7; // 1 byte CellId + 4 bytes mapping + 2 bytes truth table
|
||||
else if ( CellId == 1 )
|
||||
i += 12; // 1 byte CellId + 7 bytes mapping + 4 bytes truth tables
|
||||
else if ( CellId == 2 )
|
||||
i += 14; // 1 byte CellId + 9 bytes mapping + 4 bytes truth tables
|
||||
else
|
||||
assert( 0 ); // Unknown cell type
|
||||
nInstances++;
|
||||
}
|
||||
fprintf( pFile, "j" );
|
||||
// Calculate total size
|
||||
nTotalSize = 4; // Reserved value
|
||||
nTotalSize += 4; // Number of cell types
|
||||
// Cell type 0
|
||||
nTotalSize += 4; // CellId
|
||||
nTotalSize += strlen(pCell0) + 1; // Function description
|
||||
nTotalSize += 4; // Bytes per instance
|
||||
// Cell type 1
|
||||
nTotalSize += 4; // CellId
|
||||
nTotalSize += strlen(pCell1) + 1; // Function description
|
||||
nTotalSize += 4; // Bytes per instance
|
||||
// Cell type 2
|
||||
nTotalSize += 4; // CellId
|
||||
nTotalSize += strlen(pCell2) + 1; // Function description
|
||||
nTotalSize += 4; // Bytes per instance
|
||||
// Instance data
|
||||
nTotalSize += 4; // Total instances count
|
||||
nTotalSize += Vec_StrSize(p->vConfigs2); // Actual instance data
|
||||
Gia_FileWriteBufferSize( pFile, nTotalSize );
|
||||
// Write reserved value
|
||||
Gia_FileWriteBufferSize( pFile, 0 );
|
||||
// Write number of cell types
|
||||
Gia_FileWriteBufferSize( pFile, 3 );
|
||||
// Write cell type 0 (LUT4)
|
||||
Gia_FileWriteBufferSize( pFile, 0 ); // CellId
|
||||
fwrite( pCell0, 1, strlen(pCell0) + 1, pFile );
|
||||
Gia_FileWriteBufferSize( pFile, 7 ); // 1 byte CellId + 4 bytes mapping + 2 bytes truth table
|
||||
// Write cell type 1 (S44)
|
||||
Gia_FileWriteBufferSize( pFile, 1 ); // CellId
|
||||
fwrite( pCell1, 1, strlen(pCell1) + 1, pFile );
|
||||
Gia_FileWriteBufferSize( pFile, 12 ); // 1 byte CellId + 7 bytes mapping + 4 bytes truth tables
|
||||
// Write cell type 2 (9-input)
|
||||
Gia_FileWriteBufferSize( pFile, 2 ); // CellId
|
||||
fwrite( pCell2, 1, strlen(pCell2) + 1, pFile );
|
||||
Gia_FileWriteBufferSize( pFile, 14 ); // 1 byte CellId + 9 bytes mapping + 4 bytes truth tables
|
||||
// Write total instances
|
||||
Gia_FileWriteBufferSize( pFile, nInstances );
|
||||
// Write instance data as raw bytes
|
||||
fwrite( Vec_StrArray(p->vConfigs2), 1, Vec_StrSize(p->vConfigs2), pFile );
|
||||
}
|
||||
// write choices
|
||||
if ( Gia_ManHasChoices(p) )
|
||||
{
|
||||
|
|
@ -1543,6 +1833,15 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
|
|||
assert( Vec_IntSize(p->vObjClasses) == Gia_ManObjNum(p) );
|
||||
fwrite( Vec_IntArray(p->vObjClasses), 1, 4*Gia_ManObjNum(p), pFile );
|
||||
}
|
||||
// write object classes
|
||||
if ( p->vEquLitIds )
|
||||
{
|
||||
fprintf( pFile, "y" );
|
||||
Gia_FileWriteBufferSize( pFile, 4*Gia_ManObjNum(p) );
|
||||
assert( Vec_IntSize(p->vEquLitIds) == Gia_ManObjNum(p) );
|
||||
fwrite( Vec_IntArray(p->vEquLitIds), 1, 4*Gia_ManObjNum(p), pFile );
|
||||
if ( fVerbose ) printf( "Finished writing extension \"y\".\n" );
|
||||
}
|
||||
// write name
|
||||
if ( p->pName )
|
||||
{
|
||||
|
|
@ -1554,8 +1853,10 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
|
|||
// write comments
|
||||
if ( fWriteNewLine )
|
||||
fprintf( pFile, "c\n" );
|
||||
fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() );
|
||||
fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
|
||||
if ( !fSkipComment ) {
|
||||
fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() );
|
||||
fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
|
||||
}
|
||||
fclose( pFile );
|
||||
if ( p != pInit )
|
||||
{
|
||||
|
|
@ -1564,6 +1865,22 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
|
|||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the AIG in the binary AIGER format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine )
|
||||
{
|
||||
Gia_AigerWriteS( pInit, pFileName, fWriteSymbols, fCompact, fWriteNewLine, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the AIG in the binary AIGER format.]
|
||||
|
|
@ -1764,4 +2081,3 @@ int main( int argc, char ** argv )
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
#include "misc/st/st.h"
|
||||
#include "map/mio/mio.h"
|
||||
#include "map/mio/mioInt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -288,6 +291,101 @@ Vec_Str_t * Gia_AigerWriteMappingDoc( Gia_Man_t * p )
|
|||
return Vec_StrAllocArray( (char *)pBuffer, 4*nSize );
|
||||
}
|
||||
|
||||
int Gia_AigerWriteCellMappingInstance( Gia_Man_t * p, unsigned char * pBuffer, int nSize2, int i )
|
||||
{
|
||||
int k, iFan;
|
||||
if ( !Gia_ObjIsCellInv(p, i) ) {
|
||||
Gia_AigerWriteInt( pBuffer + nSize2, Gia_ObjCellId(p, i) ); nSize2 += 4;
|
||||
Gia_AigerWriteInt( pBuffer + nSize2, i ); nSize2 += 4;
|
||||
Gia_CellForEachFanin( p, i, iFan, k )
|
||||
{
|
||||
Gia_AigerWriteInt( pBuffer + nSize2, iFan );
|
||||
nSize2 += 4;
|
||||
}
|
||||
} else {
|
||||
Gia_AigerWriteInt( pBuffer + nSize2, 3 ); nSize2 += 4;
|
||||
Gia_AigerWriteInt( pBuffer + nSize2, i ); nSize2 += 4;
|
||||
Gia_AigerWriteInt( pBuffer + nSize2, Abc_LitNot(i) ); nSize2 += 4;
|
||||
}
|
||||
|
||||
return nSize2;
|
||||
}
|
||||
|
||||
Vec_Str_t * Gia_AigerWriteCellMappingDoc( Gia_Man_t * p )
|
||||
{
|
||||
unsigned char * pBuffer;
|
||||
int i, nCells = 0, nInstances = 0, nSize = 8, nSize2 = 0;
|
||||
Mio_Cell2_t * pCells = Mio_CollectRootsNewDefault2( 6, &nCells, 0 );
|
||||
assert( pCells );
|
||||
|
||||
for (int i = 0; i < nCells; i++)
|
||||
{
|
||||
Mio_Gate_t *pGate = (Mio_Gate_t *) pCells[i].pMioGate;
|
||||
Mio_Pin_t *pPin;
|
||||
nSize += strlen(Mio_GateReadName(pGate)) + 1;
|
||||
nSize += strlen(Mio_GateReadOutName(pGate)) + 1 + 4;
|
||||
Mio_GateForEachPin( pGate, pPin )
|
||||
nSize += strlen(Mio_PinReadName(pPin)) + 1;
|
||||
}
|
||||
|
||||
Gia_ManForEachCell( p, i )
|
||||
{
|
||||
assert ( !Gia_ObjIsCellBuf(p, i) ); // not implemented
|
||||
nInstances++;
|
||||
if ( Gia_ObjIsCellInv(p, i) )
|
||||
nSize += 12;
|
||||
else
|
||||
nSize += Gia_ObjCellSize(p, i) * 4 + 8;
|
||||
}
|
||||
|
||||
pBuffer = ABC_ALLOC( unsigned char, nSize );
|
||||
Gia_AigerWriteInt( pBuffer + nSize2, nCells ); nSize2 += 4;
|
||||
Gia_AigerWriteInt( pBuffer + nSize2, nInstances ); nSize2 += 4;
|
||||
|
||||
for (int i = 0; i < nCells; i++)
|
||||
{
|
||||
int nPins = 0;
|
||||
Mio_Gate_t *pGate = (Mio_Gate_t *) pCells[i].pMioGate;
|
||||
Mio_Pin_t *pPin;
|
||||
|
||||
strcpy((char *) pBuffer + nSize2, Mio_GateReadName(pGate));
|
||||
nSize2 += strlen(Mio_GateReadName(pGate)) + 1;
|
||||
strcpy((char *) pBuffer + nSize2, Mio_GateReadOutName(pGate));
|
||||
nSize2 += strlen(Mio_GateReadOutName(pGate)) + 1;
|
||||
|
||||
Mio_GateForEachPin( pGate, pPin )
|
||||
nPins++;
|
||||
Gia_AigerWriteInt( pBuffer + nSize2, nPins ); nSize2 += 4;
|
||||
|
||||
Mio_GateForEachPin( pGate, pPin )
|
||||
{
|
||||
strcpy((char *) pBuffer + nSize2, Mio_PinReadName(pPin));
|
||||
nSize2 += strlen(Mio_PinReadName(pPin)) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
Gia_ManForEachCell( p, i )
|
||||
{
|
||||
if ( Gia_ObjIsCellBuf(p, i) )
|
||||
continue;
|
||||
|
||||
if ( Gia_ObjIsCellInv(p, i) && !Abc_LitIsCompl(i) ) {
|
||||
// swap the order so that the inverter is after the driver
|
||||
// of the inverter's input
|
||||
nSize2 = Gia_AigerWriteCellMappingInstance(p, pBuffer, nSize2, Abc_LitNot(i) );
|
||||
nSize2 = Gia_AigerWriteCellMappingInstance(p, pBuffer, nSize2, i );
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
nSize2 = Gia_AigerWriteCellMappingInstance(p, pBuffer, nSize2, i );
|
||||
}
|
||||
|
||||
assert( nSize2 == nSize );
|
||||
ABC_FREE( pCells );
|
||||
return Vec_StrAllocArray( (char *)pBuffer, nSize );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Read/write packing information.]
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,580 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaBsFind.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaBsFind.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Cost function: sum of squared differences between all pairs
|
||||
int cost_sum_squares(int* subset, int K, void * pData) {
|
||||
double cost = 0;
|
||||
for (int i = 0; i < K - 1; i++) {
|
||||
for (int j = i + 1; j < K; j++) {
|
||||
int diff = subset[i] - subset[j];
|
||||
cost += diff * diff;
|
||||
}
|
||||
}
|
||||
// Normalize to be between 2 and 100
|
||||
return (int)(2.0 + (cost / (K * K)) * 0.98);
|
||||
}
|
||||
|
||||
// Compare function for qsort - for sorting individual subsets
|
||||
int compare_ints(const void* a, const void* b) {
|
||||
return *(int*)a - *(int*)b;
|
||||
}
|
||||
|
||||
// Compare function for qsort - for sorting subsets by cost
|
||||
// Subset format: [K, element1, element2, ..., elementK, cost]
|
||||
int compare_subsets_by_cost(const void* a, const void* b) {
|
||||
const int* subset_a = (const int*)a;
|
||||
const int* subset_b = (const int*)b;
|
||||
int K_a = subset_a[0];
|
||||
int K_b = subset_b[0];
|
||||
assert( K_a == K_b );
|
||||
// Cost is at position K+1 (after K and K elements)
|
||||
return subset_a[K_a + 1] - subset_b[K_b + 1];
|
||||
}
|
||||
|
||||
// Generate a random subset of K numbers from 0 to N-1
|
||||
// Format: [K, element1, element2, ..., elementK, cost]
|
||||
void generate_random_subset(int* subset, int K, int N) {
|
||||
subset[0] = K; // Store K in first position
|
||||
int count = 0;
|
||||
|
||||
// First, generate K unique random numbers
|
||||
while (count < K) {
|
||||
int num = rand() % N;
|
||||
|
||||
// Check if number already exists in subset
|
||||
int exists = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (subset[i + 1] == num) {
|
||||
exists = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
subset[count + 1] = num;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Then, sort the subset using bubble sort
|
||||
for (int i = 1; i < K; i++) {
|
||||
for (int j = 1; j < K - i + 1; j++) {
|
||||
if (subset[j] > subset[j + 1]) {
|
||||
int temp = subset[j];
|
||||
subset[j] = subset[j + 1];
|
||||
subset[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create offspring from two parent subsets
|
||||
// Uses pre-allocated arrays to avoid repeated memory allocation
|
||||
void create_offspring(int* parent1, int* parent2, int* offspring, int K, int N,
|
||||
int* in_offspring, int* in_parent1, int* in_parent2, int* candidates) {
|
||||
int count = 0;
|
||||
offspring[0] = K; // Store K in first position
|
||||
|
||||
// Mark which numbers are in each parent (skip first element which is K)
|
||||
for (int i = 1; i <= K; i++) {
|
||||
in_parent1[parent1[i]] = 1;
|
||||
in_parent2[parent2[i]] = 1;
|
||||
}
|
||||
|
||||
// First, add numbers that appear in both parents
|
||||
for (int i = 0; i < N && count < K; i++) {
|
||||
if (in_parent1[i] && in_parent2[i]) {
|
||||
offspring[count + 1] = i;
|
||||
count++;
|
||||
in_offspring[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Create array of numbers that appear in exactly one parent
|
||||
int num_candidates = 0;
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
if ((in_parent1[i] || in_parent2[i]) && !in_offspring[i]) {
|
||||
candidates[num_candidates++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Randomly add from candidates until we have K numbers
|
||||
while (count < K && num_candidates > 0) {
|
||||
int idx = rand() % num_candidates;
|
||||
offspring[count + 1] = candidates[idx];
|
||||
count++;
|
||||
in_offspring[candidates[idx]] = 1;
|
||||
|
||||
// Remove selected candidate
|
||||
candidates[idx] = candidates[--num_candidates];
|
||||
}
|
||||
|
||||
// Sort the offspring elements (not including the first K value)
|
||||
qsort(&offspring[1], K, sizeof(int), compare_ints);
|
||||
|
||||
// Clean up the intean arrays for next use - only clean used entries
|
||||
for (int i = 1; i <= K; i++) {
|
||||
in_parent1[parent1[i]] = 0;
|
||||
in_parent2[parent2[i]] = 0;
|
||||
}
|
||||
for (int i = 1; i <= K; i++) {
|
||||
in_offspring[offspring[i]] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Count unique subsets in a sorted array of subsets
|
||||
// Returns the number of unique subsets and prints the percentage
|
||||
int count_unique_subsets(int* sorted_subsets, int num_subsets, int subset_size, const char* label) {
|
||||
if (num_subsets == 0) return 0;
|
||||
|
||||
int unique_count = 1; // First subset is always unique
|
||||
int K = sorted_subsets[0]; // Get K from first subset
|
||||
|
||||
// Compare each subset with the previous one
|
||||
for (int i = 1; i < num_subsets; i++) {
|
||||
int* current = &sorted_subsets[i * subset_size];
|
||||
int* previous = &sorted_subsets[(i - 1) * subset_size];
|
||||
|
||||
// Compare all K elements (skip position 0 which has K, and K+1 which has cost)
|
||||
int is_different = 0;
|
||||
for (int j = 1; j <= K; j++) {
|
||||
if (current[j] != previous[j]) {
|
||||
is_different = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_different) {
|
||||
unique_count++;
|
||||
}
|
||||
}
|
||||
|
||||
double percentage = (unique_count * 100.0) / num_subsets;
|
||||
printf("%s: %d unique subsets out of %d (%.1f%%)\n",
|
||||
label, unique_count, num_subsets, percentage);
|
||||
|
||||
return unique_count;
|
||||
}
|
||||
|
||||
// Main genetic algorithm
|
||||
int genetic_subset_selection(int N, int K, int B, int L,
|
||||
int verbose,
|
||||
int (*cost_function)(int*, int, void *),
|
||||
int** best_subsets_history,
|
||||
int* iterations_used,
|
||||
void * pUserData) {
|
||||
int print_unique = 0;
|
||||
int M = B * (B - 1) / 2;
|
||||
int subset_size = K + 2; // K value + K elements + cost
|
||||
|
||||
// Allocate arrays
|
||||
int* current_generation = (int*)malloc(M * subset_size * sizeof(int));
|
||||
int* next_generation = (int*)malloc(M * subset_size * sizeof(int));
|
||||
int* all_best_subsets = (int*)calloc(B * L * subset_size, sizeof(int));
|
||||
|
||||
// Pre-allocate reusable arrays for create_offspring
|
||||
int* in_offspring = (int*)calloc(N, sizeof(int));
|
||||
int* in_parent1 = (int*)calloc(N, sizeof(int));
|
||||
int* in_parent2 = (int*)calloc(N, sizeof(int));
|
||||
int* candidates = (int*)malloc(K * 2 * sizeof(int));
|
||||
|
||||
// Generate initial population
|
||||
for (int i = 0; i < M; i++) {
|
||||
int* subset = ¤t_generation[i * subset_size];
|
||||
generate_random_subset(subset, K, N);
|
||||
// Cost function uses elements starting at position 1
|
||||
subset[K + 1] = cost_function(&subset[1], K, pUserData);
|
||||
}
|
||||
|
||||
// Sort to get best B subsets
|
||||
qsort(current_generation, M, subset_size * sizeof(int), compare_subsets_by_cost);
|
||||
if ( print_unique ) count_unique_subsets(current_generation, M, subset_size, "Initial population");
|
||||
|
||||
int best_cost = current_generation[K + 1];
|
||||
int generation = 0;
|
||||
int total_best_count = 0;
|
||||
|
||||
// Main evolutionary loop
|
||||
while (generation < L) {
|
||||
// Store best B subsets from current generation
|
||||
for (int i = 0; i < B && total_best_count < B * L; i++) {
|
||||
memcpy(&all_best_subsets[total_best_count * subset_size],
|
||||
¤t_generation[i * subset_size],
|
||||
subset_size * sizeof(int));
|
||||
total_best_count++;
|
||||
}
|
||||
|
||||
if ( verbose ) {
|
||||
printf( "Iter %d\n", generation );
|
||||
for (int i = 0; i < B; i++ ) {
|
||||
printf( "Subset %2d : {", i );
|
||||
for (int k = 0; k < K; k++ )
|
||||
printf( " %2d", (¤t_generation[i * subset_size])[k+1] );
|
||||
printf( " } " );
|
||||
printf( "Cost %2d\n", (¤t_generation[i * subset_size])[K+1] );
|
||||
}
|
||||
}
|
||||
|
||||
// Create next generation from pairs of best B subsets
|
||||
int offspring_idx = 0;
|
||||
for (int i = 0; i < B; i++) {
|
||||
for (int j = i + 1; j < B; j++) {
|
||||
int* parent1 = ¤t_generation[i * subset_size];
|
||||
int* parent2 = ¤t_generation[j * subset_size];
|
||||
int* offspring = &next_generation[offspring_idx * subset_size];
|
||||
|
||||
create_offspring(parent1, parent2, offspring, K, N,
|
||||
in_offspring, in_parent1, in_parent2, candidates);
|
||||
offspring[K + 1] = cost_function(&offspring[1], K, pUserData);
|
||||
offspring_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort next generation
|
||||
qsort(next_generation, M, subset_size * sizeof(int), compare_subsets_by_cost);
|
||||
if ( print_unique ) count_unique_subsets(next_generation, M, subset_size, "Next generation");
|
||||
|
||||
generation++;
|
||||
|
||||
// Check for improvement
|
||||
int new_best_cost = next_generation[K + 1];
|
||||
if (new_best_cost >= best_cost) {
|
||||
break; // No improvement
|
||||
}
|
||||
|
||||
best_cost = new_best_cost;
|
||||
|
||||
// Swap generations
|
||||
int* temp = current_generation;
|
||||
current_generation = next_generation;
|
||||
next_generation = temp;
|
||||
}
|
||||
|
||||
// Sort all best subsets collected using qsort
|
||||
qsort(all_best_subsets, total_best_count, subset_size * sizeof(int), compare_subsets_by_cost);
|
||||
if ( print_unique ) count_unique_subsets(all_best_subsets, total_best_count, subset_size, "All best subsets");
|
||||
|
||||
if ( verbose ) {
|
||||
printf( "Final best\n" );
|
||||
for (int i = 0; i < B; i++ ) {
|
||||
printf( "Subset %2d : {", i );
|
||||
for (int k = 0; k < K; k++ )
|
||||
printf( " %2d", (&all_best_subsets[i * subset_size])[k+1] );
|
||||
printf( " } " );
|
||||
printf( "Cost %2d\n", (&all_best_subsets[i * subset_size])[K+1] );
|
||||
}
|
||||
}
|
||||
|
||||
// Free pre-allocated arrays
|
||||
free(in_offspring);
|
||||
free(in_parent1);
|
||||
free(in_parent2);
|
||||
free(candidates);
|
||||
|
||||
// Return results
|
||||
if (best_subsets_history != NULL) {
|
||||
*best_subsets_history = all_best_subsets;
|
||||
} else {
|
||||
free(all_best_subsets);
|
||||
}
|
||||
|
||||
if (iterations_used != NULL) {
|
||||
*iterations_used = generation + 1;
|
||||
}
|
||||
|
||||
free(current_generation);
|
||||
free(next_generation);
|
||||
|
||||
return best_cost;
|
||||
}
|
||||
|
||||
// Test bench
|
||||
/*
|
||||
int bs_find_test() {
|
||||
srand(time(NULL));
|
||||
|
||||
// Test parameters
|
||||
int N = 30; // Total numbers (0 to 29)
|
||||
int K = 6; // Subset size
|
||||
int B = 10; // Number of best subsets to keep
|
||||
int L = 50; // Maximum iterations
|
||||
|
||||
printf("Genetic Algorithm for Subset Selection\n");
|
||||
printf("======================================\n");
|
||||
printf("Parameters:\n");
|
||||
printf(" N (total numbers): %d\n", N);
|
||||
printf(" K (subset size): %d\n", K);
|
||||
printf(" B (best subsets): %d\n", B);
|
||||
printf(" L (max iterations): %d\n", L);
|
||||
printf("\n");
|
||||
|
||||
// Run the algorithm
|
||||
int* best_subsets_history = NULL;
|
||||
int iterations_used = 0;
|
||||
int best_cost = genetic_subset_selection(N, K, B, L, 0,
|
||||
cost_sum_squares,
|
||||
&best_subsets_history,
|
||||
&iterations_used);
|
||||
|
||||
printf("Best cost found: %d\n", best_cost);
|
||||
printf("Iterations until convergence: %d\n\n", iterations_used);
|
||||
|
||||
// Display top 5 best subsets
|
||||
printf("Top 5 best subsets:\n");
|
||||
int subset_size = K + 2;
|
||||
for (int i = 0; i < 5 && i < B * L; i++) {
|
||||
int* subset = &best_subsets_history[i * subset_size];
|
||||
if (subset[K + 1] == 0) break; // Check if cost is 0 (uninitialized)
|
||||
|
||||
printf("Subset %d: {", i + 1);
|
||||
for (int j = 1; j <= K; j++) {
|
||||
printf("%d", subset[j]);
|
||||
if (j < K) printf(", ");
|
||||
}
|
||||
printf("} - Cost: %d\n", subset[K + 1]);
|
||||
}
|
||||
|
||||
// Test with different parameters
|
||||
printf("\n\nTesting with different parameters:\n");
|
||||
printf("==================================\n");
|
||||
|
||||
// Test 1: Smaller problem
|
||||
N = 20; K = 4; B = 6; L = 30;
|
||||
free(best_subsets_history);
|
||||
best_subsets_history = NULL;
|
||||
iterations_used = 0;
|
||||
|
||||
best_cost = genetic_subset_selection(N, K, B, L, 0,
|
||||
cost_sum_squares,
|
||||
&best_subsets_history,
|
||||
&iterations_used);
|
||||
|
||||
printf("\nTest 1 - N=%d, K=%d, B=%d, L=%d\n", N, K, B, L);
|
||||
printf("Best cost: %d\n", best_cost);
|
||||
printf("Iterations until convergence: %d\n", iterations_used);
|
||||
printf("Best subset: {");
|
||||
for (int j = 1; j <= K; j++) {
|
||||
printf("%d", best_subsets_history[j]);
|
||||
if (j < K) printf(", ");
|
||||
}
|
||||
printf("}\n");
|
||||
|
||||
// Test 2: Larger problem
|
||||
N = 50; K = 8; B = 15; L = 100;
|
||||
free(best_subsets_history);
|
||||
best_subsets_history = NULL;
|
||||
iterations_used = 0;
|
||||
|
||||
best_cost = genetic_subset_selection(N, K, B, L, 0,
|
||||
cost_sum_squares,
|
||||
&best_subsets_history,
|
||||
&iterations_used);
|
||||
|
||||
printf("\nTest 2 - N=%d, K=%d, B=%d, L=%d\n", N, K, B, L);
|
||||
printf("Best cost: %d\n", best_cost);
|
||||
printf("Iterations until convergence: %d\n", iterations_used);
|
||||
printf("Best subset: {");
|
||||
for (int j = 1; j <= K; j++) {
|
||||
printf("%d", best_subsets_history[j]);
|
||||
if (j < K) printf(", ");
|
||||
}
|
||||
printf("}\n");
|
||||
|
||||
// Test 3: Test convergence speed with different B values
|
||||
printf("\n\nConvergence Speed Analysis:\n");
|
||||
printf("===========================\n");
|
||||
N = 40; K = 7; L = 100;
|
||||
|
||||
for (int B_test = 5; B_test <= 20; B_test += 5) {
|
||||
free(best_subsets_history);
|
||||
best_subsets_history = NULL;
|
||||
iterations_used = 0;
|
||||
|
||||
best_cost = genetic_subset_selection(N, K, B_test, L, 0,
|
||||
cost_sum_squares,
|
||||
&best_subsets_history,
|
||||
&iterations_used);
|
||||
|
||||
printf("B=%2d: Best cost=%3d, Iterations=%3d\n",
|
||||
B_test, best_cost, iterations_used);
|
||||
}
|
||||
|
||||
free(best_subsets_history);
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Wrd_t * Gia_ManBsFindStart( Gia_Man_t * pGia, int nWords )
|
||||
{
|
||||
Vec_Wrd_t * vSims = Vec_WrdStartRandom( (Gia_ManCiNum(pGia) + 1) * nWords );
|
||||
Vec_WrdFillExtra( vSims, Gia_ManObjNum(pGia) * nWords, 0 );
|
||||
Abc_TtClear( Vec_WrdArray(vSims), nWords );
|
||||
return vSims;
|
||||
}
|
||||
void Gia_ManBsFindNext( Gia_Man_t * pGia, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsOuts, int iMint )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
word * pSims[2], * pSim;
|
||||
Gia_ManForEachAnd( pGia, pObj, i ) {
|
||||
pSim = Vec_WrdEntryP( vSims, i * nWords );
|
||||
pSims[0] = Vec_WrdEntryP( vSims, Gia_ObjFaninId0(pObj, i) * nWords );
|
||||
pSims[1] = Vec_WrdEntryP( vSims, Gia_ObjFaninId1(pObj, i) * nWords );
|
||||
Abc_TtAndCompl( pSim, pSims[0], Gia_ObjFaninC0(pObj), pSims[1], Gia_ObjFaninC1(pObj), nWords );
|
||||
}
|
||||
Gia_ManForEachCo( pGia, pObj, i ) {
|
||||
pSim = Vec_WrdEntryP( vSimsOuts, (iMint * Gia_ManCoNum(pGia) + i) * nWords );
|
||||
pSims[0] = Vec_WrdEntryP( vSims, Gia_ObjFaninId0p(pGia, pObj) * nWords );
|
||||
Abc_TtCopy( pSim, pSims[0], nWords, Gia_ObjFaninC0(pObj) );
|
||||
}
|
||||
}
|
||||
int Gia_ManBsFindMyu( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsOuts, Vec_Int_t * vVarNums, Vec_Wrd_t * vTemp )
|
||||
{
|
||||
int nMints = 1 << Vec_IntSize(vVarNums);
|
||||
int nWordsAll = Gia_ManCoNum(p) * nWords;
|
||||
int nMyu = 0, pMyu[256], i, k, Var;
|
||||
assert( nMints <= 256 );
|
||||
assert( Vec_WrdSize(vTemp) == nWords * Vec_IntSize(vVarNums) );
|
||||
assert( Vec_WrdSize(vSimsOuts) == nMints * nWordsAll );
|
||||
Vec_IntForEachEntry( vVarNums, Var, i )
|
||||
Abc_TtCopy( Vec_WrdEntryP(vTemp, i * nWords), Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), nWords, 0 );
|
||||
for ( int m = 0; m < nMints; m++ ) {
|
||||
Vec_IntForEachEntry( vVarNums, Var, i )
|
||||
Abc_TtConst( Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), nWords, (m >> i) & 1 );
|
||||
Gia_ManBsFindNext( p, nWords, vSims, vSimsOuts, m );
|
||||
}
|
||||
Vec_IntForEachEntry( vVarNums, Var, i )
|
||||
Abc_TtCopy( Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), Vec_WrdEntryP(vTemp, i * nWords), nWords, 0 );
|
||||
for ( i = 0; i < nMints; i++ ) {
|
||||
word * pSim = Vec_WrdEntryP(vSimsOuts, nWordsAll * i);
|
||||
for ( k = 0; k < nMyu; k++ )
|
||||
if ( Abc_TtEqual(pSim, Vec_WrdEntryP(vSimsOuts, nWordsAll * pMyu[k]), nWordsAll) )
|
||||
break;
|
||||
if ( k == nMyu )
|
||||
pMyu[nMyu++] = i;
|
||||
}
|
||||
return nMyu;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct BsFind_UserData_t_ {
|
||||
Gia_Man_t * pGia;
|
||||
int nWords;
|
||||
Vec_Wrd_t * vSims;
|
||||
Vec_Wrd_t * vSimsOuts;
|
||||
Vec_Int_t * vVarNums;
|
||||
Vec_Wrd_t * vTemp;
|
||||
} BsFind_UserData_t;
|
||||
|
||||
BsFind_UserData_t * Gia_ManBsFindMyuFunctionStart( Gia_Man_t * pGia, int nWords, int nLutSize )
|
||||
{
|
||||
BsFind_UserData_t * p = ABC_CALLOC( BsFind_UserData_t, 1 );
|
||||
p->pGia = pGia;
|
||||
p->nWords = nWords;
|
||||
p->vSims = Gia_ManBsFindStart( pGia, nWords );
|
||||
p->vSimsOuts = Vec_WrdStart( (1 << nLutSize) * Gia_ManCoNum(pGia) * nWords );
|
||||
p->vVarNums = Vec_IntAlloc( nLutSize );
|
||||
p->vTemp = Vec_WrdStart( nLutSize * nWords );
|
||||
return p;
|
||||
}
|
||||
int Gia_ManBsFindMyuFunction( int * subset, int K, void * pUserData )
|
||||
{
|
||||
BsFind_UserData_t * p = (BsFind_UserData_t *)pUserData;
|
||||
Vec_IntClear( p->vVarNums );
|
||||
for ( int i = 0; i < K; i++ )
|
||||
Vec_IntPush( p->vVarNums, subset[i] );
|
||||
return Gia_ManBsFindMyu( p->pGia, p->nWords, p->vSims, p->vSimsOuts, p->vVarNums, p->vTemp );
|
||||
}
|
||||
void Gia_ManBsFindMyuFunctionStop( BsFind_UserData_t * p )
|
||||
{
|
||||
Vec_WrdFree( p->vSims );
|
||||
Vec_WrdFree( p->vSimsOuts );
|
||||
Vec_WrdFree( p->vTemp );
|
||||
Vec_IntFree( p->vVarNums );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManBsFindBest( Gia_Man_t * pGia, int nWords, int nLutSize, int nBest, int nIterMax, int fVerbose )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
Abc_Random(1);
|
||||
BsFind_UserData_t * p = Gia_ManBsFindMyuFunctionStart( pGia, nWords, nLutSize );
|
||||
int nIters = 0, Res = genetic_subset_selection( Gia_ManCiNum(pGia), nLutSize, nBest, nIterMax, fVerbose, Gia_ManBsFindMyuFunction, NULL, &nIters, (void *)p );
|
||||
printf( "The best Myu %d was found after considering %d bound-sets in %d iterations. ", Res, nIters*nBest*(nBest-1)/2, nIters );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
Gia_ManBsFindMyuFunctionStop( p );
|
||||
return Res;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -64,6 +64,7 @@ struct Cbs_Man_t_
|
|||
{
|
||||
Cbs_Par_t Pars; // parameters
|
||||
Gia_Man_t * pAig; // AIG manager
|
||||
int nSyncedObjs; // pAig objects already prepped (Value/marks/refs) for resident reuse
|
||||
Cbs_Que_t pProp; // propagation queue
|
||||
Cbs_Que_t pJust; // justification queue
|
||||
Cbs_Que_t pClauses; // clause queue
|
||||
|
|
@ -71,6 +72,9 @@ struct Cbs_Man_t_
|
|||
Vec_Int_t * vLevReas; // levels and decisions
|
||||
Vec_Int_t * vModel; // satisfying assignment
|
||||
Vec_Ptr_t * vTemp; // temporary storage
|
||||
Vec_Int_t * vOutLits; // optional endpoint literals to sample before cancel
|
||||
Vec_Int_t * vOutVals; // optional endpoint values by output
|
||||
int iOutVal; // current output whose endpoints are sampled
|
||||
// SAT calls statistics
|
||||
int nSatUnsat; // the number of proofs
|
||||
int nSatSat; // the number of failure
|
||||
|
|
@ -256,6 +260,29 @@ static inline void Cbs_ManSaveModelAll( Cbs_Man_t * p, Vec_Int_t * vCex )
|
|||
Vec_IntPush( vCex, Abc_Var2Lit(Gia_ObjId(p->pAig,pVar), !Cbs_VarValue(pVar)) );
|
||||
}
|
||||
|
||||
static inline int Cbs_ManLitValue( Cbs_Man_t * p, int iLit )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
if ( iLit < 0 )
|
||||
return -1;
|
||||
if ( Abc_Lit2Var(iLit) == 0 )
|
||||
return Abc_LitIsCompl(iLit);
|
||||
pObj = Gia_ManObj( p->pAig, Abc_Lit2Var(iLit) );
|
||||
if ( !Cbs_VarIsAssigned(pObj) )
|
||||
return -1;
|
||||
return Cbs_VarValue(pObj) ^ Abc_LitIsCompl(iLit);
|
||||
}
|
||||
|
||||
static inline void Cbs_ManSaveOutVals( Cbs_Man_t * p, Vec_Int_t * vOutLits, Vec_Int_t * vOutVals, int Out )
|
||||
{
|
||||
if ( vOutLits == NULL || vOutVals == NULL )
|
||||
return;
|
||||
if ( 2*Out + 1 >= Vec_IntSize(vOutLits) )
|
||||
return;
|
||||
Vec_IntWriteEntry( vOutVals, 2*Out, Cbs_ManLitValue( p, Vec_IntEntry(vOutLits, 2*Out) ) );
|
||||
Vec_IntWriteEntry( vOutVals, 2*Out + 1, Cbs_ManLitValue( p, Vec_IntEntry(vOutLits, 2*Out + 1) ) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -954,7 +981,10 @@ int Cbs_ManSolve( Cbs_Man_t * p, Gia_Obj_t * pObj )
|
|||
p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0;
|
||||
Cbs_ManAssign( p, pObj, 0, NULL, NULL );
|
||||
if ( !Cbs_ManSolve_rec(p, 0) && !Cbs_ManCheckLimits(p) )
|
||||
{
|
||||
Cbs_ManSaveModel( p, p->vModel );
|
||||
Cbs_ManSaveOutVals( p, p->vOutLits, p->vOutVals, p->iOutVal );
|
||||
}
|
||||
else
|
||||
RetValue = 1;
|
||||
Cbs_ManCancelUntil( p, 0 );
|
||||
|
|
@ -1034,14 +1064,14 @@ void Cbs_ManSatPrintStats( Cbs_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose )
|
||||
Vec_Int_t * Cbs_ManSolveMiterNcOutVals( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose, Vec_Int_t * vOutLits, Vec_Int_t ** pvOutVals )
|
||||
{
|
||||
extern void Gia_ManCollectTest( Gia_Man_t * pAig );
|
||||
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
|
||||
Cbs_Man_t * p;
|
||||
Vec_Int_t * vCex, * vVisit, * vCexStore;
|
||||
Cbs_Man_t * p;
|
||||
Vec_Int_t * vCex, * vVisit, * vCexStore, * vOutVals = NULL;
|
||||
Vec_Str_t * vStatus;
|
||||
Gia_Obj_t * pRoot;
|
||||
Gia_Obj_t * pRoot;
|
||||
int i, status;
|
||||
abctime clk, clkTotal = Abc_Clock();
|
||||
assert( Gia_ManRegNum(pAig) == 0 );
|
||||
|
|
@ -1058,6 +1088,12 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
|||
// create resulting data-structures
|
||||
vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
|
||||
vCexStore = Vec_IntAlloc( 10000 );
|
||||
if ( pvOutVals )
|
||||
{
|
||||
*pvOutVals = NULL;
|
||||
if ( vOutLits )
|
||||
vOutVals = Vec_IntStartFull( 2 * Gia_ManPoNum(pAig) );
|
||||
}
|
||||
vVisit = Vec_IntAlloc( 100 );
|
||||
vCex = Cbs_ReadModel( p );
|
||||
// solve for each output
|
||||
|
|
@ -1084,7 +1120,13 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
|||
clk = Abc_Clock();
|
||||
p->Pars.fUseHighest = 1;
|
||||
p->Pars.fUseLowest = 0;
|
||||
p->vOutLits = vOutLits;
|
||||
p->vOutVals = vOutVals;
|
||||
p->iOutVal = i;
|
||||
status = Cbs_ManSolve( p, Gia_ObjChild0(pRoot) );
|
||||
p->vOutLits = NULL;
|
||||
p->vOutVals = NULL;
|
||||
p->iOutVal = -1;
|
||||
// printf( "\n" );
|
||||
/*
|
||||
if ( status == -1 )
|
||||
|
|
@ -1126,6 +1168,10 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
|||
// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro );
|
||||
Cbs_ManStop( p );
|
||||
*pvStatus = vStatus;
|
||||
if ( pvOutVals )
|
||||
*pvOutVals = vOutVals;
|
||||
else
|
||||
Vec_IntFreeP( &vOutVals );
|
||||
|
||||
// printf( "Total number of cex literals = %d. (Ave = %d)\n",
|
||||
// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat,
|
||||
|
|
@ -1133,6 +1179,132 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
|||
return vCexStore;
|
||||
}
|
||||
|
||||
Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose )
|
||||
{
|
||||
return Cbs_ManSolveMiterNcOutVals( pAig, nConfs, pvStatus, f0Proved, fVerbose, NULL, NULL );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Incrementally prepares newly appended objects of a persistent AIG.]
|
||||
|
||||
Description [The pAig of a resident manager is append-only across solve calls.
|
||||
Cbs needs every unassigned object to carry Value=~0 and clean marks, and reads
|
||||
Gia_ObjRefNum during branching. After a clean solve Cbs restores Value/marks
|
||||
of the nodes it touched, and freshly appended nodes are zero-initialized, so we
|
||||
only have to prep the suffix [nSyncedObjs, ObjNum): set Value=~0, clear marks,
|
||||
grow pRefs and bump each new AND's fanin refs (= the global fanout counts that
|
||||
Gia_ManCreateRefs would produce, computed incrementally). This replaces the
|
||||
per-round O(|pAig|) refs/marks/value rebuild with O(newly appended).]
|
||||
|
||||
SideEffects [Allocates/grows pAig->pRefs (freed by Gia_ManStop).]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Cbs_ManSyncCore( Cbs_Man_t * p )
|
||||
{
|
||||
Gia_Man_t * pAig = p->pAig;
|
||||
Gia_Obj_t * pObj;
|
||||
int i, nObjs = Gia_ManObjNum( pAig );
|
||||
assert( p->nSyncedObjs <= nObjs );
|
||||
if ( p->nSyncedObjs == nObjs )
|
||||
return;
|
||||
pAig->pRefs = ABC_REALLOC( int, pAig->pRefs, nObjs );
|
||||
memset( pAig->pRefs + p->nSyncedObjs, 0, sizeof(int) * (nObjs - p->nSyncedObjs) );
|
||||
for ( i = p->nSyncedObjs; i < nObjs; i++ )
|
||||
{
|
||||
pObj = Gia_ManObj( pAig, i );
|
||||
pObj->fMark0 = pObj->fMark1 = 0;
|
||||
pObj->Value = ~0;
|
||||
if ( Gia_ObjIsAnd(pObj) )
|
||||
{
|
||||
pAig->pRefs[Gia_ObjFaninId0(pObj, i)]++;
|
||||
pAig->pRefs[Gia_ObjFaninId1(pObj, i)]++;
|
||||
}
|
||||
}
|
||||
p->nSyncedObjs = nObjs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Solves a set of root literals directly on a persistent AIG.]
|
||||
|
||||
Description [Same prover as Cbs_ManSolveMiterNc, but each problem is a root
|
||||
literal of p->pAig (no CO needed) instead of a CO of a freshly built view, and
|
||||
the manager is resident: it is allocated once on the persistent COless pCore
|
||||
and reused across rounds, only Cbs_ManSyncCore-ing the objects appended since
|
||||
the last call - so neither the throwaway view (alloc + copy-all-CIs + cone
|
||||
copy) nor the per-round whole-AIG prep is paid. Output index i corresponds to
|
||||
vRootLits[i]; vCexStore / vStatus format matches Cbs_ManSolveMiterNc. CEX is
|
||||
saved by CioId, which on pCore equals the view's CI numbering.]
|
||||
|
||||
SideEffects [Prepares newly appended objects via Cbs_ManSyncCore.]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Cbs_ManSolveRoots( Cbs_Man_t * p, Vec_Int_t * vRootLits, Vec_Str_t ** pvStatus, int fVerbose )
|
||||
{
|
||||
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
|
||||
Gia_Man_t * pAig = p->pAig;
|
||||
Vec_Int_t * vCex, * vCexStore;
|
||||
Vec_Str_t * vStatus;
|
||||
int i, iLit, status;
|
||||
abctime clk, clkTotal = Abc_Clock();
|
||||
assert( Gia_ManRegNum(pAig) == 0 );
|
||||
Cbs_ManSyncCore( p ); // prep only objects appended since the last solve
|
||||
vStatus = Vec_StrAlloc( Vec_IntSize(vRootLits) );
|
||||
vCexStore = Vec_IntAlloc( 10000 );
|
||||
vCex = Cbs_ReadModel( p );
|
||||
Vec_IntForEachEntry( vRootLits, iLit, i )
|
||||
{
|
||||
Vec_IntClear( vCex );
|
||||
if ( Abc_Lit2Var(iLit) == 0 ) // structural constant root
|
||||
{
|
||||
if ( Abc_LitIsCompl(iLit) ) // const 1: trivial counter-example
|
||||
{
|
||||
Cec_ManSatAddToStore( vCexStore, vCex, i );
|
||||
Vec_StrPush( vStatus, 0 );
|
||||
}
|
||||
else // const 0: proved
|
||||
Vec_StrPush( vStatus, 1 );
|
||||
continue;
|
||||
}
|
||||
clk = Abc_Clock();
|
||||
p->Pars.fUseHighest = 1;
|
||||
p->Pars.fUseLowest = 0;
|
||||
status = Cbs_ManSolve( p, Gia_ObjFromLit(pAig, iLit) );
|
||||
Vec_StrPush( vStatus, (char)status );
|
||||
if ( status == -1 )
|
||||
{
|
||||
p->nSatUndec++;
|
||||
p->nConfUndec += p->Pars.nBTThis;
|
||||
Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout
|
||||
p->timeSatUndec += Abc_Clock() - clk;
|
||||
continue;
|
||||
}
|
||||
if ( status == 1 )
|
||||
{
|
||||
p->nSatUnsat++;
|
||||
p->nConfUnsat += p->Pars.nBTThis;
|
||||
p->timeSatUnsat += Abc_Clock() - clk;
|
||||
continue;
|
||||
}
|
||||
p->nSatSat++;
|
||||
p->nConfSat += p->Pars.nBTThis;
|
||||
Cec_ManSatAddToStore( vCexStore, vCex, i );
|
||||
p->timeSatSat += Abc_Clock() - clk;
|
||||
}
|
||||
p->nSatTotal = Vec_IntSize( vRootLits );
|
||||
p->timeTotal = Abc_Clock() - clkTotal;
|
||||
if ( fVerbose )
|
||||
Cbs_ManSatPrintStats( p );
|
||||
// manager is resident: caller (Cec_DynSrm) owns its lifetime
|
||||
*pvStatus = vStatus;
|
||||
return vCexStore;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
@ -1140,4 +1312,3 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,117 @@
|
|||
#ifndef ABC__aig__gia__giaCSatP_h
|
||||
#define ABC__aig__gia__giaCSatP_h
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gia.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
|
||||
typedef struct CbsP_Par_t_ CbsP_Par_t;
|
||||
struct CbsP_Par_t_
|
||||
{
|
||||
// conflict limits
|
||||
int nBTLimit; // limit on the number of conflicts
|
||||
int nJustLimit; // limit on the size of justification queue
|
||||
// current parameters
|
||||
int nBTThis; // number of conflicts
|
||||
int nBTThisNc; // number of conflicts
|
||||
int nJustThis; // max size of the frontier
|
||||
int nBTTotal; // total number of conflicts
|
||||
int nJustTotal; // total size of the frontier
|
||||
// decision heuristics
|
||||
int fUseHighest; // use node with the highest ID
|
||||
int fUseLowest; // use node with the highest ID
|
||||
int fUseMaxFF; // use node with the largest fanin fanout
|
||||
// other
|
||||
int fVerbose;
|
||||
int fUseProved;
|
||||
|
||||
// statistics
|
||||
int nJscanThis;
|
||||
int nRscanThis;
|
||||
int nPropThis;
|
||||
int maxJscanUndec;
|
||||
int maxRscanUndec;
|
||||
int maxPropUndec;
|
||||
int maxJscanSolved;
|
||||
int maxRscanSolved;
|
||||
int maxPropSolved;
|
||||
int nSat, nUnsat, nUndec;
|
||||
long accJscanSat;
|
||||
long accJscanUnsat;
|
||||
long accJscanUndec;
|
||||
long accRscanSat;
|
||||
long accRscanUnsat;
|
||||
long accRscanUndec;
|
||||
long accPropSat;
|
||||
long accPropUnsat;
|
||||
long accPropUndec;
|
||||
|
||||
// other limits
|
||||
int nJscanLimit;
|
||||
int nRscanLimit;
|
||||
int nPropLimit;
|
||||
};
|
||||
|
||||
typedef struct CbsP_Que_t_ CbsP_Que_t;
|
||||
struct CbsP_Que_t_
|
||||
{
|
||||
int iHead; // beginning of the queue
|
||||
int iTail; // end of the queue
|
||||
int nSize; // allocated size
|
||||
Gia_Obj_t ** pData; // nodes stored in the queue
|
||||
};
|
||||
|
||||
typedef struct CbsP_Man_t_ CbsP_Man_t;
|
||||
struct CbsP_Man_t_
|
||||
{
|
||||
CbsP_Par_t Pars; // parameters
|
||||
Gia_Man_t * pAig; // AIG manager
|
||||
CbsP_Que_t pProp; // propagation queue
|
||||
CbsP_Que_t pJust; // justification queue
|
||||
CbsP_Que_t pClauses; // clause queue
|
||||
Gia_Obj_t ** pIter; // iterator through clause vars
|
||||
Vec_Int_t * vLevReas; // levels and decisions
|
||||
Vec_Int_t * vValue;
|
||||
Vec_Int_t * vModel; // satisfying assignment
|
||||
Vec_Ptr_t * vTemp; // temporary storage
|
||||
// SAT calls statistics
|
||||
int nSatUnsat; // the number of proofs
|
||||
int nSatSat; // the number of failure
|
||||
int nSatUndec; // the number of timeouts
|
||||
int nSatTotal; // the number of calls
|
||||
// conflicts
|
||||
int nConfUnsat; // conflicts in unsat problems
|
||||
int nConfSat; // conflicts in sat problems
|
||||
int nConfUndec; // conflicts in undec problems
|
||||
// runtime stats
|
||||
abctime timeSatUnsat; // unsat
|
||||
abctime timeSatSat; // sat
|
||||
abctime timeSatUndec; // undecided
|
||||
abctime timeTotal; // total runtime
|
||||
};
|
||||
|
||||
CbsP_Man_t * CbsP_ManAlloc( Gia_Man_t * pGia );
|
||||
void CbsP_ManStop( CbsP_Man_t * p );
|
||||
void CbsP_ManSatPrintStats( CbsP_Man_t * p );
|
||||
void CbsP_PrintRecord( CbsP_Par_t * pPars );
|
||||
int CbsP_ManSolve2( CbsP_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
|
||||
|
||||
#define CBS_UNSAT 1
|
||||
#define CBS_SAT 0
|
||||
#define CBS_UNDEC -1
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -83,6 +83,7 @@ struct Tas_Man_t_
|
|||
{
|
||||
Tas_Par_t Pars; // parameters
|
||||
Gia_Man_t * pAig; // AIG manager
|
||||
int nSyncedObjs; // pAig objects already prepped (Value/marks/refs) for resident reuse
|
||||
Tas_Que_t pProp; // propagation queue
|
||||
Tas_Que_t pJust; // justification queue
|
||||
Tas_Que_t pClauses; // clause queue
|
||||
|
|
@ -90,6 +91,9 @@ struct Tas_Man_t_
|
|||
Vec_Int_t * vLevReas; // levels and decisions
|
||||
Vec_Int_t * vModel; // satisfying assignment
|
||||
Vec_Ptr_t * vTemp; // temporary storage
|
||||
Vec_Int_t * vOutLits; // optional endpoint literals to sample before cancel
|
||||
Vec_Int_t * vOutVals; // optional endpoint values by output
|
||||
int iOutVal; // current output whose endpoints are sampled
|
||||
// watched clauses
|
||||
Tas_Sto_t pStore; // storage for watched clauses
|
||||
int * pWatches; // watched lists for each literal
|
||||
|
|
@ -308,6 +312,29 @@ static inline void Tas_ManSaveModel( Tas_Man_t * p, Vec_Int_t * vCex )
|
|||
}
|
||||
}
|
||||
|
||||
static inline int Tas_ManLitValue( Tas_Man_t * p, int iLit )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
if ( iLit < 0 )
|
||||
return -1;
|
||||
if ( Abc_Lit2Var(iLit) == 0 )
|
||||
return Abc_LitIsCompl(iLit);
|
||||
pObj = Gia_ManObj( p->pAig, Abc_Lit2Var(iLit) );
|
||||
if ( !Tas_VarIsAssigned(pObj) )
|
||||
return -1;
|
||||
return Tas_VarValue(pObj) ^ Abc_LitIsCompl(iLit);
|
||||
}
|
||||
|
||||
static inline void Tas_ManSaveOutVals( Tas_Man_t * p, Vec_Int_t * vOutLits, Vec_Int_t * vOutVals, int Out )
|
||||
{
|
||||
if ( vOutLits == NULL || vOutVals == NULL )
|
||||
return;
|
||||
if ( 2*Out + 1 >= Vec_IntSize(vOutLits) )
|
||||
return;
|
||||
Vec_IntWriteEntry( vOutVals, 2*Out, Tas_ManLitValue( p, Vec_IntEntry(vOutLits, 2*Out) ) );
|
||||
Vec_IntWriteEntry( vOutVals, 2*Out + 1, Tas_ManLitValue( p, Vec_IntEntry(vOutLits, 2*Out + 1) ) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -1380,7 +1407,10 @@ int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 )
|
|||
if ( pObj2 && !Tas_VarIsAssigned(Gia_Regular(pObj2)) )
|
||||
Tas_ManAssign( p, pObj2, 0, NULL, NULL );
|
||||
if ( !Tas_ManSolve_rec(p, 0) && !Tas_ManCheckLimits(p) )
|
||||
{
|
||||
Tas_ManSaveModel( p, p->vModel );
|
||||
Tas_ManSaveOutVals( p, p->vOutLits, p->vOutVals, p->iOutVal );
|
||||
}
|
||||
else
|
||||
RetValue = 1;
|
||||
Tas_ManCancelUntil( p, 0 );
|
||||
|
|
@ -1514,14 +1544,14 @@ void Tas_ManSatPrintStats( Tas_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose )
|
||||
Vec_Int_t * Tas_ManSolveMiterNcOutVals( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose, Vec_Int_t * vOutLits, Vec_Int_t ** pvOutVals )
|
||||
{
|
||||
extern void Gia_ManCollectTest( Gia_Man_t * pAig );
|
||||
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
|
||||
Tas_Man_t * p;
|
||||
Vec_Int_t * vCex, * vVisit, * vCexStore;
|
||||
Tas_Man_t * p;
|
||||
Vec_Int_t * vCex, * vVisit, * vCexStore, * vOutVals = NULL;
|
||||
Vec_Str_t * vStatus;
|
||||
Gia_Obj_t * pRoot;//, * pRootCopy;
|
||||
Gia_Obj_t * pRoot;//, * pRootCopy;
|
||||
// Gia_Man_t * pAigCopy = Gia_ManDup( pAig ), * pAigTemp;
|
||||
|
||||
int i, status;
|
||||
|
|
@ -1540,6 +1570,12 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
|||
// create resulting data-structures
|
||||
vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
|
||||
vCexStore = Vec_IntAlloc( 10000 );
|
||||
if ( pvOutVals )
|
||||
{
|
||||
*pvOutVals = NULL;
|
||||
if ( vOutLits )
|
||||
vOutVals = Vec_IntStartFull( 2 * Gia_ManPoNum(pAig) );
|
||||
}
|
||||
vVisit = Vec_IntAlloc( 100 );
|
||||
vCex = Tas_ReadModel( p );
|
||||
// solve for each output
|
||||
|
|
@ -1567,7 +1603,13 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
|||
// p->Pars.fUseActive = 1;
|
||||
p->Pars.fUseHighest = 1;
|
||||
p->Pars.fUseLowest = 0;
|
||||
p->vOutLits = vOutLits;
|
||||
p->vOutVals = vOutVals;
|
||||
p->iOutVal = i;
|
||||
status = Tas_ManSolve( p, Gia_ObjChild0(pRoot), NULL );
|
||||
p->vOutLits = NULL;
|
||||
p->vOutVals = NULL;
|
||||
p->iOutVal = -1;
|
||||
// printf( "\n" );
|
||||
/*
|
||||
if ( status == -1 )
|
||||
|
|
@ -1621,6 +1663,10 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
|||
// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro );
|
||||
Tas_ManStop( p );
|
||||
*pvStatus = vStatus;
|
||||
if ( pvOutVals )
|
||||
*pvOutVals = vOutVals;
|
||||
else
|
||||
Vec_IntFreeP( &vOutVals );
|
||||
|
||||
// printf( "Total number of cex literals = %d. (Ave = %d)\n",
|
||||
// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat,
|
||||
|
|
@ -1628,6 +1674,11 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
|||
return vCexStore;
|
||||
}
|
||||
|
||||
Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose )
|
||||
{
|
||||
return Tas_ManSolveMiterNcOutVals( pAig, nConfs, pvStatus, fVerbose, NULL, NULL );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Packs patterns into array of simulation info.]
|
||||
|
|
@ -1778,13 +1829,148 @@ void Tas_ManSolveMiterNc2( Gia_Man_t * pAig, int nConfs, Gia_Man_t * pAigOld, Ve
|
|||
Tas_ManSatPrintStats( p );
|
||||
Tas_ManStop( p );
|
||||
Vec_PtrFree( vPres );
|
||||
Vec_StrFree( vStatus );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the conflict limit.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Tas_ManSetConflictNum( Tas_Man_t * p, int Num )
|
||||
{
|
||||
p->Pars.nBTLimit = Num;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Syncs newly appended pAig objects for resident reuse.]
|
||||
|
||||
Description [Prepares objects appended since the last sync so the
|
||||
persistent solver can reuse the same manager across rounds. Mirrors
|
||||
Cbs_ManSyncCore but also resizes the TAS-specific watched-literal and
|
||||
activity arrays.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Tas_ManSyncCore( Tas_Man_t * p )
|
||||
{
|
||||
Gia_Man_t * pAig = p->pAig;
|
||||
Gia_Obj_t * pObj;
|
||||
int i, nObjs = Gia_ManObjNum( pAig );
|
||||
assert( p->nSyncedObjs <= nObjs );
|
||||
if ( p->nSyncedObjs == nObjs )
|
||||
return;
|
||||
pAig->pRefs = ABC_REALLOC( int, pAig->pRefs, nObjs );
|
||||
memset( pAig->pRefs + p->nSyncedObjs, 0, sizeof(int) * (nObjs - p->nSyncedObjs) );
|
||||
p->pWatches = ABC_REALLOC( int, p->pWatches, 2 * nObjs );
|
||||
memset( p->pWatches + 2 * p->nSyncedObjs, 0, sizeof(int) * 2 * (nObjs - p->nSyncedObjs) );
|
||||
p->pActivity = ABC_REALLOC( float, p->pActivity, nObjs );
|
||||
memset( p->pActivity + p->nSyncedObjs, 0, sizeof(float) * (nObjs - p->nSyncedObjs) );
|
||||
for ( i = p->nSyncedObjs; i < nObjs; i++ )
|
||||
{
|
||||
pObj = Gia_ManObj( pAig, i );
|
||||
pObj->fMark0 = pObj->fMark1 = 0;
|
||||
pObj->Value = ~0;
|
||||
pObj->fPhase = 0;
|
||||
if ( Gia_ObjIsAnd(pObj) )
|
||||
{
|
||||
pAig->pRefs[Gia_ObjFaninId0(pObj, i)]++;
|
||||
pAig->pRefs[Gia_ObjFaninId1(pObj, i)]++;
|
||||
}
|
||||
}
|
||||
p->nSyncedObjs = nObjs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Solves a set of root literals directly on a persistent AIG.]
|
||||
|
||||
Description [Same prover as Tas_ManSolveMiterNc, but each problem is a root
|
||||
literal of p->pAig (no CO needed) instead of a CO of a freshly built view, and
|
||||
the manager is resident: it is allocated once on the persistent COless pCore
|
||||
and reused across rounds, only Tas_ManSyncCore-ing the objects appended since
|
||||
the last call. Output index i corresponds to vRootLits[i]; vCexStore / vStatus
|
||||
format matches Tas_ManSolveMiterNc. CEX is saved by CioId, which on pCore
|
||||
equals the view's CI numbering.]
|
||||
|
||||
SideEffects [Prepares newly appended objects via Tas_ManSyncCore.]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Tas_ManSolveRoots( Tas_Man_t * p, Vec_Int_t * vRootLits, Vec_Str_t ** pvStatus, int fVerbose )
|
||||
{
|
||||
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
|
||||
Gia_Man_t * pAig = p->pAig;
|
||||
Vec_Int_t * vCex, * vCexStore;
|
||||
Vec_Str_t * vStatus;
|
||||
int i, iLit, status;
|
||||
abctime clk, clkTotal = Abc_Clock();
|
||||
assert( Gia_ManRegNum(pAig) == 0 );
|
||||
Tas_ManSyncCore( p ); // prep only objects appended since the last solve
|
||||
vStatus = Vec_StrAlloc( Vec_IntSize(vRootLits) );
|
||||
vCexStore = Vec_IntAlloc( 10000 );
|
||||
vCex = Tas_ReadModel( p );
|
||||
Vec_IntForEachEntry( vRootLits, iLit, i )
|
||||
{
|
||||
Vec_IntClear( vCex );
|
||||
if ( Abc_Lit2Var(iLit) == 0 ) // structural constant root
|
||||
{
|
||||
if ( Abc_LitIsCompl(iLit) ) // const 1: trivial counter-example
|
||||
{
|
||||
Cec_ManSatAddToStore( vCexStore, vCex, i );
|
||||
Vec_StrPush( vStatus, 0 );
|
||||
}
|
||||
else // const 0: proved
|
||||
Vec_StrPush( vStatus, 1 );
|
||||
continue;
|
||||
}
|
||||
clk = Abc_Clock();
|
||||
p->Pars.fUseHighest = 1;
|
||||
p->Pars.fUseLowest = 0;
|
||||
status = Tas_ManSolve( p, Gia_ObjFromLit(pAig, iLit), NULL );
|
||||
Vec_StrPush( vStatus, (char)status );
|
||||
if ( status == -1 )
|
||||
{
|
||||
p->nSatUndec++;
|
||||
p->nConfUndec += p->Pars.nBTThis;
|
||||
Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout
|
||||
p->timeSatUndec += Abc_Clock() - clk;
|
||||
continue;
|
||||
}
|
||||
if ( status == 0 )
|
||||
{
|
||||
p->nSatSat++;
|
||||
p->nConfSat += p->Pars.nBTThis;
|
||||
Cec_ManSatAddToStore( vCexStore, vCex, i );
|
||||
p->timeSatSat += Abc_Clock() - clk;
|
||||
continue;
|
||||
}
|
||||
assert( status == 1 );
|
||||
p->nSatUnsat++;
|
||||
p->nConfUnsat += p->Pars.nBTThis;
|
||||
p->timeSatUnsat += Abc_Clock() - clk;
|
||||
}
|
||||
p->nSatTotal += Vec_IntSize(vRootLits);
|
||||
p->timeTotal += Abc_Clock() - clkTotal;
|
||||
*pvStatus = vStatus;
|
||||
return vCexStore;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ void Gia_ManCounterExampleValueStart( Gia_Man_t * pGia, Abc_Cex_t * pCex )
|
|||
pGia->pData2 = ABC_CALLOC( unsigned, Abc_BitWordNum( (pCex->iFrame + 1) * Gia_ManObjNum(pGia) ) );
|
||||
// the register values in the counter-example should be zero
|
||||
Gia_ManForEachRo( pGia, pObj, k )
|
||||
assert( Abc_InfoHasBit(pCex->pData, iBit++) == 0 );
|
||||
assert( Abc_InfoHasBit(pCex->pData, iBit) == 0 ), iBit++;
|
||||
// iterate through the timeframes
|
||||
nObjs = Gia_ManObjNum(pGia);
|
||||
for ( i = 0; i <= pCex->iFrame; i++ )
|
||||
|
|
|
|||
|
|
@ -42,42 +42,6 @@ extern int Gia_ManFactorNode( Gia_Man_t * p, char * pSop, Vec_Int_t * vLeaves );
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Gia_GetFakeNames( int nNames )
|
||||
{
|
||||
Vec_Ptr_t * vNames;
|
||||
char Buffer[5];
|
||||
int i;
|
||||
|
||||
vNames = Vec_PtrAlloc( nNames );
|
||||
for ( i = 0; i < nNames; i++ )
|
||||
{
|
||||
if ( nNames < 26 )
|
||||
{
|
||||
Buffer[0] = 'a' + i;
|
||||
Buffer[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer[0] = 'a' + i%26;
|
||||
Buffer[1] = '0' + i/26;
|
||||
Buffer[2] = 0;
|
||||
}
|
||||
Vec_PtrPush( vNames, Extra_UtilStrsav(Buffer) );
|
||||
}
|
||||
return vNames;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -378,11 +342,11 @@ Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose )
|
|||
Dsd_Decompose( pManDsd, (DdNode **)Vec_PtrArray(vFuncs), Vec_PtrSize(vFuncs) );
|
||||
if ( fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vNamesCi = Gia_GetFakeNames( Gia_ManCiNum(p) );
|
||||
Vec_Ptr_t * vNamesCo = Gia_GetFakeNames( Gia_ManCoNum(p) );
|
||||
Vec_Ptr_t * vNamesCi = Gia_GetFakeNames( Gia_ManCiNum(p), 0 );
|
||||
Vec_Ptr_t * vNamesCo = Gia_GetFakeNames( Gia_ManCoNum(p), 1 );
|
||||
char ** ppNamesCi = (char **)Vec_PtrArray( vNamesCi );
|
||||
char ** ppNamesCo = (char **)Vec_PtrArray( vNamesCo );
|
||||
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, 0, -1 );
|
||||
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, 0, -1, 0 );
|
||||
Vec_PtrFreeFree( vNamesCi );
|
||||
Vec_PtrFreeFree( vNamesCo );
|
||||
}
|
||||
|
|
@ -404,6 +368,145 @@ void Gia_ManCollapseTestTest( Gia_Man_t * p )
|
|||
Gia_ManStop( pNew );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManPrintDsdOne( Dsd_Manager_t * pManDsd, int Output, int OffSet )
|
||||
{
|
||||
Vec_Str_t * vStr = Vec_StrAlloc( 100 );
|
||||
Dsd_TreePrint4( vStr, pManDsd, Output );
|
||||
for ( int i = 0; i < OffSet; i++ )
|
||||
printf( " " );
|
||||
printf( "Supp %2d nDsd %2d %s\n", Dsd_TreeSuppSize(pManDsd, Output), Dsd_TreeNonDsdMax(pManDsd, Output), Vec_StrArray(vStr) );
|
||||
Vec_StrFree( vStr );
|
||||
fflush( stdout );
|
||||
}
|
||||
void Gia_ManPrintDsd( Dsd_Manager_t * pManDsd, int Output, int nOutputs, int OffSet )
|
||||
{
|
||||
if ( Output == -1 )
|
||||
{
|
||||
for ( int i = 0; i < nOutputs; i++ )
|
||||
Gia_ManPrintDsdOne( pManDsd, i, OffSet );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( Output >= 0 && Output < nOutputs );
|
||||
Gia_ManPrintDsdOne( pManDsd, Output, OffSet );
|
||||
}
|
||||
}
|
||||
|
||||
void Gia_ManCheckDsd( Gia_Man_t * p, int OffSet, int fVerbose )
|
||||
{
|
||||
DdManager * dd;
|
||||
Dsd_Manager_t * pManDsd;
|
||||
Vec_Ptr_t * vFuncs;
|
||||
dd = Cudd_Init( Gia_ManCiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
|
||||
Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
|
||||
vFuncs = Gia_ManCollapse( p, dd, 10000, 0 );
|
||||
Cudd_AutodynDisable( dd );
|
||||
if ( vFuncs == NULL )
|
||||
{
|
||||
Extra_StopManager( dd );
|
||||
return;
|
||||
}
|
||||
pManDsd = Dsd_ManagerStart( dd, Gia_ManCiNum(p), 0 );
|
||||
if ( pManDsd == NULL )
|
||||
{
|
||||
Gia_ManCollapseDeref( dd, vFuncs );
|
||||
Cudd_Quit( dd );
|
||||
return;
|
||||
}
|
||||
Dsd_Decompose( pManDsd, (DdNode **)Vec_PtrArray(vFuncs), Vec_PtrSize(vFuncs) );
|
||||
|
||||
if ( fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vNamesCi = Gia_GetFakeNames( Gia_ManCiNum(p), 0 );
|
||||
Vec_Ptr_t * vNamesCo = Gia_GetFakeNames( Gia_ManCoNum(p), 1 );
|
||||
char ** ppNamesCi = (char **)Vec_PtrArray( vNamesCi );
|
||||
char ** ppNamesCo = (char **)Vec_PtrArray( vNamesCo );
|
||||
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, 0, -1, OffSet );
|
||||
Vec_PtrFreeFree( vNamesCi );
|
||||
Vec_PtrFreeFree( vNamesCo );
|
||||
}
|
||||
else
|
||||
Gia_ManPrintDsd( pManDsd, 0, Vec_PtrSize(vFuncs), 0 );
|
||||
|
||||
Dsd_ManagerStop( pManDsd );
|
||||
Gia_ManCollapseDeref( dd, vFuncs );
|
||||
Extra_StopManager( dd );
|
||||
}
|
||||
|
||||
Vec_Ptr_t * Gia_ManRecurDsdCof( DdManager * dd, Vec_Ptr_t * vFuncs, int iVar )
|
||||
{
|
||||
Vec_Ptr_t * vNew = Vec_PtrAlloc( 2 * Vec_PtrSize(vFuncs) ); DdNode * bFunc; int i;
|
||||
Vec_PtrForEachEntry( DdNode *, vFuncs, bFunc, i ) {
|
||||
DdNode * bCof0 = Cudd_Cofactor( dd, bFunc, Cudd_Not(Cudd_bddIthVar(dd, iVar)) ); Cudd_Ref( bCof0 );
|
||||
DdNode * bCof1 = Cudd_Cofactor( dd, bFunc, Cudd_bddIthVar(dd, iVar) ); Cudd_Ref( bCof1 );
|
||||
Vec_PtrPush( vNew, bCof0 );
|
||||
Vec_PtrPush( vNew, bCof1 );
|
||||
}
|
||||
return vNew;
|
||||
}
|
||||
void Gia_ManRecurDsd( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
DdManager * dd;
|
||||
Dsd_Manager_t * pManDsd;
|
||||
Vec_Ptr_t * vFuncs, * vAux;
|
||||
dd = Cudd_Init( Gia_ManCiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
|
||||
Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
|
||||
vFuncs = Gia_ManCollapse( p, dd, 10000, 0 );
|
||||
Cudd_AutodynDisable( dd );
|
||||
if ( vFuncs == NULL )
|
||||
{
|
||||
Extra_StopManager( dd );
|
||||
return;
|
||||
}
|
||||
pManDsd = Dsd_ManagerStart( dd, Gia_ManCiNum(p), 0 );
|
||||
if ( pManDsd == NULL )
|
||||
{
|
||||
Gia_ManCollapseDeref( dd, vFuncs );
|
||||
Cudd_Quit( dd );
|
||||
return;
|
||||
}
|
||||
Dsd_Decompose( pManDsd, (DdNode **)Vec_PtrArray(vFuncs), Vec_PtrSize(vFuncs) );
|
||||
|
||||
printf( "Function:\n" );
|
||||
Gia_ManPrintDsd( pManDsd, 0, Vec_PtrSize(vFuncs), 0 );
|
||||
|
||||
for ( int i = 0; i < 5 && Dsd_TreeNonDsdMax(pManDsd, -1) > 0; i++ )
|
||||
{
|
||||
int v, iBestV = -1, DsdMin = ABC_INFINITY, SuppMin = ABC_INFINITY;
|
||||
for ( v = 0; v < Gia_ManCiNum(p); v++ )
|
||||
{
|
||||
Vec_Ptr_t * vTemp = Gia_ManRecurDsdCof( dd, vFuncs, v );
|
||||
Dsd_Decompose( pManDsd, (DdNode **)Vec_PtrArray(vTemp), Vec_PtrSize(vTemp) );
|
||||
int DsdCur = Dsd_TreeNonDsdMax( pManDsd, -1 );
|
||||
int SuppCur = Dsd_TreeSuppSize( pManDsd, -1 );
|
||||
if ( DsdMin > DsdCur || (DsdMin == DsdCur && SuppMin > SuppCur) )
|
||||
DsdMin = DsdCur, SuppMin = SuppCur, iBestV = v;
|
||||
Gia_ManCollapseDeref( dd, vTemp );
|
||||
}
|
||||
assert( iBestV >= 0 );
|
||||
vFuncs = Gia_ManRecurDsdCof( dd, vAux = vFuncs, iBestV );
|
||||
Gia_ManCollapseDeref( dd, vAux );
|
||||
printf( "Cofactoring variable %c:\n", (int)(iBestV >= 26 ? 'A' - 26 : 'a') + iBestV );
|
||||
Dsd_Decompose( pManDsd, (DdNode **)Vec_PtrArray(vFuncs), Vec_PtrSize(vFuncs) );
|
||||
Gia_ManPrintDsd( pManDsd, -1, Vec_PtrSize(vFuncs), (i+1)*2 );
|
||||
}
|
||||
|
||||
Dsd_ManagerStop( pManDsd );
|
||||
Gia_ManCollapseDeref( dd, vFuncs );
|
||||
Extra_StopManager( dd );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose )
|
||||
|
|
@ -411,6 +514,14 @@ Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void Gia_ManCheckDsd( Gia_Man_t * p, int OffSet, int fVerbose )
|
||||
{
|
||||
}
|
||||
|
||||
void Gia_ManRecurDsd( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -993,6 +993,97 @@ Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print the matrix.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManDsdMatrix( Gia_Man_t * p, int iIn )
|
||||
{
|
||||
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, j;
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
|
||||
assert( Gia_ManPoNum(p) == 1 );
|
||||
assert( iIn >= 0 && iIn < Gia_ManPiNum(p) );
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
for ( i = 0; i < Gia_ManPiNum(p); i++ ) if ( i != iIn )
|
||||
for ( j = i+1; j < Gia_ManPiNum(p); j++ ) if ( j != iIn )
|
||||
{
|
||||
int pRes[8], k, n;
|
||||
int iLit0 = Gia_ManPi(p, iIn)->Value;
|
||||
int iLit1 = Gia_ManPi(p, i)->Value;
|
||||
int iLit2 = Gia_ManPi(p, j)->Value;
|
||||
for ( k = 0; k < 8; k++ )
|
||||
{
|
||||
Gia_ManPi(p, iIn)->Value = k & 1;
|
||||
Gia_ManPi(p, i)->Value = (k >> 1) & 1;
|
||||
Gia_ManPi(p, j)->Value = (k >> 2) & 1;
|
||||
Gia_ManForEachAnd( p, pObj, n )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
pRes[k] = Gia_ObjFanin0Copy(Gia_ManPo(p, 0));
|
||||
}
|
||||
Gia_ManPi(p, iIn)->Value = iLit0;
|
||||
Gia_ManPi(p, i)->Value = iLit1;
|
||||
Gia_ManPi(p, j)->Value = iLit2;
|
||||
for ( k = 0; k < 4; k++ )
|
||||
pRes[k] = Gia_ManHashXor( pNew, pRes[2*k], pRes[2*k+1] );
|
||||
Vec_IntPush( vRes, Gia_ManHashXor(pNew, Gia_ManHashAnd(pNew, pRes[0], pRes[3]), Gia_ManHashAnd(pNew, pRes[1], pRes[2])) );
|
||||
}
|
||||
Vec_IntForEachEntry( vRes, j, i )
|
||||
Gia_ManAppendCo( pNew, j );
|
||||
Vec_IntFree( vRes );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
return pNew;
|
||||
}
|
||||
void Gia_ManPrintDsdMatrix( Gia_Man_t * p, int iIn )
|
||||
{
|
||||
extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
|
||||
Gia_Man_t * pNew = Gia_ManDsdMatrix( p, iIn ); int i, j, fFirst = 1, Count = 0;
|
||||
Gia_Man_t * pSweep = Cec4_ManSimulateTest3( pNew, 0, 0 );
|
||||
Gia_ManStop( pNew );
|
||||
printf( "%4c : ", ' ' );
|
||||
for ( j = 0; j < Gia_ManPiNum(p); j++ )
|
||||
printf( "%4d", j );
|
||||
printf( "\n" );
|
||||
for ( i = 0; i < Gia_ManPiNum(p); i++, printf("\n"), fFirst = 1 )
|
||||
for ( j = 0; j < Gia_ManPiNum(p); j++ )
|
||||
{
|
||||
if ( fFirst )
|
||||
printf( "%4d : ", i ), fFirst = 0;
|
||||
if ( i == iIn )
|
||||
continue;
|
||||
if ( j == iIn )
|
||||
printf( "%4c", ' ' );
|
||||
else
|
||||
{
|
||||
if ( j > i ) {
|
||||
if ( Gia_ObjFaninLit0p(pSweep, Gia_ManPo(pSweep, Count++)) == 0 )
|
||||
printf( "%4c", '.' );
|
||||
else
|
||||
printf( "%4c", '+' );
|
||||
}
|
||||
else
|
||||
printf( "%4c", ' ' );
|
||||
}
|
||||
}
|
||||
assert( Count == Gia_ManPoNum(pSweep) );
|
||||
Gia_ManStop( pSweep );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "gia.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "misc/vec/vecHsh.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -28,9 +29,9 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define GIA_MAX_CUTSIZE 8
|
||||
#define GIA_MAX_CUTNUM 51
|
||||
#define GIA_MAX_TT_WORDS ((GIA_MAX_CUTSIZE > 6) ? 1 << (GIA_MAX_CUTSIZE-6) : 1)
|
||||
#define GIA_MAX_CUTSIZE 14
|
||||
#define GIA_MAX_CUTNUM 257
|
||||
#define GIA_MAX_TT_WORDS ((GIA_MAX_CUTSIZE > 6) ? 1 << (GIA_MAX_CUTSIZE-6) : 1)
|
||||
|
||||
#define GIA_CUT_NO_LEAF 0xF
|
||||
|
||||
|
|
@ -44,6 +45,7 @@ struct Gia_Cut_t_
|
|||
unsigned nTreeLeaves : 28; // tree leaves
|
||||
unsigned nLeaves : 4; // leaf count
|
||||
int pLeaves[GIA_MAX_CUTSIZE]; // leaves
|
||||
float CostF;
|
||||
};
|
||||
|
||||
typedef struct Gia_Sto_t_ Gia_Sto_t;
|
||||
|
|
@ -280,7 +282,7 @@ static inline int Gia_CutSetLastCutIsContained( Gia_Cut_t ** pCuts, int nCuts )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Gia_CutCompare( Gia_Cut_t * pCut0, Gia_Cut_t * pCut1 )
|
||||
static inline int Gia_CutCompare2( Gia_Cut_t * pCut0, Gia_Cut_t * pCut1 )
|
||||
{
|
||||
if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1;
|
||||
if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1;
|
||||
|
|
@ -288,6 +290,14 @@ static inline int Gia_CutCompare( Gia_Cut_t * pCut0, Gia_Cut_t * pCut1 )
|
|||
if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
|
||||
return 0;
|
||||
}
|
||||
static inline int Gia_CutCompare( Gia_Cut_t * pCut0, Gia_Cut_t * pCut1 )
|
||||
{
|
||||
if ( pCut0->CostF > pCut1->CostF ) return -1;
|
||||
if ( pCut0->CostF < pCut1->CostF ) return 1;
|
||||
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
|
||||
if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
|
||||
return 0;
|
||||
}
|
||||
static inline int Gia_CutSetLastCutContains( Gia_Cut_t ** pCuts, int nCuts )
|
||||
{
|
||||
int i, k, fChanges = 0;
|
||||
|
|
@ -431,6 +441,13 @@ static inline int Gia_CutTreeLeaves( Gia_Sto_t * p, Gia_Cut_t * pCut )
|
|||
Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] ) == 1;
|
||||
return Cost;
|
||||
}
|
||||
static inline float Gia_CutGetCost( Gia_Sto_t * p, Gia_Cut_t * pCut )
|
||||
{
|
||||
int i, Cost = 0;
|
||||
for ( i = 0; i < (int)pCut->nLeaves; i++ )
|
||||
Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] );
|
||||
return (float)Cost / Abc_MaxInt(1, pCut->nLeaves);
|
||||
}
|
||||
static inline int Gia_StoPrepareSet( Gia_Sto_t * p, int iObj, int Index )
|
||||
{
|
||||
Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj );
|
||||
|
|
@ -444,6 +461,7 @@ static inline int Gia_StoPrepareSet( Gia_Sto_t * p, int iObj, int Index )
|
|||
pCutTemp->iFunc = pCut[pCut[0]+1];
|
||||
pCutTemp->Sign = Gia_CutGetSign( pCutTemp );
|
||||
pCutTemp->nTreeLeaves = Gia_CutTreeLeaves( p, pCutTemp );
|
||||
pCutTemp->CostF = Gia_CutGetCost( p, pCutTemp );
|
||||
}
|
||||
return pList[0];
|
||||
}
|
||||
|
|
@ -511,6 +529,7 @@ void Gia_StoMergeCuts( Gia_Sto_t * p, int iObj )
|
|||
if ( p->fCutMin && Gia_CutComputeTruth(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) )
|
||||
pCutsR[nCutsR]->Sign = Gia_CutGetSign(pCutsR[nCutsR]);
|
||||
pCutsR[nCutsR]->nTreeLeaves = Gia_CutTreeLeaves( p, pCutsR[nCutsR] );
|
||||
pCutsR[nCutsR]->CostF = Gia_CutGetCost( p, pCutsR[nCutsR] );
|
||||
nCutsR = Gia_CutSetAddCut( pCutsR, nCutsR, nCutNum );
|
||||
}
|
||||
p->CutCount[3] += nCutsR;
|
||||
|
|
@ -630,7 +649,7 @@ void Gia_StoComputeCuts( Gia_Man_t * pGia )
|
|||
printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
|
||||
printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
|
||||
printf( "\n" );
|
||||
printf( "The number of nodes with cut count over the limit (%d cuts) = %d nodes (out of %d). ",
|
||||
printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ",
|
||||
p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
|
||||
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
|
||||
}
|
||||
|
|
@ -671,7 +690,7 @@ Vec_Wec_t * Gia_ManSelectCuts( Vec_Wec_t * vCuts, int nCuts, int nCutSizeMin )
|
|||
Vec_Wec_t * vCutsSel = Vec_WecStart( nCuts );
|
||||
int i; srand( time(NULL) );
|
||||
for ( i = 0; i < nCuts; i++ )
|
||||
while ( !Gia_StoSelectOneCut(vCuts, (rand() | (rand() << 15)) % Vec_WecSize(vCuts), Vec_WecEntry(vCutsSel, i), nCutSizeMin) );
|
||||
while ( !Gia_StoSelectOneCut(vCuts, (int)(((unsigned)rand() | ((unsigned)rand() << 15)) % Vec_WecSize(vCuts)), Vec_WecEntry(vCutsSel, i), nCutSizeMin) );
|
||||
return vCutsSel;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManExtractCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fVerbose0 )
|
||||
|
|
@ -705,7 +724,7 @@ Vec_Wec_t * Gia_ManExtractCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int
|
|||
printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
|
||||
printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
|
||||
printf( "\n" );
|
||||
printf( "The number of nodes with cut count over the limit (%d cuts) = %d nodes (out of %d). ",
|
||||
printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ",
|
||||
p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
|
||||
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
|
||||
}
|
||||
|
|
@ -778,10 +797,777 @@ void Gia_ManExtractTest( Gia_Man_t * pGia )
|
|||
Abc_PrintTime( 0, "Creating windows", Abc_Clock() - clk );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Extract a given number of cuts.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_StoCutPrint( int * pCut )
|
||||
{
|
||||
int v;
|
||||
printf( "{" );
|
||||
for ( v = 1; v <= pCut[0]; v++ )
|
||||
printf( " %d", pCut[v] );
|
||||
printf( " }\n" );
|
||||
}
|
||||
void Gia_StoPrintCuts( Vec_Int_t * vThis, int iObj, int nCutSize )
|
||||
{
|
||||
int i, * pCut;
|
||||
printf( "Cuts of node %d (size = %d):\n", iObj, nCutSize );
|
||||
Sdb_ForEachCut( Vec_IntArray(vThis), pCut, i )
|
||||
if ( !nCutSize || pCut[0] == nCutSize )
|
||||
Gia_StoCutPrint( pCut );
|
||||
}
|
||||
Vec_Wec_t * Gia_ManFilterCuts( Gia_Man_t * pGia, Vec_Wec_t * vStore, int nCutSize, int nCuts )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
Vec_Wec_t * vCutsSel = Vec_WecAlloc( nCuts );
|
||||
Vec_Int_t * vLevel, * vCut = Vec_IntAlloc( 10 );
|
||||
Vec_Wec_t * vCuts = Vec_WecAlloc( 1000 );
|
||||
Hsh_VecMan_t * p = Hsh_VecManStart( 1000 ); int i, s;
|
||||
Vec_WecForEachLevel( vStore, vLevel, i ) if ( Vec_IntSize(vLevel) )
|
||||
{
|
||||
int v, k, * pCut, Value;
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k )
|
||||
{
|
||||
if ( pCut[0] < 2 )
|
||||
continue;
|
||||
|
||||
for ( v = 1; v <= pCut[0]; v++ )
|
||||
if ( pCut[v] < 9 )
|
||||
break;
|
||||
if ( v <= pCut[0] )
|
||||
continue;
|
||||
|
||||
Vec_IntClear( vCut );
|
||||
Vec_IntPushArray( vCut, pCut+1, pCut[0] );
|
||||
Value = Hsh_VecManAdd( p, vCut );
|
||||
if ( Value == Vec_WecSize(vCuts) )
|
||||
{
|
||||
Vec_Int_t * vTemp = Vec_WecPushLevel(vCuts);
|
||||
Vec_IntPush( vTemp, 0 );
|
||||
Vec_IntAppend( vTemp, vCut );
|
||||
}
|
||||
Vec_IntAddToEntry( Vec_WecEntry(vCuts, Value), 0, 1 );
|
||||
}
|
||||
}
|
||||
printf( "Collected cuts = %d.\n", Vec_WecSize(vCuts) );
|
||||
for ( s = 3; s <= nCutSize; s++ )
|
||||
Vec_WecForEachLevel( vCuts, vLevel, i )
|
||||
if ( Vec_IntSize(vLevel) - 1 == s )
|
||||
{
|
||||
int * pCut = Vec_IntEntryP(vLevel, 1);
|
||||
int u, v, Value;
|
||||
for ( u = 0; u < s; u++ )
|
||||
{
|
||||
Vec_IntClear( vCut );
|
||||
for ( v = 0; v < s; v++ ) if ( v != u )
|
||||
Vec_IntPush( vCut, pCut[v] );
|
||||
assert( Vec_IntSize(vCut) == s-1 );
|
||||
Value = Hsh_VecManAdd( p, vCut );
|
||||
if ( Value < Vec_WecSize(vCuts) )
|
||||
Vec_IntAddToEntry( vLevel, 0, Vec_IntEntry(Vec_WecEntry(vCuts, Value), 0) );
|
||||
}
|
||||
}
|
||||
Hsh_VecManStop( p );
|
||||
Vec_IntFree( vCut );
|
||||
// collect
|
||||
Vec_WecSortByFirstInt( vCuts, 1 );
|
||||
Vec_WecForEachLevelStop( vCuts, vLevel, i, Abc_MinInt(Vec_WecSize(vCuts), nCuts) )
|
||||
Vec_IntAppend( Vec_WecPushLevel(vCutsSel), vLevel );
|
||||
Abc_PrintTime( 0, "Cut filtering time", Abc_Clock() - clkStart );
|
||||
return vCutsSel;
|
||||
}
|
||||
int Gia_ManCountRefs( Gia_Man_t * pGia, Vec_Int_t * vLevel )
|
||||
{
|
||||
int i, iObj, nRefs = 0;
|
||||
Vec_IntForEachEntry( vLevel, iObj, i )
|
||||
nRefs += Gia_ObjRefNumId(pGia, iObj);
|
||||
return nRefs;
|
||||
}
|
||||
Vec_Wrd_t * Gia_ManGenSims( Gia_Man_t * pGia )
|
||||
{
|
||||
Vec_Wrd_t * vSims;
|
||||
Vec_WrdFreeP( &pGia->vSimsPi );
|
||||
pGia->vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(pGia) );
|
||||
vSims = Gia_ManSimPatSim( pGia );
|
||||
return vSims;
|
||||
}
|
||||
int Gia_ManFindSatDcs( Gia_Man_t * pGia, Vec_Wrd_t * vSims, Vec_Int_t * vLevel )
|
||||
{
|
||||
int nWords = Vec_WrdSize(pGia->vSimsPi) / Gia_ManCiNum(pGia);
|
||||
int i, w, iObj, Res = 0, Pres[256] = {0}, nMints = 1 << Vec_IntSize(vLevel);
|
||||
for ( w = 0; w < 64*nWords; w++ )
|
||||
{
|
||||
int iInMint = 0;
|
||||
Vec_IntForEachEntry( vLevel, iObj, i )
|
||||
if ( Abc_TtGetBit( Vec_WrdEntryP(vSims, iObj*nWords), w ) )
|
||||
iInMint |= 1 << i;
|
||||
Pres[iInMint]++;
|
||||
}
|
||||
for ( i = 0; i < nMints; i++ )
|
||||
Res += Pres[i] == 0;
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
int Gia_ManCollectCutDivs( Gia_Man_t * p, Vec_Int_t * vIns )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, Res = 0;
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
|
||||
Vec_IntSort( vIns, 0 );
|
||||
|
||||
Vec_IntPush( vRes, 0 );
|
||||
Vec_IntAppend( vRes, vIns );
|
||||
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachObjVec( vIns, p, pObj, i )
|
||||
Gia_ObjSetTravIdCurrent( p, pObj );
|
||||
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
continue;
|
||||
else if ( Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(pObj)) && Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin1(pObj)) )
|
||||
{
|
||||
if ( !Gia_ObjIsTravIdPrevious(p, pObj) )
|
||||
Vec_IntPush( vRes, i );
|
||||
Gia_ObjSetTravIdCurrent( p, pObj );
|
||||
}
|
||||
// printf( "Divisors: " );
|
||||
// Vec_IntPrint( vRes );
|
||||
Res = Vec_IntSize(vRes);
|
||||
Vec_IntFree( vRes );
|
||||
return Res;
|
||||
}
|
||||
|
||||
void Gia_ManConsiderCuts( Gia_Man_t * pGia, Vec_Wec_t * vCuts )
|
||||
{
|
||||
Vec_Wrd_t * vSims = Gia_ManGenSims( pGia );
|
||||
Vec_Int_t * vLevel; int i;
|
||||
Gia_ManCreateRefs( pGia );
|
||||
Vec_WecForEachLevel( vCuts, vLevel, i )
|
||||
{
|
||||
printf( "Cut %3d ", i );
|
||||
printf( "Ref = %3d : ", Vec_IntEntry(vLevel, 0) );
|
||||
|
||||
Vec_IntShift( vLevel, 1 );
|
||||
printf( "Ref = %3d : ", Gia_ManCountRefs(pGia, vLevel) );
|
||||
printf( "SDC = %3d : ", Gia_ManFindSatDcs(pGia, vSims, vLevel) );
|
||||
printf( "Div = %3d : ", Gia_ManCollectCutDivs(pGia, vLevel) );
|
||||
Vec_IntPrint( vLevel );
|
||||
Vec_IntShift( vLevel, -1 );
|
||||
}
|
||||
Vec_WrdFree( vSims );
|
||||
}
|
||||
|
||||
|
||||
Vec_Wec_t * Gia_ManExploreCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fVerbose0 )
|
||||
{
|
||||
int nCutSize = nCutSize0;
|
||||
int nCutNum = 64;
|
||||
int fCutMin = 0;
|
||||
int fTruthMin = 0;
|
||||
int fVerbose = fVerbose0;
|
||||
Vec_Wec_t * vCutsSel;
|
||||
Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose );
|
||||
Gia_Obj_t * pObj; int i, iObj;
|
||||
assert( nCutSize <= GIA_MAX_CUTSIZE );
|
||||
assert( nCutNum < GIA_MAX_CUTNUM );
|
||||
// prepare references
|
||||
Gia_ManForEachObj( p->pGia, pObj, iObj )
|
||||
Gia_StoRefObj( p, iObj );
|
||||
// compute cuts
|
||||
Gia_StoComputeCutsConst0( p, 0 );
|
||||
Gia_ManForEachCiId( p->pGia, iObj, i )
|
||||
Gia_StoComputeCutsCi( p, iObj );
|
||||
Gia_ManForEachAnd( p->pGia, pObj, iObj )
|
||||
Gia_StoComputeCutsNode( p, iObj );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Running cut computation with CutSize = %d CutNum = %d CutMin = %s TruthMin = %s\n",
|
||||
p->nCutSize, p->nCutNum, p->fCutMin ? "yes":"no", p->fTruthMin ? "yes":"no" );
|
||||
printf( "CutPair = %.0f ", p->CutCount[0] );
|
||||
printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] );
|
||||
printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] );
|
||||
printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
|
||||
printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
|
||||
printf( "\n" );
|
||||
printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ",
|
||||
p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
|
||||
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
|
||||
}
|
||||
vCutsSel = Gia_ManFilterCuts( pGia, p->vCuts, nCutSize0, nCuts0 );
|
||||
//Gia_ManConsiderCuts( pGia, vCutsSel );
|
||||
Gia_StoFree( p );
|
||||
return vCutsSel;
|
||||
}
|
||||
void Gia_ManExploreCutsTest( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fVerbose0 )
|
||||
{
|
||||
Vec_Wec_t * vCutSel = Gia_ManExploreCuts( pGia, nCutSize0, nCuts0, fVerbose0 );
|
||||
Vec_WecPrint( vCutSel, 0 );
|
||||
Vec_WecFree( vCutSel );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Sto_t * Gia_ManMatchCutsInt( Gia_Man_t * pGia, int nCutSize0, int nCutNum0, int fTruth0, int fVerbose0 )
|
||||
{
|
||||
int nCutSize = nCutSize0;
|
||||
int nCutNum = nCutNum0;
|
||||
int fCutMin = fTruth0;
|
||||
int fTruthMin = fTruth0;
|
||||
int fVerbose = fVerbose0;
|
||||
Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose );
|
||||
Gia_Obj_t * pObj; int i, iObj;
|
||||
assert( nCutSize <= GIA_MAX_CUTSIZE );
|
||||
assert( nCutNum < GIA_MAX_CUTNUM );
|
||||
// prepare references
|
||||
Gia_ManForEachObj( p->pGia, pObj, iObj )
|
||||
Gia_StoRefObj( p, iObj );
|
||||
// compute cuts
|
||||
Gia_StoComputeCutsConst0( p, 0 );
|
||||
Gia_ManForEachCiId( p->pGia, iObj, i )
|
||||
Gia_StoComputeCutsCi( p, iObj );
|
||||
Gia_ManForEachAnd( p->pGia, pObj, iObj )
|
||||
Gia_StoComputeCutsNode( p, iObj );
|
||||
if ( p->fVerbose )
|
||||
{
|
||||
printf( "Running cut computation with CutSize = %d CutNum = %d CutMin = %s TruthMin = %s\n",
|
||||
p->nCutSize, p->nCutNum, p->fCutMin ? "yes":"no", p->fTruthMin ? "yes":"no" );
|
||||
printf( "CutPair = %.0f ", p->CutCount[0] );
|
||||
printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] );
|
||||
printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] );
|
||||
printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
|
||||
printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
|
||||
printf( "\n" );
|
||||
printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ",
|
||||
p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
|
||||
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
|
||||
}
|
||||
return p;
|
||||
}
|
||||
int Gia_ManCountSelfCuts( Gia_Man_t * p, Gia_Sto_t * pSto )
|
||||
{
|
||||
Vec_Int_t * vLevel; int i, k, * pCut, nNodes = 0;
|
||||
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
|
||||
Gia_Obj_t * pObj = Gia_ManObj(p, i);
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
continue;
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k )
|
||||
nNodes += pCut[0] == 2 && pCut[1] == Gia_ObjFaninId0p(p, pObj) && pCut[2] == Gia_ObjFaninId1p(p, pObj);
|
||||
}
|
||||
return nNodes;
|
||||
}
|
||||
void Gia_ManEvalCutHashing( Gia_Man_t * p, Gia_Sto_t * pSto )
|
||||
{
|
||||
Hsh_VecMan_t * pHash = Hsh_VecManStart( 100000 );
|
||||
Vec_Int_t vTemp = {0};
|
||||
Vec_Int_t * vLevel; int i, k, * pCut, nBytes = 0, nCuts = 0;
|
||||
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
|
||||
Gia_Obj_t * pObj = Gia_ManObj(p, i);
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
continue;
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) {
|
||||
vTemp.nSize = vTemp.nCap = pCut[0];
|
||||
vTemp.pArray = pCut+1;
|
||||
Hsh_VecManAdd( pHash, &vTemp );
|
||||
nBytes += 4*(pCut[0]+1);
|
||||
nCuts++;
|
||||
}
|
||||
}
|
||||
printf( "Total cuts = %d. Unique = %d. Memory = %.2f MB. With hashing = %.2f MB.\n",
|
||||
nCuts, Hsh_VecSize(pHash), 1.0*nBytes/(1<<20), Hsh_VecManMemory(pHash)/(1<<20) );
|
||||
Hsh_VecManStop( pHash );
|
||||
}
|
||||
void Gia_ManDumpCutsText( Gia_Man_t * p, Gia_Sto_t * pSto, FILE * pFile, int fVerbose, char * pFileName )
|
||||
{
|
||||
Vec_Int_t * vLevel; int i, k, c, * pCut, nCuts = 0, nNodes = 0;
|
||||
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
|
||||
if ( !Gia_ObjIsAnd(Gia_ManObj(p, i)) )
|
||||
continue;
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) {
|
||||
if ( pCut[0] == 1 )
|
||||
continue;
|
||||
fprintf( pFile, "%d ", i );
|
||||
for ( c = 1; c <= pCut[0]; c++ )
|
||||
fprintf( pFile, "%d ", pCut[c] );
|
||||
fprintf( pFile, "1\n" );
|
||||
nCuts++;
|
||||
}
|
||||
nNodes++;
|
||||
}
|
||||
Gia_Obj_t * pObj;
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
fprintf( pFile, "%d %d 0\n", Gia_ObjId(p, pObj), Gia_ObjFaninId0p(p, pObj) );
|
||||
if ( fVerbose )
|
||||
printf( "Dumped %d cuts for %d nodes into text file \"%s\".\n", nCuts, nNodes, pFileName ? pFileName : "stdout" );
|
||||
}
|
||||
void Gia_ManDumpCutsPrint( Gia_Man_t * p, Vec_Int_t * vStore, int nCutSize, int nCutNum )
|
||||
{
|
||||
int o, f, c;
|
||||
int nObjs = Gia_ManObjNum( p );
|
||||
int * pStore = Vec_IntArray( vStore );
|
||||
if ( nCutSize == 0 || nCutNum == 0 )
|
||||
return;
|
||||
for ( o = 0; o < nObjs; o++ ) {
|
||||
Gia_Obj_t * pObj = Gia_ManObj( p, o );
|
||||
int * pNodeStore;
|
||||
if ( !Gia_ObjIsAnd(pObj) && !Gia_ObjIsCo(pObj) )
|
||||
continue;
|
||||
pNodeStore = pStore + o * nCutSize * nCutNum;
|
||||
printf( "Node %d has %d cuts:\n", o, nCutNum );
|
||||
for ( f = 0; f < nCutSize; f++ ) {
|
||||
printf( "Fanin %d:", f );
|
||||
for ( c = 0; c < nCutNum; c++ )
|
||||
printf( " %4d", pNodeStore[f * nCutNum + c] );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
void Gia_ManDumpCutsBin( Gia_Man_t * p, Gia_Sto_t * pSto, FILE * pFile, int nCutSize, int nCutNum, int fVerbose, char * pFileName )
|
||||
{
|
||||
Vec_Int_t * vLevel; int i, k, c, * pCut, Num, RetValue, nCuts = 0, nNodes = 0;
|
||||
Vec_Int_t * vStore = Vec_IntStart( Gia_ManObjNum(p) * nCutSize * nCutNum );
|
||||
int * pStore = Vec_IntArray( vStore );
|
||||
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
|
||||
Gia_Obj_t * pObj = Gia_ManObj(p, i);
|
||||
int CutIndex = 0;
|
||||
int * pNodeStore;
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
continue;
|
||||
pNodeStore = pStore + i * nCutSize * nCutNum;
|
||||
// flatten cuts as [object][leaf][cut], so each leaf spans nCutNum consecutive entries
|
||||
// add the mandatory two-leaf cut composed of the current node's fanins
|
||||
if ( nCutNum > 0 ) {
|
||||
pNodeStore[CutIndex] = Gia_ObjFaninId0p( p, pObj );
|
||||
pNodeStore[nCutNum + CutIndex] = Gia_ObjFaninId1p( p, pObj );
|
||||
CutIndex++;
|
||||
nCuts++;
|
||||
}
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) {
|
||||
if ( pCut[0] == 1 )
|
||||
continue;
|
||||
if ( CutIndex >= nCutNum )
|
||||
break;
|
||||
assert( pCut[0] <= nCutSize );
|
||||
for ( c = 0; c < pCut[0]; c++ )
|
||||
pNodeStore[c * nCutNum + CutIndex] = pCut[c+1];
|
||||
CutIndex++;
|
||||
nCuts++;
|
||||
}
|
||||
nNodes++;
|
||||
}
|
||||
// add unit cuts for primary outputs driven by arbitrary objects (const, PI, or internal node)
|
||||
if ( nCutSize > 0 && nCutNum > 0 ) {
|
||||
Gia_Obj_t * pObj;
|
||||
Gia_ManForEachCo( p, pObj, i ) {
|
||||
int ObjId = Gia_ObjId( p, pObj );
|
||||
int * pNodeStore = pStore + ObjId * nCutSize * nCutNum;
|
||||
pNodeStore[0] = Gia_ObjFaninId0p( p, pObj );
|
||||
nCuts++;
|
||||
}
|
||||
}
|
||||
// the number of dimension
|
||||
Num = 3;
|
||||
RetValue = fwrite( &Num, 4, 1, pFile );
|
||||
assert( RetValue == 1 );
|
||||
// the number of objects
|
||||
Num = Gia_ManObjNum(p);
|
||||
RetValue = fwrite( &Num, 4, 1, pFile );
|
||||
assert( RetValue == 1 );
|
||||
// the cut size
|
||||
Num = nCutSize;
|
||||
RetValue = fwrite( &Num, 4, 1, pFile );
|
||||
assert( RetValue == 1 );
|
||||
// the cut count
|
||||
Num = nCutNum;
|
||||
RetValue = fwrite( &Num, 4, 1, pFile );
|
||||
assert( RetValue == 1 );
|
||||
// the cuts themselves
|
||||
RetValue = fwrite( Vec_IntArray(vStore), 4, Vec_IntSize(vStore), pFile );
|
||||
assert( RetValue == Vec_IntSize(vStore) );
|
||||
if ( fVerbose )
|
||||
printf( "Dumped %d cuts for %d nodes into binary file \"%s\" (%.2f MB).\n", nCuts, nNodes, pFileName, Vec_IntMemory(vStore)/(1<<20) );
|
||||
//Gia_ManDumpCutsPrint( p, vStore, nCutSize, nCutNum );
|
||||
Vec_IntFree( vStore );
|
||||
}
|
||||
void Gia_ManComputeCutsCore( Gia_Man_t * pGia, int nCutSize, int nCutNum, int fTruth, int fVerbose, int fDumpText, int fDumpBin, char * pFileName )
|
||||
{
|
||||
Gia_Sto_t * pSto = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, fTruth, fVerbose );
|
||||
if ( fDumpText ) {
|
||||
FILE * pFile = pFileName ? fopen(pFileName, "wb") : stdout;
|
||||
if ( !pFile ) return;
|
||||
Gia_ManDumpCutsText( pGia, pSto, pFile, fVerbose, pFileName );
|
||||
fclose( pFile );
|
||||
}
|
||||
else if ( fDumpBin ) {
|
||||
FILE * pFile = pFileName ? fopen(pFileName, "wb") : NULL;
|
||||
if ( !pFile ) return;
|
||||
Gia_ManDumpCutsBin( pGia, pSto, pFile, nCutSize, nCutNum, fVerbose, pFileName );
|
||||
fclose( pFile );
|
||||
}
|
||||
//printf( "The number of nodes with self-cuts = %d (out of %d).\n", Gia_ManCountSelfCuts(pGia, pSto), Gia_ManAndNum(pGia) );
|
||||
//Gia_ManEvalCutHashing( pGia, pSto );
|
||||
Gia_StoFree( pSto );
|
||||
}
|
||||
|
||||
Vec_Wec_t * Gia_ManCompute54Cuts( Gia_Man_t * pGia, int fVerbose )
|
||||
{
|
||||
Gia_Sto_t * pSto = Gia_ManMatchCutsInt( pGia, 5, 8, 0, fVerbose );
|
||||
Vec_Wec_t * vRes = Vec_WecAlloc( 1000 );
|
||||
Vec_Int_t * vLevel; int i, k, c, * pCut;
|
||||
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
|
||||
if ( !Gia_ObjIsAnd(Gia_ManObj(pGia, i)) )
|
||||
continue;
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) {
|
||||
if ( pCut[0] != 4 && pCut[0] != 5 )
|
||||
continue;
|
||||
Vec_Int_t * vCut = Vec_WecPushLevel( vRes );
|
||||
for ( c = 1; c <= pCut[0]; c++ )
|
||||
Vec_IntPush( vCut, pCut[c] );
|
||||
Vec_IntPush( vCut, i );
|
||||
}
|
||||
}
|
||||
Gia_StoFree( pSto );
|
||||
return vRes;
|
||||
}
|
||||
void Gia_ManMatchCuts( Vec_Mem_t * vTtMem, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose )
|
||||
{
|
||||
Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, 1, fVerbose );
|
||||
Vec_Int_t * vLevel; int i, j, k, * pCut;
|
||||
Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
|
||||
Vec_Wec_t * vCuts = Vec_WecAlloc( 100 );
|
||||
abctime clkStart = Abc_Clock();
|
||||
assert( Abc_Truth6WordNum(nCutSize) == Vec_MemEntrySize(vTtMem) );
|
||||
Vec_WecForEachLevel( p->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
|
||||
{
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] > 1 )
|
||||
{
|
||||
word * pTruth = Vec_MemReadEntry( p->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
|
||||
int * pSpot = Vec_MemHashLookup( vTtMem, pTruth );
|
||||
if ( *pSpot == -1 )
|
||||
continue;
|
||||
Vec_IntPush( vNodes, i );
|
||||
vLevel = Vec_WecPushLevel( vCuts );
|
||||
Vec_IntPush( vLevel, i );
|
||||
for ( j = 1; j <= pCut[0]; j++ )
|
||||
Vec_IntPush( vLevel, pCut[j] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf( "Nodes with matching cuts: " );
|
||||
Vec_IntPrint( vNodes );
|
||||
if ( Vec_WecSize(vCuts) > 32 )
|
||||
Vec_WecShrink(vCuts, 32);
|
||||
Vec_WecPrint( vCuts, 0 );
|
||||
Vec_WecFree( vCuts );
|
||||
Vec_IntFree( vNodes );
|
||||
Gia_StoFree( p );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "Cut matching time", Abc_Clock() - clkStart );
|
||||
}
|
||||
Vec_Ptr_t * Gia_ManMatchCutsArray( Vec_Ptr_t * vTtMems, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vRes = Vec_PtrAlloc( Vec_PtrSize(vTtMems) );
|
||||
Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, 1, fVerbose );
|
||||
Vec_Int_t * vLevel, * vTemp; int i, k, c, * pCut;
|
||||
abctime clkStart = Abc_Clock();
|
||||
for ( i = 0; i < Vec_PtrSize(vTtMems); i++ )
|
||||
Vec_PtrPush( vRes, Vec_WecAlloc(100) );
|
||||
Vec_WecForEachLevel( p->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
|
||||
{
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] > 1 )
|
||||
{
|
||||
Vec_Mem_t * vTtMem; int m;
|
||||
Vec_PtrForEachEntry( Vec_Mem_t *, vTtMems, vTtMem, m )
|
||||
{
|
||||
word * pTruth = Vec_MemReadEntry( p->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
|
||||
int * pSpot = Vec_MemHashLookup( vTtMem, pTruth );
|
||||
if ( *pSpot == -1 )
|
||||
continue;
|
||||
vTemp = Vec_WecPushLevel( (Vec_Wec_t *)Vec_PtrEntry(vRes, m) );
|
||||
Vec_IntPush( vTemp, i );
|
||||
for ( c = 1; c <= pCut[0]; c++ )
|
||||
Vec_IntPush( vTemp, pCut[c] );
|
||||
}
|
||||
}
|
||||
}
|
||||
Gia_StoFree( p );
|
||||
if ( fVerbose ) {
|
||||
Vec_Wec_t * vCuts;
|
||||
printf( "Detected nodes by type: " );
|
||||
Vec_PtrForEachEntry( Vec_Wec_t *, vRes, vCuts, i )
|
||||
printf( "Type%d = %d ", i, Vec_WecSize(vCuts) );
|
||||
Abc_PrintTime( 1, "Cut matching time", Abc_Clock() - clkStart );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
Vec_Ptr_t * Gia_ManMatchCutsMany( Vec_Mem_t * vTtMem, Vec_Int_t * vMap, int nFuncs, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose )
|
||||
{
|
||||
Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, 1, fVerbose );
|
||||
Vec_Int_t * vLevel; int i, j, k, * pCut;
|
||||
abctime clkStart = Abc_Clock();
|
||||
assert( Abc_Truth6WordNum(nCutSize) == Vec_MemEntrySize(vTtMem) );
|
||||
Vec_Ptr_t * vRes = Vec_PtrAlloc( nFuncs );
|
||||
for ( i = 0; i < nFuncs; i++ )
|
||||
Vec_PtrPush( vRes, Vec_WecAlloc(10) );
|
||||
Vec_WecForEachLevel( p->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
|
||||
{
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] > 1 )
|
||||
{
|
||||
word * pTruth = Vec_MemReadEntry( p->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
|
||||
assert( (pTruth[0] & 1) == 0 );
|
||||
int * pSpot = Vec_MemHashLookup( vTtMem, pTruth );
|
||||
if ( *pSpot == -1 )
|
||||
continue;
|
||||
int iFunc = vMap ? Vec_IntEntry( vMap, *pSpot ) : 0;
|
||||
assert( iFunc < nFuncs );
|
||||
Vec_Wec_t * vCuts = (Vec_Wec_t *)Vec_PtrEntry( vRes, iFunc );
|
||||
vLevel = Vec_WecPushLevel( vCuts );
|
||||
Vec_IntPush( vLevel, i );
|
||||
for ( j = 1; j <= pCut[0]; j++ )
|
||||
Vec_IntPush( vLevel, pCut[j] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
Gia_StoFree( p );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "Cut matching time", Abc_Clock() - clkStart );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Function enumeration.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Wrd_t * Gia_ManCollectCutFuncs( Gia_Man_t * p, int nCutSize, int nCutNum, int fVerbose )
|
||||
{
|
||||
Gia_Sto_t * pSto = Gia_ManMatchCutsInt( p, nCutSize, nCutNum, 1, 0 );
|
||||
Vec_Wrd_t * vFuncs = Vec_WrdAlloc( 1000 ); Vec_Int_t * vLevel; int i, k, * pCut;
|
||||
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] == nCutSize ) {
|
||||
word * pTruth = Vec_MemReadEntry( pSto->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
|
||||
Vec_WrdPush( vFuncs, pTruth[0] );
|
||||
}
|
||||
Gia_StoFree( pSto );
|
||||
if ( fVerbose )
|
||||
printf( "Collected %d cut functions using the AIG with %d nodes.\n", Vec_WrdSize(vFuncs), Gia_ManAndNum(p) );
|
||||
return vFuncs;
|
||||
}
|
||||
Vec_Int_t * Gia_ManCountNpnClasses( Vec_Mem_t * vTtMem, Vec_Int_t * vMap, int nClasses, Vec_Wrd_t * vOrig )
|
||||
{
|
||||
assert( Vec_MemEntryNum(vTtMem) == Vec_IntSize(vMap) );
|
||||
Vec_Int_t * vClassCounts = Vec_IntStart( nClasses ); int i; word Func;
|
||||
Vec_WrdForEachEntry( vOrig, Func, i ) {
|
||||
int * pSpot = Vec_MemHashLookup( vTtMem, &Func );
|
||||
if ( *pSpot == -1 )
|
||||
continue;
|
||||
int iClass = Vec_IntEntry( vMap, *pSpot );
|
||||
if ( iClass == -1 )
|
||||
continue;
|
||||
assert( iClass < Vec_IntSize(vClassCounts) );
|
||||
Vec_IntAddToEntry( vClassCounts, iClass, 1 );
|
||||
}
|
||||
return vClassCounts;
|
||||
}
|
||||
Vec_Wrd_t * Gia_ManMatchFilterClasses( Vec_Mem_t * vTtMem, Vec_Int_t * vMap, Vec_Int_t * vClassCounts, int nNumFuncs, int fVerbose )
|
||||
{
|
||||
int * pPerm = Abc_MergeSortCost( Vec_IntArray(vClassCounts), Vec_IntSize(vClassCounts) );
|
||||
Vec_Wrd_t * vBest = Vec_WrdAlloc( nNumFuncs ); int i, k, Entry;
|
||||
Vec_Int_t * vMapNew = Vec_IntStartFull( Vec_IntSize(vMap) );
|
||||
for ( i = Vec_IntSize(vClassCounts)-1; i >= 0; i-- ) {
|
||||
word Best = ~(word)0;
|
||||
Vec_IntForEachEntry( vMap, Entry, k ) {
|
||||
if ( Entry != pPerm[i] )
|
||||
continue;
|
||||
if ( Best > Vec_MemReadEntry(vTtMem, k)[0] )
|
||||
Best = Vec_MemReadEntry(vTtMem, k)[0];
|
||||
Vec_IntWriteEntry( vMapNew, k, Vec_WrdSize(vBest) );
|
||||
}
|
||||
Vec_WrdPush( vBest, Best );
|
||||
assert( ~Best );
|
||||
if ( Vec_WrdSize(vBest) == nNumFuncs )
|
||||
break;
|
||||
}
|
||||
ABC_SWAP( Vec_Int_t, *vMap, *vMapNew );
|
||||
Vec_IntFree( vMapNew );
|
||||
ABC_FREE( pPerm );
|
||||
if ( fVerbose )
|
||||
printf( "Isolated %d (out of %d) most frequently occuring classes.\n", Vec_WrdSize(vBest), Vec_IntSize(vClassCounts) );
|
||||
return vBest;
|
||||
}
|
||||
void Gia_ManMatchProfileFunctions( Vec_Wrd_t * vBestReprs, Vec_Mem_t * vTtMem, Vec_Int_t * vMap, Vec_Wrd_t * vFuncs, int nCutSize )
|
||||
{
|
||||
int BarSize = 60;
|
||||
extern void Dau_DsdPrintFromTruth( word * pTruth, int nVarsInit );
|
||||
Vec_Int_t * vCounts = Gia_ManCountNpnClasses( vTtMem, vMap, Vec_WrdSize(vBestReprs), vFuncs );
|
||||
word Repr; int c, i, MaxCount = Vec_IntFindMax( vCounts );
|
||||
Vec_WrdForEachEntry( vBestReprs, Repr, c )
|
||||
{
|
||||
int nSymb = BarSize*Vec_IntEntry(vCounts, c)/Abc_MaxInt(MaxCount, 1);
|
||||
printf( "Class%4d : ", c );
|
||||
printf( "Count =%6d ", Vec_IntEntry(vCounts, c) );
|
||||
for ( i = 0; i < nSymb; i++ )
|
||||
printf( "*" );
|
||||
for ( i = nSymb; i < BarSize+3; i++ )
|
||||
printf( " " );
|
||||
Dau_DsdPrintFromTruth( &Repr, nCutSize );
|
||||
}
|
||||
Vec_IntFree( vCounts );
|
||||
}
|
||||
void Gia_ManMatchCones( Gia_Man_t * pBig, Gia_Man_t * pSmall, int nCutSize, int nCutNum, int nNumFuncs, int nNumCones, int fVerbose )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
extern void Dau_CanonicizeArray( Vec_Wrd_t * vFuncs, int nVars, int fVerbose );
|
||||
extern Vec_Mem_t * Dau_CollectNpnFunctionsArray( Vec_Wrd_t * vFuncs, int nVars, Vec_Int_t ** pvMap, int fVerbose );
|
||||
Vec_Wrd_t * vFuncs = Gia_ManCollectCutFuncs( pSmall, nCutSize, nCutNum, fVerbose );
|
||||
Vec_Wrd_t * vOrig = Vec_WrdDup( vFuncs );
|
||||
Dau_CanonicizeArray( vFuncs, nCutSize, fVerbose );
|
||||
Vec_Int_t * vMap = NULL; int n;
|
||||
Vec_Mem_t * vTtMem = Dau_CollectNpnFunctionsArray( vFuncs, nCutSize, &vMap, fVerbose );
|
||||
Vec_WrdFree( vFuncs );
|
||||
Vec_Int_t * vClassCounts = Gia_ManCountNpnClasses( vTtMem, vMap, Vec_IntEntryLast(vMap)+1, vOrig );
|
||||
Vec_Wrd_t * vBestReprs = Gia_ManMatchFilterClasses( vTtMem, vMap, vClassCounts, nNumFuncs, fVerbose );
|
||||
assert( Vec_WrdSize(vBestReprs) == nNumFuncs );
|
||||
Vec_IntFree( vClassCounts );
|
||||
printf( "Frequency profile for %d most popular classes in the small AIG:\n", nNumFuncs );
|
||||
Gia_ManMatchProfileFunctions( vBestReprs, vTtMem, vMap, vOrig, nCutSize );
|
||||
Vec_WrdFree( vOrig );
|
||||
Abc_Random( 1 );
|
||||
for ( n = 0; n < nNumCones; n++ ) {
|
||||
int nRand = Abc_Random( 0 ) % Gia_ManCoNum(pBig);
|
||||
Gia_Man_t * pCone = Gia_ManDupCones( pBig, &nRand, 1, 1 );
|
||||
Vec_Wrd_t * vCutFuncs = Gia_ManCollectCutFuncs( pCone, nCutSize, nCutNum, 0 );
|
||||
printf( "ITER %d: Considering output cone %d with %d and-nodes. ", n+1, nRand, Gia_ManAndNum(pCone) );
|
||||
printf( "Profiling %d functions of %d-cuts:\n", Vec_WrdSize(vCutFuncs), nCutSize );
|
||||
Gia_ManMatchProfileFunctions( vBestReprs, vTtMem, vMap, vCutFuncs, nCutSize );
|
||||
Vec_WrdFree( vCutFuncs );
|
||||
Gia_ManStop( pCone );
|
||||
}
|
||||
Vec_WrdFree( vBestReprs );
|
||||
Vec_IntFree( vMap );
|
||||
Vec_MemHashFree( vTtMem );
|
||||
Vec_MemFree( vTtMem );
|
||||
Abc_PrintTime( 1, "Total computation time", Abc_Clock() - clkStart );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Function enumeration.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManMatchConesMinimizeTts( Vec_Wrd_t * vSims, int nVarsMax )
|
||||
{
|
||||
int nVars = 0;
|
||||
int nWordsMax = Abc_Truth6WordNum( nVarsMax ), nWords;
|
||||
int i, k = 0, nTruths = Vec_WrdSize(vSims) / nWordsMax;
|
||||
assert( nTruths * nWordsMax == Vec_WrdSize(vSims) );
|
||||
// support-minimize and find the largest supp size
|
||||
for ( i = 0; i < nTruths; i++ ) {
|
||||
word * pTruth = Vec_WrdEntryP( vSims, i * nWordsMax );
|
||||
int nVarsCur = Abc_TtMinBase( pTruth, NULL, nVarsMax, nVarsMax );
|
||||
nVars = Abc_MaxInt( nVars, nVarsCur );
|
||||
}
|
||||
// remap truth tables
|
||||
nWords = Abc_Truth6WordNum( nVars );
|
||||
for ( i = 0; i < nTruths; i++ ) {
|
||||
word * pTruth = Vec_WrdEntryP( vSims, i * nWordsMax );
|
||||
word * pTruth2 = Vec_WrdEntryP( vSims, k * nWords );
|
||||
if ( Abc_TtSupportSize(pTruth, nVars) < 3 )
|
||||
continue;
|
||||
memmove( pTruth2, pTruth, nWords * sizeof(word) );
|
||||
k++;
|
||||
if ( 0 ) {
|
||||
extern void Extra_PrintHexadecimal( FILE * pFile, unsigned Sign[], int nVars );
|
||||
printf( "Type%d : ", i );
|
||||
Extra_PrintHexadecimal( stdout, (unsigned *)pTruth2, nVars );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
Vec_WrdShrink ( vSims, k * nWords );
|
||||
return nVars;
|
||||
}
|
||||
void Gia_ManMatchConesOutputPrint( Vec_Ptr_t * p, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vCuts; int i;
|
||||
printf( "Nodes with matching cuts:\n" );
|
||||
Vec_PtrForEachEntry( Vec_Wec_t *, p, vCuts, i ) {
|
||||
if ( fVerbose ) {
|
||||
printf( "Type %d:\n", i );
|
||||
Vec_WecPrint( vCuts, 0 );
|
||||
}
|
||||
else
|
||||
printf( "Type %d present in %d cuts\n", i, Vec_WecSize(vCuts) );
|
||||
}
|
||||
}
|
||||
void Gia_ManMatchConesOutputFree( Vec_Ptr_t * p )
|
||||
{
|
||||
Vec_Wec_t * vCuts; int i;
|
||||
Vec_PtrForEachEntry( Vec_Wec_t *, p, vCuts, i )
|
||||
Vec_WecFree( vCuts );
|
||||
Vec_PtrFree( p );
|
||||
}
|
||||
void Gia_ManMatchConesOutput( Gia_Man_t * pBig, Gia_Man_t * pSmall, int nCutNum, int fVerbose )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
extern Vec_Mem_t * Dau_CollectNpnFunctionsArray( Vec_Wrd_t * vFuncs, int nVars, Vec_Int_t ** pvMap, int fVerbose );
|
||||
Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(pSmall) );
|
||||
Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( pSmall, vSimsPi, 1 );
|
||||
int nVars = Gia_ManMatchConesMinimizeTts( vSims, Gia_ManCiNum(pSmall) );
|
||||
Vec_WrdFree( vSimsPi );
|
||||
if ( nVars > 10 ) {
|
||||
printf( "Some output functions have support size more than 10.\n" );
|
||||
Vec_WrdFree( vSims );
|
||||
return;
|
||||
}
|
||||
Vec_Int_t * vMap = NULL;
|
||||
Vec_Mem_t * vTtMem = Dau_CollectNpnFunctionsArray( vSims, nVars, &vMap, fVerbose );
|
||||
int nFuncs = Vec_WrdSize(vSims) / Abc_Truth6WordNum(nVars);
|
||||
assert( Vec_WrdSize(vSims) == nFuncs * Abc_Truth6WordNum(nVars) );
|
||||
Vec_WrdFree( vSims );
|
||||
printf( "Using %d output functions with the support size between 3 and %d.\n", nFuncs, nVars );
|
||||
Vec_Ptr_t * vRes = Gia_ManMatchCutsMany( vTtMem, vMap, nFuncs, pBig, nVars, nCutNum, fVerbose );
|
||||
Vec_MemHashFree( vTtMem );
|
||||
Vec_MemFree( vTtMem );
|
||||
Vec_IntFree( vMap );
|
||||
Gia_ManMatchConesOutputPrint( vRes, fVerbose );
|
||||
Gia_ManMatchConesOutputFree( vRes );
|
||||
Abc_PrintTime( 1, "Total computation time", Abc_Clock() - clkStart );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -43,7 +43,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose )
|
||||
Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose, Vec_Ptr_t * vGias )
|
||||
{
|
||||
abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
|
||||
abctime clkStart = Abc_Clock();
|
||||
|
|
@ -55,6 +55,7 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
|
|||
Abc_Random(0);
|
||||
for ( i = 0; i < IterMax; i++ )
|
||||
{
|
||||
char * pCompress2rs = "balance -l; resub -K 6 -l; rewrite -l; resub -K 6 -N 2 -l; refactor -l; resub -K 8 -l; balance -l; resub -K 8 -N 2 -l; rewrite -l; resub -K 10 -l; rewrite -z -l; resub -K 10 -N 2 -l; balance -l; resub -K 12 -l; refactor -z -l; resub -K 12 -N 2 -l; rewrite -z -l; balance -l";
|
||||
unsigned Rand = Abc_Random(0);
|
||||
int fDch = Rand & 1;
|
||||
//int fCom = (Rand >> 1) & 3;
|
||||
|
|
@ -62,16 +63,16 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
|
|||
int fFx = (Rand >> 2) & 1;
|
||||
int KLut = fUseTwo ? 2 + (i % 5) : 3 + (i % 4);
|
||||
int fChange = 0;
|
||||
char Command[1000];
|
||||
char * pComp = NULL;
|
||||
char Command[2000];
|
||||
char pComp[1000];
|
||||
if ( fCom == 3 )
|
||||
pComp = "; &put; compress2rs; compress2rs; compress2rs; &get";
|
||||
sprintf( pComp, "; &put; %s; %s; %s; &get", pCompress2rs, pCompress2rs, pCompress2rs );
|
||||
else if ( fCom == 2 )
|
||||
pComp = "; &put; compress2rs; compress2rs; &get";
|
||||
sprintf( pComp, "; &put; %s; %s; &get", pCompress2rs, pCompress2rs );
|
||||
else if ( fCom == 1 )
|
||||
pComp = "; &put; compress2rs; &get";
|
||||
sprintf( pComp, "; &put; %s; &get", pCompress2rs );
|
||||
else if ( fCom == 0 )
|
||||
pComp = "; &dc2";
|
||||
sprintf( pComp, "; &dc2" );
|
||||
sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s",
|
||||
fDch ? " -f" : "", KLut, fFx ? "; &fx; &st" : "", pComp );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
|
|
@ -99,6 +100,8 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
|
|||
pNew = Gia_ManDup( pTemp );
|
||||
fChange = 1;
|
||||
iIterLast = i;
|
||||
if ( vGias )
|
||||
Vec_PtrPush( vGias, Gia_ManDup(pTemp) );
|
||||
}
|
||||
else if ( Gia_ManAndNum(pNew) + Gia_ManAndNum(pNew)/10 < Gia_ManAndNum(pTemp) )
|
||||
{
|
||||
|
|
@ -120,6 +123,7 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
|
|||
}
|
||||
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
|
||||
{
|
||||
if ( !Abc_FrameIsBatchMode() )
|
||||
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
|
||||
break;
|
||||
}
|
||||
|
|
@ -137,16 +141,19 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
|
|||
nAndsMin, nAnds, i, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||
return pNew;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose )
|
||||
Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fChoices, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vGias = fChoices ? Vec_PtrAlloc(100) : NULL;
|
||||
Gia_Man_t * pInit = Gia_ManDup(pGia);
|
||||
Gia_Man_t * pBest = Gia_ManDup(pGia);
|
||||
Gia_Man_t * pThis;
|
||||
int i;
|
||||
if ( vGias )
|
||||
Vec_PtrPush( vGias, Gia_ManDup(pGia) );
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pInit) );
|
||||
pThis = Gia_ManDeepSynOne( nNoImpr, TimeOut, nAnds, Seed+i, fUseTwo, fVerbose );
|
||||
pThis = Gia_ManDeepSynOne( nNoImpr, TimeOut, nAnds, Seed+i, fUseTwo, fVerbose, vGias );
|
||||
if ( Gia_ManAndNum(pBest) > Gia_ManAndNum(pThis) )
|
||||
{
|
||||
Gia_ManStop( pBest );
|
||||
|
|
@ -157,6 +164,393 @@ Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeO
|
|||
|
||||
}
|
||||
Gia_ManStop( pInit );
|
||||
if ( vGias) {
|
||||
if ( Vec_PtrSize(vGias) > 1 ) {
|
||||
extern Gia_Man_t * Gia_ManCreateChoicesArray( Vec_Ptr_t * vGias, int fVerbose );
|
||||
Gia_ManStopP( &pBest );
|
||||
pBest = Gia_ManCreateChoicesArray( vGias, fVerbose );
|
||||
}
|
||||
// cleanup
|
||||
Gia_Man_t * pTemp;
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i )
|
||||
Gia_ManStop( pTemp );
|
||||
Vec_PtrFree( vGias );
|
||||
}
|
||||
return pBest;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generating one AIG by applying a randomized script.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManRandSyn( Gia_Man_t * p, unsigned random_seed )
|
||||
{
|
||||
char * pCompress2rs = "balance -l; resub -K 6 -l; rewrite -l; resub -K 6 -N 2 -l; refactor -l; resub -K 8 -l; balance -l; resub -K 8 -N 2 -l; rewrite -l; resub -K 10 -l; rewrite -z -l; resub -K 10 -N 2 -l; balance -l; resub -K 12 -l; refactor -z -l; resub -K 12 -N 2 -l; rewrite -z -l; balance -l";
|
||||
unsigned Rand = random_seed;
|
||||
int fDch = Rand & 1;
|
||||
//int fCom = (Rand >> 1) & 3;
|
||||
int fCom = (Rand >> 1) & 1;
|
||||
int fFx = (Rand >> 2) & 1;
|
||||
int fUseTwo = 0;
|
||||
int KLut = fUseTwo ? 2 + (Rand % 5) : 3 + (Rand % 4);
|
||||
//int fChange = 0;
|
||||
char Command[2000];
|
||||
char pComp[1000];
|
||||
if ( fCom == 3 )
|
||||
sprintf( pComp, "; &put; %s; %s; %s; &get", pCompress2rs, pCompress2rs, pCompress2rs );
|
||||
else if ( fCom == 2 )
|
||||
sprintf( pComp, "; &put; %s; %s; &get", pCompress2rs, pCompress2rs );
|
||||
else if ( fCom == 1 )
|
||||
sprintf( pComp, "; &put; %s; &get", pCompress2rs );
|
||||
else if ( fCom == 0 )
|
||||
sprintf( pComp, "; &dc2" );
|
||||
sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s",
|
||||
fDch ? " -f" : "", KLut, fFx ? "; &fx; &st" : "", pComp );
|
||||
Gia_Man_t * pOld = Abc_FrameGetGia(Abc_FrameGetGlobalFrame());
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(p) );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
{
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_FrameSetBatchMode( 1 );
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||
return NULL;
|
||||
}
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
}
|
||||
Gia_Man_t * pRes = Abc_FrameGetGia(Abc_FrameGetGlobalFrame());
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pOld );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static void Gia_ManDeepSynParetoUpdate( Vec_Ptr_t * vPareto, Gia_Man_t * pCand, int nLevels, int nAnds )
|
||||
{
|
||||
Gia_Man_t * pBest = (Gia_Man_t *)Vec_PtrGetEntry( vPareto, nLevels );
|
||||
if ( pBest == NULL || Gia_ManAndNum(pBest) > nAnds )
|
||||
{
|
||||
if ( pBest )
|
||||
Gia_ManStop( pBest );
|
||||
Vec_PtrSetEntry( vPareto, nLevels, Gia_ManDup(pCand) );
|
||||
}
|
||||
}
|
||||
|
||||
static void Gia_ManDeepSynParetoPrint( Vec_Ptr_t * vPareto )
|
||||
{
|
||||
Gia_Man_t * pTemp;
|
||||
int i, fFirst = 1;
|
||||
printf( "Pareto points:" );
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vPareto, pTemp, i )
|
||||
{
|
||||
if ( pTemp == NULL )
|
||||
continue;
|
||||
printf( "%s%d:%d", fFirst ? " " : " ", i, Gia_ManAndNum(pTemp) );
|
||||
fFirst = 0;
|
||||
}
|
||||
if ( fFirst )
|
||||
printf( " none" );
|
||||
printf( "\n" );
|
||||
}
|
||||
|
||||
static void Gia_ManDeepSynParetoSave( Vec_Ptr_t * vPareto, char * pBase )
|
||||
{
|
||||
Gia_Man_t * pTemp;
|
||||
char FileName[1000];
|
||||
int i;
|
||||
if ( pBase == NULL )
|
||||
pBase = Extra_UtilStrsav( "gia" );
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vPareto, pTemp, i )
|
||||
{
|
||||
if ( pTemp == NULL )
|
||||
continue;
|
||||
sprintf( FileName, "%s_%d_%d.aig", pBase, i, Gia_ManAndNum(pTemp) );
|
||||
Gia_AigerWrite( pTemp, FileName, 0, 0, 0 );
|
||||
}
|
||||
ABC_FREE( pBase );
|
||||
}
|
||||
|
||||
Gia_Man_t * Gia_ManDeepSynOne2( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose, Vec_Ptr_t * vGias, Vec_Ptr_t * vPareto )
|
||||
{
|
||||
abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
|
||||
abctime clkStart = Abc_Clock();
|
||||
int s, i, k, IterMax = 100000, nLevelsMin = -1, nAndsMin = -1;
|
||||
int nNoImprCount = 0;
|
||||
Gia_Man_t * pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
|
||||
Gia_Man_t * pNew = Gia_ManDup( pTemp );
|
||||
(void)fUseTwo;
|
||||
Abc_Random(1);
|
||||
for ( s = 0; s < 10+Seed; s++ )
|
||||
Abc_Random(0);
|
||||
nLevelsMin = Gia_ManLevelNum(pNew);
|
||||
nAndsMin = Gia_ManAndNum(pNew);
|
||||
for ( i = 0; i < IterMax; )
|
||||
{
|
||||
unsigned Rand = Abc_Random(0);
|
||||
int fDch = Rand & 1;
|
||||
int fResyn = (Rand >> 1) % 3;
|
||||
int fChange = 0;
|
||||
char Command[2000];
|
||||
char pResyn[200];
|
||||
if ( fResyn == 0 )
|
||||
sprintf( pResyn, "&resyn3" );
|
||||
else if ( fResyn == 1 )
|
||||
sprintf( pResyn, "&resyn3rs" );
|
||||
else
|
||||
sprintf( pResyn, "&resyn3; &resyn3rs" );
|
||||
sprintf( Command, "&dch%s; &if -y -K 6; %s", fDch ? " -f" : "", pResyn );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
{
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_FrameSetBatchMode( 1 );
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||
return NULL;
|
||||
}
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
}
|
||||
pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
|
||||
{
|
||||
int nLevelTemp = Gia_ManLevelNum(pTemp);
|
||||
int nAndsTemp = Gia_ManAndNum(pTemp);
|
||||
if ( vPareto )
|
||||
Gia_ManDeepSynParetoUpdate( vPareto, pTemp, nLevelTemp, nAndsTemp );
|
||||
if ( nLevelsMin > nLevelTemp || (nLevelsMin == nLevelTemp && nAndsMin > nAndsTemp) )
|
||||
{
|
||||
Gia_ManStop( pNew );
|
||||
pNew = Gia_ManDup( pTemp );
|
||||
nLevelsMin = nLevelTemp;
|
||||
nAndsMin = nAndsTemp;
|
||||
fChange = 1;
|
||||
if ( vGias )
|
||||
Vec_PtrPush( vGias, Gia_ManDup(pTemp) );
|
||||
nNoImprCount = 0;
|
||||
}
|
||||
else
|
||||
nNoImprCount++;
|
||||
}
|
||||
if ( fChange && fVerbose )
|
||||
{
|
||||
printf( "Iter %6d : ", i );
|
||||
printf( "Time %8.2f sec : ", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||
printf( "Lev = %3d ", nLevelsMin );
|
||||
printf( "And = %6d ", nAndsMin );
|
||||
printf( "<== best : " );
|
||||
printf( "%s", Command );
|
||||
printf( "\n" );
|
||||
}
|
||||
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
|
||||
{
|
||||
if ( !Abc_FrameIsBatchMode() )
|
||||
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
if ( nNoImprCount > nNoImpr )
|
||||
{
|
||||
int nOuter = 1 + (Abc_Random(0) % 3);
|
||||
int nKmax = nAnds ? nAnds : 6;
|
||||
int nKmin = 3;
|
||||
int nLuts[3];
|
||||
if ( nKmax < nKmin )
|
||||
nKmin = nKmax;
|
||||
for ( k = 0; k < nOuter; k++ )
|
||||
nLuts[k] = nKmin + (Abc_Random(0) % (nKmax - nKmin + 1));
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Completed %d iterations without improvement. Trying %d outer iterations with ", nNoImpr, nOuter );
|
||||
for ( k = 0; k < nOuter; k++ )
|
||||
printf( "%sK=%d", k ? ", " : "", nLuts[k] );
|
||||
printf( ". Time = %.2f sec\n", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||
}
|
||||
nNoImprCount = 0;
|
||||
for ( k = 0; k < nOuter && i < IterMax; k++ )
|
||||
{
|
||||
int nLut = nLuts[k];
|
||||
int fOuterChange = 0;
|
||||
sprintf( Command, "&dch; &if -K %d -m; &mfs; &st", nLut );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
{
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_FrameSetBatchMode( 1 );
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
|
||||
return NULL;
|
||||
}
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
}
|
||||
pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
|
||||
{
|
||||
int nLevelTemp = Gia_ManLevelNum(pTemp);
|
||||
int nAndsTemp = Gia_ManAndNum(pTemp);
|
||||
if ( vPareto )
|
||||
Gia_ManDeepSynParetoUpdate( vPareto, pTemp, nLevelTemp, nAndsTemp );
|
||||
if ( nLevelsMin > nLevelTemp || (nLevelsMin == nLevelTemp && nAndsMin > nAndsTemp) )
|
||||
{
|
||||
Gia_ManStop( pNew );
|
||||
pNew = Gia_ManDup( pTemp );
|
||||
nLevelsMin = nLevelTemp;
|
||||
nAndsMin = nAndsTemp;
|
||||
fOuterChange = 1;
|
||||
if ( vGias )
|
||||
Vec_PtrPush( vGias, Gia_ManDup(pTemp) );
|
||||
}
|
||||
}
|
||||
if ( fOuterChange && fVerbose )
|
||||
{
|
||||
printf( "Iter %6d : ", i );
|
||||
printf( "Time %8.2f sec : ", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||
printf( "Lev = %3d ", nLevelsMin );
|
||||
printf( "And = %6d ", nAndsMin );
|
||||
printf( "<== best : " );
|
||||
printf( "%s", Command );
|
||||
printf( "\n" );
|
||||
}
|
||||
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
|
||||
{
|
||||
if ( !Abc_FrameIsBatchMode() )
|
||||
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
|
||||
return pNew;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( i == IterMax )
|
||||
printf( "Iteration limit (%d iters) is reached after %.2f seconds.\n", IterMax, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManDeepSyn2( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fChoices, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vGias = fChoices ? Vec_PtrAlloc(100) : NULL;
|
||||
Vec_Ptr_t * vPareto = fUseTwo ? Vec_PtrStart(100) : NULL;
|
||||
char * pParetoBase = NULL;
|
||||
Gia_Man_t * pInit;
|
||||
Gia_Man_t * pBest;
|
||||
Gia_Man_t * pThis;
|
||||
int i, nBestLev, nBestAnd;
|
||||
if ( !Abc_NtkRecIsRunning3() )
|
||||
{
|
||||
Abc_Print( -1, "Gia_ManDeepSyn2(): LMS library is not loaded.\n" );
|
||||
Abc_Print( -1, "Download \"rec6Lib_final_filtered3_recanon.aig\" and run \"rec_start3 _/rec6Lib_final_filtered3_recanon.aig\".\n" );
|
||||
if ( vGias )
|
||||
Vec_PtrFree( vGias );
|
||||
if ( vPareto )
|
||||
Vec_PtrFree( vPareto );
|
||||
return Gia_ManDup( pGia );
|
||||
}
|
||||
if ( vPareto )
|
||||
{
|
||||
if ( pGia->pSpec && pGia->pSpec[0] )
|
||||
pParetoBase = Extra_FileNameGeneric( pGia->pSpec );
|
||||
else if ( pGia->pName && pGia->pName[0] )
|
||||
pParetoBase = Extra_FileNameGeneric( pGia->pName );
|
||||
else
|
||||
pParetoBase = Extra_UtilStrsav( "gia" );
|
||||
}
|
||||
pInit = Gia_ManDup(pGia);
|
||||
pBest = Gia_ManDup(pGia);
|
||||
nBestLev = Gia_ManLevelNum(pBest);
|
||||
nBestAnd = Gia_ManAndNum(pBest);
|
||||
if ( vPareto )
|
||||
Gia_ManDeepSynParetoUpdate( vPareto, pGia, nBestLev, nBestAnd );
|
||||
if ( vGias )
|
||||
Vec_PtrPush( vGias, Gia_ManDup(pGia) );
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "ITER %d (out of %d) running for %d seconds\n", i + 1, nIters, TimeOut );
|
||||
int nThisLev, nThisAnd;
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pInit) );
|
||||
pThis = Gia_ManDeepSynOne2( nNoImpr, TimeOut, nAnds, Seed+i, fUseTwo, fVerbose, vGias, vPareto );
|
||||
nThisLev = Gia_ManLevelNum(pThis);
|
||||
nThisAnd = Gia_ManAndNum(pThis);
|
||||
if ( nBestLev > nThisLev || (nBestLev == nThisLev && nBestAnd > nThisAnd) )
|
||||
{
|
||||
Gia_ManStop( pBest );
|
||||
pBest = pThis;
|
||||
nBestLev = nThisLev;
|
||||
nBestAnd = nThisAnd;
|
||||
}
|
||||
else
|
||||
Gia_ManStop( pThis );
|
||||
if ( vPareto )
|
||||
Gia_ManDeepSynParetoPrint( vPareto );
|
||||
}
|
||||
Gia_ManStop( pInit );
|
||||
if ( vGias) {
|
||||
if ( Vec_PtrSize(vGias) > 1 ) {
|
||||
extern Gia_Man_t * Gia_ManCreateChoicesArray( Vec_Ptr_t * vGias, int fVerbose );
|
||||
Gia_ManStopP( &pBest );
|
||||
pBest = Gia_ManCreateChoicesArray( vGias, fVerbose );
|
||||
}
|
||||
// cleanup
|
||||
Gia_Man_t * pTemp;
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i )
|
||||
Gia_ManStop( pTemp );
|
||||
Vec_PtrFree( vGias );
|
||||
}
|
||||
if ( vPareto )
|
||||
{
|
||||
Gia_ManDeepSynParetoSave( vPareto, pParetoBase );
|
||||
Gia_Man_t * pTemp;
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vPareto, pTemp, i )
|
||||
if ( pTemp )
|
||||
Gia_ManStop( pTemp );
|
||||
Vec_PtrFree( vPareto );
|
||||
}
|
||||
return pBest;
|
||||
}
|
||||
|
||||
|
|
@ -166,4 +560,3 @@ Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeO
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
2491
src/aig/gia/giaDup.c
2491
src/aig/gia/giaDup.c
File diff suppressed because it is too large
Load Diff
|
|
@ -310,6 +310,39 @@ void Gia_ManDeriveReprs( Gia_Man_t * p )
|
|||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Given pSibls, derives original representitives and nexts.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
void Gia_ManDeriveReprsFromSibls( Gia_Man_t *p )
|
||||
{
|
||||
|
||||
int i, iObj;
|
||||
assert( !p->pReprs && p->pSibls );
|
||||
p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
|
||||
for ( i = 0; i < Gia_ManObjNum(p); i++ )
|
||||
Gia_ObjSetRepr( p, i, GIA_VOID );
|
||||
for ( i = 0; i < Gia_ManObjNum(p); i++ )
|
||||
{
|
||||
if ( p->pSibls[i] == 0 )
|
||||
continue;
|
||||
if ( p->pReprs[i].iRepr != GIA_VOID )
|
||||
continue;
|
||||
for ( iObj = p->pSibls[i]; iObj; iObj = p->pSibls[iObj] )
|
||||
p->pReprs[iObj].iRepr = i;
|
||||
}
|
||||
ABC_FREE( p->pNexts );
|
||||
p->pNexts = Gia_ManDeriveNexts( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -528,7 +561,7 @@ int Gia_ManChoiceMinLevel_rec( Gia_Man_t * p, int iPivot, int fDiveIn, Vec_Int_t
|
|||
{
|
||||
int Level0, Level1, LevelMax;
|
||||
Gia_Obj_t * pPivot = Gia_ManObj( p, iPivot );
|
||||
if ( Gia_ObjIsCi(pPivot) )
|
||||
if ( Gia_ObjIsCi(pPivot) || iPivot == 0 )
|
||||
return 0;
|
||||
if ( Gia_ObjLevel(p, pPivot) )
|
||||
return Gia_ObjLevel(p, pPivot);
|
||||
|
|
@ -715,6 +748,30 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fS
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the AIG in the DFS order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Obj_t * Gia_MakeRandomChoice( Gia_Man_t * p, int iRepr )
|
||||
{
|
||||
int iTemp, Rand, Count = 0;
|
||||
Gia_ClassForEachObj( p, iRepr, iTemp )
|
||||
Count++;
|
||||
Rand = rand() % Count;
|
||||
Count = 0;
|
||||
Gia_ClassForEachObj( p, iRepr, iTemp )
|
||||
if ( Count++ == Rand )
|
||||
break;
|
||||
return Gia_ManObj(p, iTemp);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates the AIG in the DFS order.]
|
||||
|
|
@ -735,7 +792,7 @@ void Gia_ManEquivReduce2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj,
|
|||
if ( fDiveIn && (pRepr = Gia_ManEquivRepr(p, pObj, 1, 0)) )
|
||||
{
|
||||
int iTemp, iRepr = Gia_ObjId(p, pRepr);
|
||||
Gia_Obj_t * pRepr2 = Gia_ManObj( p, Vec_IntEntry(vMap, iRepr) );
|
||||
Gia_Obj_t * pRepr2 = vMap ? Gia_ManObj( p, Vec_IntEntry(vMap, iRepr) ) : Gia_MakeRandomChoice(p, iRepr);
|
||||
Gia_ManEquivReduce2_rec( pNew, p, pRepr2, vMap, 0 );
|
||||
Gia_ClassForEachObj( p, iRepr, iTemp )
|
||||
{
|
||||
|
|
@ -751,12 +808,13 @@ void Gia_ManEquivReduce2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj,
|
|||
Gia_ManEquivReduce2_rec( pNew, p, Gia_ObjFanin1(pObj), vMap, 1 );
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
}
|
||||
Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p )
|
||||
Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p, int fRandom )
|
||||
{
|
||||
Vec_Int_t * vMap;
|
||||
Gia_Man_t * pNew;
|
||||
Gia_Obj_t * pObj;
|
||||
int i;
|
||||
if ( fRandom ) srand(time(NULL));
|
||||
if ( !p->pReprs && p->pSibls )
|
||||
{
|
||||
int * pMap = ABC_FALLOC( int, Gia_ManObjNum(p) );
|
||||
|
|
@ -789,7 +847,7 @@ Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p )
|
|||
break;
|
||||
if ( i == Gia_ManObjNum(p) )
|
||||
return Gia_ManDup( p );
|
||||
vMap = Gia_ManChoiceMinLevel( p );
|
||||
vMap = fRandom ? NULL : Gia_ManChoiceMinLevel( p );
|
||||
Gia_ManSetPhase( p );
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
|
|
@ -805,7 +863,7 @@ Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p )
|
|||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManHashStop( pNew );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
Vec_IntFree( vMap );
|
||||
Vec_IntFreeP( &vMap );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
@ -1869,7 +1927,7 @@ void Gia_ManEquivToChoices_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pOb
|
|||
Gia_Obj_t * pRepr, * pReprNew, * pObjNew;
|
||||
if ( ~pObj->Value )
|
||||
return;
|
||||
if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) )
|
||||
if ( (pRepr = Gia_ObjReprObj(p, Gia_ObjId(p, pObj))) && !Gia_ObjFailed(p,Gia_ObjId(p,pObj)) )
|
||||
{
|
||||
if ( Gia_ObjIsConst0(pRepr) )
|
||||
{
|
||||
|
|
@ -2707,6 +2765,58 @@ void Gia_ManTransferTest( Gia_Man_t * p )
|
|||
Gia_ManStop( pNew );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transfer from new to old.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManTransferEquivs2( Gia_Man_t * p, Gia_Man_t * pOld )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
Vec_Int_t * vClass;
|
||||
int i, k, iNode, iRepr;
|
||||
assert( p->pReprs != NULL );
|
||||
assert( p->pNexts != NULL );
|
||||
assert( pOld->pReprs == NULL );
|
||||
assert( pOld->pNexts == NULL );
|
||||
// create map
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManForEachObj( pOld, pObj, i )
|
||||
if ( ~pObj->Value )
|
||||
Gia_ManObj(p, Abc_Lit2Var(pObj->Value))->Value = Abc_Var2Lit(i, 0);
|
||||
// start representatives
|
||||
pOld->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pOld) );
|
||||
for ( i = 0; i < Gia_ManObjNum(pOld); i++ )
|
||||
Gia_ObjSetRepr( pOld, i, GIA_VOID );
|
||||
// iterate over constant candidates
|
||||
Gia_ManForEachConst( p, i )
|
||||
if ( ~Gia_ManObj(p, i)->Value )
|
||||
Gia_ObjSetRepr( pOld, Abc_Lit2Var(Gia_ManObj(p, i)->Value), 0 );
|
||||
// iterate over class candidates
|
||||
vClass = Vec_IntAlloc( 100 );
|
||||
Gia_ManForEachClass( p, i )
|
||||
{
|
||||
Vec_IntClear( vClass );
|
||||
Gia_ClassForEachObj( p, i, k )
|
||||
if ( (int)Gia_ManObj(p, k)->Value >= 0 )
|
||||
Vec_IntPushUnique( vClass, Abc_Lit2Var(Gia_ManObj(p, k)->Value) );
|
||||
if ( Vec_IntSize( vClass ) <= 1 )
|
||||
continue;
|
||||
assert( Vec_IntSize( vClass ) > 1 );
|
||||
Vec_IntSort( vClass, 0 );
|
||||
iRepr = Vec_IntEntry( vClass, 0 );
|
||||
Vec_IntForEachEntryStart( vClass, iNode, k, 1 )
|
||||
Gia_ObjSetRepr( pOld, iNode, iRepr );
|
||||
}
|
||||
Vec_IntFree( vClass );
|
||||
pOld->pNexts = Gia_ManDeriveNexts( pOld );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -324,12 +324,20 @@ Vec_Int_t * Gia_ManStartMappingFanoutMap( Gia_Man_t * p, Vec_Int_t * vFanoutNums
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p )
|
||||
void Gia_ObjCheckDupMappingFanins( Gia_Man_t * p, int iObj )
|
||||
{
|
||||
int * pFanins = Gia_ObjLutFanins( p, iObj );
|
||||
int i, k, nFanins = Gia_ObjLutSize( p, iObj );
|
||||
for ( i = 0; i < nFanins; i++ )
|
||||
for ( k = i + 1; k < nFanins; k++ )
|
||||
assert( pFanins[i] != pFanins[k] );
|
||||
}
|
||||
void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p, Vec_Int_t ** pvIndex )
|
||||
{
|
||||
Vec_Int_t * vCounts;
|
||||
int * pRefsOld;
|
||||
Gia_Obj_t * pObj, * pFanin;
|
||||
int i, k, iFan, iFanout;
|
||||
int i, k, iFan, iFanout, Index;
|
||||
assert( p->vFanoutNums == NULL );
|
||||
assert( p->vFanout == NULL );
|
||||
// recompute reference counters
|
||||
|
|
@ -339,17 +347,22 @@ void Gia_ManStaticMappingFanoutStart( Gia_Man_t * p )
|
|||
p->pLutRefs = pRefsOld;
|
||||
// start the fanout maps
|
||||
p->vFanout = Gia_ManStartMappingFanoutMap( p, p->vFanoutNums );
|
||||
if ( pvIndex )
|
||||
*pvIndex = Vec_IntStart( Vec_IntSize(p->vFanout) );
|
||||
// incrementally add fanouts
|
||||
vCounts = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
Gia_ManForEachLut( p, i )
|
||||
{
|
||||
Gia_ObjCheckDupMappingFanins( p, i );
|
||||
pObj = Gia_ManObj( p, i );
|
||||
Gia_LutForEachFanin( p, i, iFan, k )
|
||||
Gia_LutForEachFaninIndex( p, i, iFan, k, Index )
|
||||
{
|
||||
pFanin = Gia_ManObj( p, iFan );
|
||||
iFanout = Vec_IntEntry( vCounts, iFan );
|
||||
Gia_ObjSetFanout( p, pFanin, iFanout, pObj );
|
||||
Vec_IntAddToEntry( vCounts, iFan, 1 );
|
||||
if ( pvIndex )
|
||||
Vec_IntWriteEntry( *pvIndex, Vec_IntEntry(p->vFanout, iFan) + iFanout, Index );
|
||||
}
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
|
|
|
|||
|
|
@ -150,6 +150,13 @@ Vec_Wrd_t * Gia_ManComputeTruths( Gia_Man_t * p, int nCutSize, int nLutNum, int
|
|||
// collect and sort fanins
|
||||
vLeaves.nCap = vLeaves.nSize = Gia_ObjLutSize( p, i );
|
||||
vLeaves.pArray = Gia_ObjLutFanins( p, i );
|
||||
if( !Vec_IntCheckUniqueSmall(&vLeaves) )
|
||||
{
|
||||
Vec_IntUniqify(&vLeaves);
|
||||
Vec_IntWriteEntry(p->vMapping, Vec_IntEntry(p->vMapping, i), vLeaves.nSize);
|
||||
for ( k = 0; k < vLeaves.nSize; k++ )
|
||||
Vec_IntWriteEntry(p->vMapping, Vec_IntEntry(p->vMapping, i) + 1 + k, vLeaves.pArray[k]);
|
||||
}
|
||||
assert( Vec_IntCheckUniqueSmall(&vLeaves) );
|
||||
Vec_IntSelectSort( Vec_IntArray(&vLeaves), Vec_IntSize(&vLeaves) );
|
||||
if ( !fReverse )
|
||||
|
|
@ -210,7 +217,9 @@ Vec_Wec_t * Gia_ManFxRetrieve( Gia_Man_t * p, Vec_Str_t ** pvCompl, int fReverse
|
|||
int nVars = Gia_ObjLutSize( p, i );
|
||||
int * pVars = Gia_ObjLutFanins( p, i );
|
||||
word * pTruth = Vec_WrdEntryP( vTruths, Counter++ * nWords );
|
||||
Abc_TtFlipVar5( pTruth, nVars );
|
||||
int Status = Kit_TruthIsop( (unsigned *)pTruth, nVars, vCover, 1 );
|
||||
Abc_TtFlipVar5( pTruth, nVars );
|
||||
if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) )
|
||||
{
|
||||
Vec_StrWriteEntry( *pvCompl, pObj->Value, (char)(Vec_IntSize(vCover) == 0) );
|
||||
|
|
|
|||
|
|
@ -924,10 +924,657 @@ void Gia_ManTestWordFile( Gia_Man_t * p, char * pFileName, char * pDumpFile, int
|
|||
Abc_PrintTime( 1, "Total checking time", Abc_Clock() - clk );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManSumCount( char * p, Vec_Int_t * vDec, int b )
|
||||
{
|
||||
int i, Ent, Count = 0, Sum = 0;
|
||||
for ( i = 0; p[i]; i++ ) {
|
||||
Ent = (p[i] >= '0' && p[i] <= '9') ? p[i]-'0' : p[i]-'A'+10;
|
||||
Count += Vec_IntEntry(vDec, Ent) + b * (1 << (Sum += Ent));
|
||||
}
|
||||
return Count + b * ((1 << Sum) - 1);
|
||||
}
|
||||
Vec_Str_t * Gia_ManSumEnum_rec( int Num )
|
||||
{
|
||||
if ( Num == 1 ) {
|
||||
Vec_Str_t * vRes = Vec_StrAlloc(2);
|
||||
Vec_StrPush( vRes, '1' );
|
||||
Vec_StrPush( vRes, '\0' );
|
||||
return vRes;
|
||||
}
|
||||
Vec_Str_t * vRes = Vec_StrAlloc( 16 );
|
||||
for ( int i = 1; i < Num; i++ ) {
|
||||
Vec_Str_t * vRes0 = Gia_ManSumEnum_rec(i);
|
||||
Vec_Str_t * vRes1 = Gia_ManSumEnum_rec(Num-i);
|
||||
for ( int c0 = 0; c0 < Vec_StrSize(vRes0); c0 += strlen(Vec_StrEntryP(vRes0,c0))+1 )
|
||||
for ( int c1 = 0; c1 < Vec_StrSize(vRes1); c1 += strlen(Vec_StrEntryP(vRes1,c1))+1 )
|
||||
Vec_StrPrintF( vRes, "%s%s%c", Vec_StrEntryP(vRes0,c0), Vec_StrEntryP(vRes1,c1), '\0' );
|
||||
Vec_StrPrintF( vRes, "%c%c", Num < 10 ? '0'+Num : 'A'+Num-10, '\0' );
|
||||
Vec_StrFree( vRes0 );
|
||||
Vec_StrFree( vRes1 );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
void Gia_ManSumEnum( int n, Vec_Int_t * vDec )
|
||||
{
|
||||
Vec_Str_t * vRes = Gia_ManSumEnum_rec( n );
|
||||
for ( int b = 1; b <= 256; b <<= 1 ) {
|
||||
int iBest = -1, CountCur, CountBest = ABC_INFINITY;
|
||||
for ( int c0 = 0; c0 < Vec_StrSize(vRes); c0 += strlen(Vec_StrEntryP(vRes,c0))+1 ) {
|
||||
CountCur = Gia_ManSumCount( Vec_StrEntryP(vRes,c0), vDec, b );
|
||||
if ( CountBest > CountCur )
|
||||
CountBest = CountCur, iBest = c0;
|
||||
}
|
||||
printf( " %8d", CountBest );
|
||||
//printf( " %8s", Vec_StrEntryP(vRes,iBest) );
|
||||
//printf( " %.3f", (float)CountBest/(3*b*((1<<n)-1)) );
|
||||
}
|
||||
// Vec_StrPrint( vRes, 0 );
|
||||
Vec_StrFree( vRes );
|
||||
}
|
||||
Vec_Int_t * Gia_ManSumGenDec( int n )
|
||||
{
|
||||
Vec_Int_t * vDec = Vec_IntAlloc( n + 1 );
|
||||
Vec_IntPush( vDec, 0 );
|
||||
Vec_IntPush( vDec, 0 );
|
||||
Vec_IntPush( vDec, 4 );
|
||||
Vec_IntPush( vDec, 12 );
|
||||
for ( int i = 4; i <= n; i++ ) {
|
||||
int Ent0 = Vec_IntEntry( vDec, i / 2 );
|
||||
int Ent1 = Vec_IntEntry( vDec, i - i / 2 );
|
||||
assert( Vec_IntSize(vDec) == i );
|
||||
Vec_IntPush( vDec, Ent0 + Ent1 + (1 << i / 2) * (1 << (i - i / 2)) );
|
||||
}
|
||||
return vDec;
|
||||
}
|
||||
void Gia_ManSumEnumTest()
|
||||
{
|
||||
Vec_Int_t * vDec = Gia_ManSumGenDec( 16 );
|
||||
printf( " " );
|
||||
for ( int b = 1; b <= 256; b <<= 1 )
|
||||
printf( " %8d", b );
|
||||
printf( "\n" );
|
||||
for ( int i = 1; i <= 15; i++ ) {
|
||||
printf( "%2d :", i );
|
||||
Gia_ManSumEnum( i, vDec );
|
||||
printf( "\n" );
|
||||
}
|
||||
Vec_IntFree( vDec );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManGenNeuronDumpVerilog( Vec_Wrd_t * vData, int nIBits, int nOBits )
|
||||
{
|
||||
FILE * pFile = fopen( "temp.v", "wb" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open output file.\n" );
|
||||
return;
|
||||
}
|
||||
fprintf( pFile, "module neuron_%d_%d_%d ( input [%d:0] i, output [%d:0] o );\n",
|
||||
Vec_WrdSize(vData)-1, nIBits, nOBits, (Vec_WrdSize(vData)-1)*nIBits-1, nOBits-1 );
|
||||
fprintf( pFile, "assign o = %d'h%lX", nOBits, Vec_WrdEntryLast(vData) );
|
||||
word Data; int i;
|
||||
Vec_WrdForEachEntryStop( vData, Data, i, Vec_WrdSize(vData)-1 )
|
||||
fprintf( pFile, "\n + %d'h%lX * i[%d:%d]", nOBits, Data, nIBits*(i+1)-1, nIBits*i );
|
||||
fprintf( pFile, ";\nendmodule\n\n" );
|
||||
fclose( pFile );
|
||||
printf( "Dumped the neuron specification into file \"temp.v\".\n" );
|
||||
}
|
||||
void Gia_ManGenNeuronAdder( Gia_Man_t * p, int nLits, int * pLitsA, int * pLitsB, int Carry, Vec_Int_t * vRes )
|
||||
{
|
||||
extern void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps );
|
||||
int i, Res = -1;
|
||||
Vec_IntClear( vRes );
|
||||
for ( i = 0; i < nLits; i++ ) {
|
||||
Wlc_BlastFullAdder( p, pLitsA[i], pLitsB[i], Carry, &Carry, &Res );
|
||||
Vec_IntPush( vRes, Res );
|
||||
}
|
||||
}
|
||||
void Gia_ManGenCompact( Gia_Man_t * p, Vec_Int_t * vIn0, Vec_Int_t * vIn1, Vec_Int_t * vIn2, Vec_Int_t * vOut0, Vec_Int_t * vOut1 )
|
||||
{
|
||||
extern void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps );
|
||||
assert( Vec_IntSize(vIn0) == Vec_IntSize(vIn1) );
|
||||
assert( Vec_IntSize(vIn0) == Vec_IntSize(vIn2) );
|
||||
Vec_IntPush( vOut1, 0 );
|
||||
int i, Lit0, Lit1, Lit2, Out0, Out1;
|
||||
Vec_IntForEachEntryThree( vIn0, vIn1, vIn2, Lit0, Lit1, Lit2, i ) {
|
||||
Wlc_BlastFullAdder( p, Lit0, Lit1, Lit2, &Out1, &Out0 );
|
||||
Vec_IntPush( vOut0, Out0 );
|
||||
Vec_IntPush( vOut1, Out1 );
|
||||
}
|
||||
Vec_IntPop( vOut1 );
|
||||
assert( Vec_IntSize(vIn0) == Vec_IntSize(vOut0) );
|
||||
assert( Vec_IntSize(vIn0) == Vec_IntSize(vOut1) );
|
||||
}
|
||||
Vec_Wec_t * Gia_ManGenNeuronCreateArgs( Vec_Wrd_t * vData, int nIBits, int nOBits )
|
||||
{
|
||||
word Data = Vec_WrdEntryLast(vData); int i, b, n, nLits = 2;
|
||||
Vec_Wec_t * vArgs = Vec_WecAlloc( Vec_WrdSize(vData) * nIBits );
|
||||
Vec_Int_t * vLev = Vec_WecPushLevel( vArgs );
|
||||
Vec_IntFill( vLev, nOBits, 0 );
|
||||
for ( b = 0; b < nOBits; b++ )
|
||||
if ( (Data >> b) & 1 )
|
||||
Vec_IntWriteEntry( vLev, b, 1 );
|
||||
Vec_WrdForEachEntryStop( vData, Data, i, Vec_WrdSize(vData)-1 ) {
|
||||
for ( n = 0; n < nIBits; n++, nLits += 2 ) {
|
||||
Vec_Int_t * vLev = Vec_WecPushLevel( vArgs );
|
||||
Vec_IntFill( vLev, nOBits, 0 );
|
||||
for ( b = 0; b < nOBits; b++ )
|
||||
if ( ((Data >> b) & 1) && b+n < nOBits )
|
||||
Vec_IntWriteEntry( vLev, b+n, nLits );
|
||||
}
|
||||
}
|
||||
return vArgs;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManGenNeuronTransformArgs( Gia_Man_t * pNew, Vec_Wec_t * vArgs, int nLutSize, int nOBits )
|
||||
{
|
||||
int i, nParts = (Vec_WecSize(vArgs) + nLutSize - 2) / nLutSize;
|
||||
while ( Vec_WecSize(vArgs) < nLutSize*nParts+1 )
|
||||
Vec_IntFill( Vec_WecPushLevel(vArgs), nOBits, 0 );
|
||||
assert( Vec_WecSize(vArgs) == nLutSize*nParts+1 );
|
||||
Vec_Wec_t * vNew = Vec_WecAlloc( nParts );
|
||||
Vec_Int_t * vRes = Vec_WecPushLevel( vNew ), * vArg;
|
||||
Vec_IntAppend( vRes, Vec_WecEntry(vArgs, 0) );
|
||||
Vec_WecForEachLevelStart( vArgs, vArg, i, 1 ) {
|
||||
Gia_ManGenNeuronAdder( pNew, nOBits, Vec_IntArray(vArg), Vec_IntArray(vRes), 0, vRes );
|
||||
if ( (i-1) % nLutSize == nLutSize-1 && i < Vec_WecSize(vArgs)-1 ) {
|
||||
vRes = Vec_WecPushLevel( vNew );
|
||||
Vec_IntFill( vRes, nOBits, 0 );
|
||||
}
|
||||
}
|
||||
assert( Vec_WecSize(vNew) == nParts );
|
||||
return vNew;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManGenNeuronCompactArgs( Gia_Man_t * pNew, Vec_Wec_t * vArgs, int nLutSize, int nOBits )
|
||||
{
|
||||
int i, nParts = Vec_WecSize(vArgs) / 3;
|
||||
Vec_Wec_t * vNew = Vec_WecAlloc( 2 * nParts + Vec_WecSize(vArgs) % 3 );
|
||||
for ( i = 0; i < nParts; i++ ) {
|
||||
Vec_Int_t * vIn0 = Vec_WecEntry(vArgs, 3*i+0);
|
||||
Vec_Int_t * vIn1 = Vec_WecEntry(vArgs, 3*i+1);
|
||||
Vec_Int_t * vIn2 = Vec_WecEntry(vArgs, 3*i+2);
|
||||
Vec_Int_t * vOut0 = Vec_WecPushLevel(vNew);
|
||||
Vec_Int_t * vOut1 = Vec_WecPushLevel(vNew);
|
||||
Gia_ManGenCompact( pNew, vIn0, vIn1, vIn2, vOut0, vOut1 );
|
||||
}
|
||||
for ( i = 3*nParts; i < Vec_WecSize(vArgs); i++ )
|
||||
Vec_IntAppend( Vec_WecPushLevel(vNew), Vec_WecEntry(vArgs, i) );
|
||||
assert( Vec_WecSize(vNew) == 2 * nParts + Vec_WecSize(vArgs) % 3 );
|
||||
return vNew;
|
||||
}
|
||||
Vec_Int_t * Gia_ManGenNeuronFinal( Gia_Man_t * pNew, Vec_Wec_t * vArgs, int nOBits )
|
||||
{
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( nOBits ), * vArg; int i;
|
||||
Vec_IntAppend( vRes, Vec_WecEntry(vArgs, 0) );
|
||||
Vec_WecForEachLevelStart( vArgs, vArg, i, 1 )
|
||||
Gia_ManGenNeuronAdder( pNew, nOBits, Vec_IntArray(vArg), Vec_IntArray(vRes), 0, vRes );
|
||||
return vRes;
|
||||
}
|
||||
int Gia_ManGenNeuronBitWidth( Vec_Wrd_t * vData, int nIBits )
|
||||
{
|
||||
int i, InMask = (1<<nIBits)-1;
|
||||
word Data, DataMax = Vec_WrdEntryLast(vData);
|
||||
Vec_WrdForEachEntryStop( vData, Data, i, Vec_WrdSize(vData)-1 )
|
||||
DataMax += InMask * Data;
|
||||
return Abc_Base2LogW(DataMax);
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenNeuron( char * pFileName, int nIBits, int nLutSize, int fDump, int fVerbose )
|
||||
{
|
||||
int nWords = -1;
|
||||
Vec_Wrd_t * vData = Vec_WrdReadHex( pFileName, &nWords, 0 );
|
||||
if ( vData == NULL )
|
||||
return NULL;
|
||||
|
||||
assert( nWords == 1 );
|
||||
assert( 0 < nIBits && nIBits < 32 );
|
||||
int i, Lit, nOBits = Gia_ManGenNeuronBitWidth( vData, nIBits );
|
||||
if ( fDump ) Gia_ManGenNeuronDumpVerilog( vData, nIBits, nOBits );
|
||||
|
||||
Gia_Man_t * pTemp, * pNew = Gia_ManStart( 10000 );
|
||||
pNew->pName = Abc_UtilStrsav( "neuron" );
|
||||
for ( i = 0; i < nIBits * (Vec_WrdSize(vData)-1); i++ )
|
||||
Gia_ManAppendCi( pNew );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
|
||||
Vec_Wec_t * vTemp, * vArgs = Gia_ManGenNeuronCreateArgs( vData, nIBits, nOBits );
|
||||
Vec_WrdFree( vData );
|
||||
|
||||
if ( nLutSize ) {
|
||||
vArgs = Gia_ManGenNeuronTransformArgs( pNew, vTemp = vArgs, nLutSize, nOBits );
|
||||
Vec_WecFree( vTemp );
|
||||
while ( Vec_WecSize(vArgs) > 2 ) {
|
||||
vArgs = Gia_ManGenNeuronCompactArgs( pNew, vTemp = vArgs, nLutSize, nOBits );
|
||||
Vec_WecFree( vTemp );
|
||||
}
|
||||
}
|
||||
|
||||
Vec_Int_t * vRes = Gia_ManGenNeuronFinal( pNew, vArgs, nOBits );
|
||||
Vec_IntForEachEntry( vRes, Lit, i )
|
||||
Gia_ManAppendCo( pNew, Lit );
|
||||
Vec_IntFree( vRes );
|
||||
Vec_WecFree( vArgs );
|
||||
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generates minimum-node AIG for n-bit comparator (a > b).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManDupGenComp( int nBits, int fInterleave, int fSigned )
|
||||
{
|
||||
Gia_Man_t * pNew, * pTemp; int i, iLit = 1, iLitXor = 0, iLitB = 0;
|
||||
Vec_Int_t * vBitsA = Vec_IntAlloc( nBits + 1 );
|
||||
Vec_Int_t * vBitsB = Vec_IntAlloc( nBits + 1 );
|
||||
pNew = Gia_ManStart( 6*nBits+10 );
|
||||
pNew->pName = Abc_UtilStrsav( "comp" );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
if ( fInterleave ) {
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
Vec_IntPush( vBitsA, Gia_ManAppendCi(pNew) ),
|
||||
Vec_IntPush( vBitsB, Gia_ManAppendCi(pNew) );
|
||||
}
|
||||
else {
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
Vec_IntPush( vBitsA, Gia_ManAppendCi(pNew) );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
Vec_IntPush( vBitsB, Gia_ManAppendCi(pNew) );
|
||||
}
|
||||
if ( fSigned ) {
|
||||
iLitXor = Gia_ManHashXor( pNew, Vec_IntPop(vBitsA), (iLitB = Vec_IntPop(vBitsB)) );
|
||||
nBits--;
|
||||
}
|
||||
Vec_IntPush( vBitsA, 0 );
|
||||
Vec_IntPush( vBitsB, 0 );
|
||||
for ( i = 0; i < nBits; i++ ) {
|
||||
int iLitA0 = Vec_IntEntry(vBitsA, i);
|
||||
int iLitA1 = Vec_IntEntry(vBitsA, i+1);
|
||||
int iLitB0 = Vec_IntEntry(vBitsB, i);
|
||||
int iLitB1 = Vec_IntEntry(vBitsB, i+1);
|
||||
int iOrLit0;
|
||||
if ( i == 0 )
|
||||
iOrLit0 = Gia_ManHashOr(pNew, Abc_LitNotCond(iLitA0, !(i&1)), Abc_LitNotCond(iLitB0, i&1));
|
||||
else
|
||||
iOrLit0 = Gia_ManHashAnd(pNew, Abc_LitNotCond(iLitA0, !(i&1)), Abc_LitNotCond(iLitB0, i&1));
|
||||
int iOrLit1 = Gia_ManHashAnd(pNew, Abc_LitNotCond(iLitA1, !(i&1)), Abc_LitNotCond(iLitB1, i&1));
|
||||
int iOrLit = Gia_ManHashOr(pNew, iOrLit0, iOrLit1 );
|
||||
iLit = Gia_ManHashOr(pNew, Abc_LitNot(iLit), iOrLit );
|
||||
}
|
||||
iLit = Abc_LitNotCond(iLit, nBits&1);
|
||||
if ( fSigned )
|
||||
iLit = Gia_ManHashMux(pNew, iLitXor, iLitB, iLit );
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
Vec_IntFree( vBitsA );
|
||||
Vec_IntFree( vBitsB );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generates optimized AIG for the decoder and the multiplexer.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_GenDecoder( Gia_Man_t * p, int * pLits, int nLits )
|
||||
{
|
||||
if ( nLits == 1 )
|
||||
{
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 2 );
|
||||
Vec_IntPush( vRes, Abc_LitNot(pLits[0]) );
|
||||
Vec_IntPush( vRes, pLits[0] );
|
||||
return vRes;
|
||||
}
|
||||
assert( nLits > 1 );
|
||||
int nPart1 = nLits / 2;
|
||||
int nPart2 = nLits - nPart1;
|
||||
Vec_Int_t * vRes1 = Gia_GenDecoder( p, pLits, nPart1 );
|
||||
Vec_Int_t * vRes2 = Gia_GenDecoder( p, pLits+nPart1, nPart2 );
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vRes1) * Vec_IntSize(vRes2) );
|
||||
int i, k, Lit1, Lit2;
|
||||
Vec_IntForEachEntry( vRes2, Lit2, k )
|
||||
Vec_IntForEachEntry( vRes1, Lit1, i )
|
||||
Vec_IntPush( vRes, Gia_ManHashAnd(p, Lit1, Lit2) );
|
||||
Vec_IntFree( vRes1 );
|
||||
Vec_IntFree( vRes2 );
|
||||
return vRes;
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenMux( int nIns, char * pNums )
|
||||
{
|
||||
Vec_Int_t * vIns = Vec_IntAlloc( nIns );
|
||||
Vec_Int_t * vData = Vec_IntAlloc( 1 << nIns );
|
||||
Gia_Man_t * p = Gia_ManStart( 4*(1 << nIns) + nIns ), * pTemp;
|
||||
int i, iStart = 0, nSize = 1 << nIns;
|
||||
p->pName = Abc_UtilStrsav( "mux" );
|
||||
for ( i = 0; i < nIns; i++ )
|
||||
Vec_IntPush( vIns, Gia_ManAppendCi(p) );
|
||||
for ( i = 0; i < nSize; i++ )
|
||||
Vec_IntPush( vData, Gia_ManAppendCi(p) );
|
||||
Gia_ManHashAlloc( p );
|
||||
for ( i = (int)strlen(pNums)-1; i >= 0; i-- )
|
||||
{
|
||||
int k, b, nBits = (int)(pNums[i] - '0');
|
||||
Vec_Int_t * vDec = Gia_GenDecoder( p, Vec_IntEntryP(vIns, iStart), nBits );
|
||||
for ( k = 0; k < nSize; k++ )
|
||||
Vec_IntWriteEntry( vData, k, Gia_ManHashAnd(p, Vec_IntEntry(vData, k), Vec_IntEntry(vDec, k%Vec_IntSize(vDec))) );
|
||||
for ( b = 0; b < nBits; b++, nSize /= 2 )
|
||||
for ( k = 0; k < nSize/2; k++ )
|
||||
Vec_IntWriteEntry( vData, k, Gia_ManHashOr(p, Vec_IntEntry(vData, 2*k), Vec_IntEntry(vData, 2*k+1)) );
|
||||
Vec_IntFree( vDec );
|
||||
iStart += nBits;
|
||||
}
|
||||
assert( nSize == 1 );
|
||||
Gia_ManAppendCo( p, Vec_IntEntry(vData, 0) );
|
||||
Vec_IntFree( vIns );
|
||||
Vec_IntFree( vData );
|
||||
p = Gia_ManCleanup( pTemp = p );
|
||||
Gia_ManStop( pTemp );
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generates N-bit sorter using pair-wise sorting algorithm.]
|
||||
|
||||
Description [https://en.wikipedia.org/wiki/Pairwise_sorting_network]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Gia_ManGenSorterOne( Gia_Man_t * p, int * pLits, int i, int k )
|
||||
{
|
||||
int Lit1 = Gia_ManAppendAnd( p, pLits[i], pLits[k] );
|
||||
int Lit2 = Gia_ManAppendOr ( p, pLits[i], pLits[k] );
|
||||
pLits[i] = Lit1;
|
||||
pLits[k] = Lit2;
|
||||
}
|
||||
static inline void Gia_ManGenSorterConstrMerge( Gia_Man_t * p, int * pLits, int lo, int hi, int r )
|
||||
{
|
||||
int i, step = r * 2;
|
||||
if ( step < hi - lo )
|
||||
{
|
||||
Gia_ManGenSorterConstrMerge( p, pLits, lo, hi-r, step );
|
||||
Gia_ManGenSorterConstrMerge( p, pLits, lo+r, hi, step );
|
||||
for ( i = lo+r; i < hi-r; i += step )
|
||||
Gia_ManGenSorterOne( p, pLits, i, i+r );
|
||||
}
|
||||
}
|
||||
static inline void Gia_ManGenSorterConstrRange( Gia_Man_t * p, int * pLits, int lo, int hi )
|
||||
{
|
||||
if ( hi - lo >= 1 )
|
||||
{
|
||||
int i, mid = lo + (hi - lo) / 2;
|
||||
for ( i = lo; i <= mid; i++ )
|
||||
Gia_ManGenSorterOne( p, pLits, i, i + (hi - lo + 1) / 2 );
|
||||
Gia_ManGenSorterConstrRange( p, pLits, lo, mid );
|
||||
Gia_ManGenSorterConstrRange( p, pLits, mid+1, hi );
|
||||
Gia_ManGenSorterConstrMerge( p, pLits, lo, hi, 1 );
|
||||
}
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenSorter( int LogN )
|
||||
{
|
||||
int i, nVars = 1 << LogN;
|
||||
int nVarsAlloc = nVars + 2 * (nVars * LogN * (LogN-1) / 4 + nVars - 1);
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( nVars );
|
||||
Gia_Man_t * p = Gia_ManStart( 1 + 2*nVars + nVarsAlloc );
|
||||
p->pName = Abc_UtilStrsav( "sorter" );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
Vec_IntPush( vLits, Gia_ManAppendCi(p) );
|
||||
Gia_ManGenSorterConstrRange( p, Vec_IntArray(vLits), 0, nVars - 1 );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
Gia_ManAppendCo( p, Vec_IntEntry(vLits, i) );
|
||||
Vec_IntFree( vLits );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generates brand-name adders.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManGenPrep( int nVars, int ** p )
|
||||
{
|
||||
int i, k;
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
p[i][k] = -1;
|
||||
}
|
||||
void Gia_ManGenSK( int nVars, int ** p )
|
||||
{
|
||||
int i, k, nBits = Abc_Base2Log(nVars);
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
if ( (k >> i) & 1 )
|
||||
p[i+1][k] = ((1 << i) - 1) | ((k >> (i+1)) << (i+1));
|
||||
}
|
||||
void Gia_ManGenBK( int nVars, int ** p )
|
||||
{
|
||||
int i, k, nBits = Abc_Base2Log(nVars);
|
||||
nVars = 1 << nBits;
|
||||
for ( i = 1; i < nBits; i++ )
|
||||
for ( k = (1 << i) - 1; k < nVars; k += (1 << i) )
|
||||
p[i][k] = k - (1 << (i-1));
|
||||
p[nBits][nVars-1] = (1<<(nBits-1))-1;
|
||||
for ( i = 1; i < nBits; i++ )
|
||||
for ( k = (1 << i) - 1; k < nVars-(1 << i); k += (1 << i) )
|
||||
p[2*nBits-1-i][nVars-1-k+((1<<(i-1))-1)] = nVars-1-k+((1<<(i-1))-1) - (1 << (i-1));
|
||||
}
|
||||
void Gia_ManGenHC( int nVars, int ** p )
|
||||
{
|
||||
int i, k, nBits = Abc_Base2Log(nVars);
|
||||
nVars = 1 << nBits;
|
||||
for ( k = 1; k < nVars; k += 2 )
|
||||
p[1][k] = k - 1;
|
||||
for ( i = 2; i <= nBits; i++ )
|
||||
for ( k = 1 + (1 << (i-1)); k < nVars; k += 2 )
|
||||
p[i][k] = k - (1 << (i-1));
|
||||
for ( k = 2; k < nVars; k += 2 )
|
||||
p[nBits+1][k] = k - 1;
|
||||
}
|
||||
void Gia_ManGenRca( int nVars, int ** p )
|
||||
{
|
||||
int i;
|
||||
for ( i = 1; i < nVars; i++ )
|
||||
p[i][i] = i-1;
|
||||
}
|
||||
void Gia_ManGenPrint( int nVars, int ** p )
|
||||
{
|
||||
int i, k;
|
||||
for ( i = nVars-1; i >= 0; i-- )
|
||||
printf( "%2d ", i );
|
||||
printf( "\n" );
|
||||
for ( i = 0; i < nVars; i++ ) {
|
||||
for ( k = nVars-1; k >= 0; k-- )
|
||||
if ( p[i][k] >= 0 )
|
||||
break;
|
||||
for ( k = nVars-1; k >= 0; k-- )
|
||||
if ( p[i][k] == -1 )
|
||||
printf( " - " );
|
||||
else
|
||||
printf( "%2d ", p[i][k] );
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
void Gia_ManGenPrefix( Gia_Man_t * pNew, int * p, int * g, int p2, int g2 )
|
||||
{
|
||||
*g = Gia_ManHashOr(pNew, *g, Gia_ManHashAnd(pNew, *p, g2));
|
||||
*p = Gia_ManHashAnd(pNew, *p, p2);
|
||||
}
|
||||
static int Gia_ManGenAdderMaj( Gia_Man_t * p, int a, int b, int c )
|
||||
{
|
||||
int ab = Gia_ManHashAnd( p, a, b );
|
||||
int ac = Gia_ManHashAnd( p, a, c );
|
||||
int bc = Gia_ManHashAnd( p, b, c );
|
||||
return Gia_ManHashOr( p, ab, Gia_ManHashOr( p, ac, bc ) );
|
||||
}
|
||||
static int Gia_ManGenAdderFloorPow2( int n )
|
||||
{
|
||||
int r = 1;
|
||||
assert( n > 0 );
|
||||
while ( r <= n / 2 )
|
||||
r *= 2;
|
||||
return r;
|
||||
}
|
||||
static void Gia_ManGenAdderMMRange( Gia_Man_t * p, int nVars, int * pLitsI, int * pM0, int * pM1, int i, int k )
|
||||
{
|
||||
int Index = i * nVars + k;
|
||||
int nRange, nLeft, j;
|
||||
assert( 0 <= i && i <= k && k < nVars );
|
||||
if ( pM0[Index] >= 0 )
|
||||
return;
|
||||
if ( i == k )
|
||||
{
|
||||
pM0[Index] = pLitsI[2*i];
|
||||
pM1[Index] = pLitsI[2*i+1];
|
||||
return;
|
||||
}
|
||||
nRange = k - i + 1;
|
||||
nLeft = Gia_ManGenAdderFloorPow2( nRange - 1 );
|
||||
j = i + nLeft - 1;
|
||||
Gia_ManGenAdderMMRange( p, nVars, pLitsI, pM0, pM1, i, j );
|
||||
Gia_ManGenAdderMMRange( p, nVars, pLitsI, pM0, pM1, j+1, k );
|
||||
pM0[Index] = Gia_ManGenAdderMaj( p, pM0[(j+1)*nVars+k], pM1[(j+1)*nVars+k], pM0[i*nVars+j] );
|
||||
pM1[Index] = Gia_ManGenAdderMaj( p, pM0[(j+1)*nVars+k], pM1[(j+1)*nVars+k], pM1[i*nVars+j] );
|
||||
}
|
||||
static int Gia_ManGenAdderMMCarry( Gia_Man_t * p, int nVars, int * pLitsI, int * pM0, int * pM1, int * pCarries, int iCarry )
|
||||
{
|
||||
int nBase, iBeg;
|
||||
assert( 0 <= iCarry && iCarry <= nVars );
|
||||
if ( pCarries[iCarry] >= 0 )
|
||||
return pCarries[iCarry];
|
||||
nBase = Gia_ManGenAdderFloorPow2( iCarry );
|
||||
iBeg = nBase - 1;
|
||||
Gia_ManGenAdderMMRange( p, nVars, pLitsI, pM0, pM1, iBeg, iCarry-1 );
|
||||
pCarries[iCarry] = Gia_ManGenAdderMaj( p, pM0[iBeg*nVars+iCarry-1], pM1[iBeg*nVars+iCarry-1], Gia_ManGenAdderMMCarry( p, nVars, pLitsI, pM0, pM1, pCarries, iBeg ) );
|
||||
return pCarries[iCarry];
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenAdder( int nVars, int fSK, int fBK, int fHC, int fMM, int fCarries, int fVerbose )
|
||||
{
|
||||
extern void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps );
|
||||
int i, k, nBits = Abc_Base2Log(nVars), nVarsAlloc = (1 << nBits) + 2;
|
||||
int ** pStore = fMM ? NULL : (int **)Extra_ArrayAlloc( nVarsAlloc, nVarsAlloc, 4 );
|
||||
printf( "Generating %d-bit ", nVars );
|
||||
if ( fMM )
|
||||
printf("M/M ");
|
||||
else
|
||||
{
|
||||
Gia_ManGenPrep( nVars+2, pStore );
|
||||
if ( fSK )
|
||||
Gia_ManGenSK( nVars, pStore ), printf("Sklansky ");
|
||||
else if ( fBK )
|
||||
Gia_ManGenBK( nVars, pStore ), printf("Brent-Kung ");
|
||||
else if ( fHC )
|
||||
Gia_ManGenHC( nVars, pStore ), printf("Huan-Carlsson ");
|
||||
else
|
||||
Gia_ManGenRca( nVars, pStore ), printf("ripple-carry ");
|
||||
}
|
||||
printf( "adder with%s carry-in and carry-out\n", fCarries ? "":"out" );
|
||||
if ( fVerbose && !fMM ) Gia_ManGenPrint( nVars, pStore );
|
||||
Gia_Man_t * p = Gia_ManStart( 1000 ), * pTemp;
|
||||
p->pName = Abc_UtilStrsav( "adder" );
|
||||
int * pLitsI = ABC_CALLOC( int, 2*nVars+10 );
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
pLitsI[2*k] = Gia_ManAppendCi(p);
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
pLitsI[2*k+1] = Gia_ManAppendCi(p);
|
||||
int Carry = fCarries ? Gia_ManAppendCi(p) : 0;
|
||||
Gia_ManHashStart( p );
|
||||
if ( fMM )
|
||||
{
|
||||
int nPairs = nVars * nVars;
|
||||
int * pM0 = ABC_ALLOC( int, nPairs );
|
||||
int * pM1 = ABC_ALLOC( int, nPairs );
|
||||
int * pCarries = ABC_ALLOC( int, nVars + 1 );
|
||||
int * pProps = ABC_ALLOC( int, nVars );
|
||||
for ( k = 0; k < nPairs; k++ )
|
||||
pM0[k] = pM1[k] = -1;
|
||||
for ( k = 0; k <= nVars; k++ )
|
||||
pCarries[k] = -1;
|
||||
pCarries[0] = Carry;
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
pProps[k] = Gia_ManHashXor( p, pLitsI[2*k], pLitsI[2*k+1] );
|
||||
if ( fCarries )
|
||||
Gia_ManAppendCo( p, Gia_ManGenAdderMMCarry( p, nVars, pLitsI, pM0, pM1, pCarries, nVars ) );
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
Gia_ManAppendCo( p, Gia_ManHashXor( p, pProps[k], Gia_ManGenAdderMMCarry( p, nVars, pLitsI, pM0, pM1, pCarries, k ) ) );
|
||||
ABC_FREE( pM0 );
|
||||
ABC_FREE( pM1 );
|
||||
ABC_FREE( pCarries );
|
||||
ABC_FREE( pProps );
|
||||
ABC_FREE( pLitsI );
|
||||
p = Gia_ManCleanup( pTemp = p );
|
||||
Gia_ManStop( pTemp );
|
||||
return p;
|
||||
}
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
Wlc_BlastFullAdder( p, pLitsI[2*k], pLitsI[2*k+1], k ? 0 : Carry, &pLitsI[2*k+1], &pLitsI[2*k] );
|
||||
int * pLits = ABC_CALLOC( int, 2*nVars+10 );
|
||||
memcpy( pLits, pLitsI, sizeof(int)*2*nVars );
|
||||
for ( i = 1; i < nVars; i++ )
|
||||
for ( k = nVars - 1; k >= 1; k-- )
|
||||
if ( pStore[i][k] >= 0 )
|
||||
Gia_ManGenPrefix( p, &pLits[2*k], &pLits[2*k+1], pLits[2*pStore[i][k]], pLits[2*pStore[i][k]+1] );
|
||||
if ( fCarries )
|
||||
Gia_ManAppendCo( p, pLits[2*(k-1)+1] );
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
Gia_ManAppendCo( p, k ? Gia_ManHashXor(p, pLitsI[2*k], pLits[2*(k-1)+1]) : pLitsI[2*k] );
|
||||
ABC_FREE( pStore );
|
||||
ABC_FREE( pLitsI );
|
||||
ABC_FREE( pLits );
|
||||
p = Gia_ManCleanup( pTemp = p );
|
||||
Gia_ManStop( pTemp );
|
||||
return p;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -470,6 +470,65 @@ int Gia_ManCountDupLut( Gia_Man_t * p )
|
|||
return nCountDup + nCountPis;
|
||||
}
|
||||
|
||||
void Gia_ManCollectLuts_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vLuts )
|
||||
{
|
||||
if ( Gia_ObjIsTravIdCurrentId( p, iObj ) || !Gia_ObjIsAnd(Gia_ManObj(p, iObj)) )
|
||||
return;
|
||||
Gia_ObjSetTravIdCurrentId( p, iObj );
|
||||
int k, iFan;
|
||||
Gia_LutForEachFanin( p, iObj, iFan, k )
|
||||
Gia_ManCollectLuts_rec( p, iFan, vLuts );
|
||||
Vec_IntPush( vLuts, iObj );
|
||||
}
|
||||
int Gia_ManCountLutLevels( Gia_Man_t * p, Vec_Int_t * vLuts, Vec_Int_t * vLevel )
|
||||
{
|
||||
int i, iObj, k, iFan, LevelMax = 0;
|
||||
Vec_IntForEachEntry( vLuts, iObj, i ) {
|
||||
int Level = 0;
|
||||
Gia_LutForEachFanin( p, iObj, iFan, k )
|
||||
Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, iFan) );
|
||||
Vec_IntWriteEntry( vLevel, iObj, Level+1 );
|
||||
LevelMax = Abc_MaxInt( LevelMax, Level+1 );
|
||||
}
|
||||
Vec_IntForEachEntry( vLuts, iObj, i )
|
||||
Vec_IntWriteEntry( vLevel, iObj, 0 );
|
||||
return LevelMax;
|
||||
}
|
||||
void Gia_ManPrintOutputLutStats( Gia_Man_t * p )
|
||||
{
|
||||
int Limit = 100000;
|
||||
int nLutSize = Gia_ManLutSizeMax(p);
|
||||
Vec_Int_t * vLuts = Vec_IntAlloc( 1000 );
|
||||
Vec_Int_t * vNodes = Vec_IntStart( Limit );
|
||||
Vec_Int_t * vLevels = Vec_IntStart( Limit );
|
||||
Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
int i, DriverId, Value, nTotalLuts = 0;
|
||||
Gia_ManForEachCoDriverId( p, DriverId, i ) {
|
||||
Vec_IntClear( vLuts );
|
||||
Gia_ManIncrementTravId(p);
|
||||
Gia_ManCollectLuts_rec( p, DriverId, vLuts );
|
||||
if ( Vec_IntSize(vLuts) < Limit )
|
||||
Vec_IntAddToEntry( vNodes, Vec_IntSize(vLuts), 1 );
|
||||
int Level = Gia_ManCountLutLevels( p, vLuts, vLevel );
|
||||
if ( Level < Limit )
|
||||
Vec_IntAddToEntry( vLevels, Level, 1 );
|
||||
nTotalLuts += Vec_IntSize(vLuts);
|
||||
}
|
||||
printf( "Level count statistics for %d AIG outputs:\n", Gia_ManCoNum(p) );
|
||||
Vec_IntForEachEntry( vLevels, Value, i )
|
||||
if ( Value )
|
||||
printf( " %2d level : Function count = %8d (%6.2f %%)\n", i, Value, 100.0*Value/Gia_ManCoNum(p) );
|
||||
printf( "LUT count statistics for %d AIG outputs:\n", Gia_ManCoNum(p) );
|
||||
Vec_IntForEachEntry( vNodes, Value, i )
|
||||
if ( Value )
|
||||
printf( " %2d LUT%d : Function count = %8d (%6.2f %%)\n", i, nLutSize, Value, 100.0*Value/Gia_ManCoNum(p) );
|
||||
printf( "Sum total of LUT counts for all outputs = %d. Shared LUT count = %d.\n", nTotalLuts, Gia_ManLutNum(p) );
|
||||
Vec_IntFree( vLuts );
|
||||
Vec_IntFree( vNodes );
|
||||
Vec_IntFree( vLevels );
|
||||
Vec_IntFree( vLevel );
|
||||
}
|
||||
|
||||
void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile )
|
||||
{
|
||||
int fDisable2Lut = 1;
|
||||
|
|
@ -558,11 +617,12 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile )
|
|||
FILE * pTable = fopen( pDumpFile, "a+" );
|
||||
if ( strcmp( FileNameOld, p->pName ) )
|
||||
{
|
||||
sprintf( FileNameOld, "%s", p->pName );
|
||||
sprintf( FileNameOld, "%s_out", p->pName );
|
||||
fprintf( pTable, "\n" );
|
||||
fprintf( pTable, "%s ", p->pName );
|
||||
fprintf( pTable, " " );
|
||||
fprintf( pTable, "%d ", Gia_ManAndNum(p) );
|
||||
//fprintf( pTable, "%d ", Gia_ManAndNum(p) );
|
||||
fprintf( pTable, "%d ", Gia_ManRegNum(p) );
|
||||
fprintf( pTable, "%d ", nLuts );
|
||||
fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) );
|
||||
//fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) );
|
||||
|
|
@ -575,11 +635,13 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile )
|
|||
//printf( "This part of the code is currently not used.\n" );
|
||||
//assert( 0 );
|
||||
fprintf( pTable, " " );
|
||||
fprintf( pTable, " " );
|
||||
fprintf( pTable, "%d ", Gia_ManRegNum(p) );
|
||||
fprintf( pTable, "%d ", nLuts );
|
||||
fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) );
|
||||
//fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) );
|
||||
//fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) );
|
||||
fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC );
|
||||
// fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC );
|
||||
clk = Abc_Clock();
|
||||
}
|
||||
fclose( pTable );
|
||||
|
|
@ -1113,6 +1175,111 @@ int Gia_ManFromIfLogicCreateLutSpecial( Gia_Man_t * pNew, word * pRes, Vec_Int_t
|
|||
return iObjLit2;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Write mapping for LUT with given fanins.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManFromIfLogicCreateLutSpecialJ( Gia_Man_t * pNew, word * pRes, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking )
|
||||
{
|
||||
word Truth;
|
||||
int i, iObjLit1, iObjLit2, iObjLit3;
|
||||
word z = If_CutPerformDeriveJ( NULL, (unsigned *)pRes, Vec_IntSize(vLeaves), Vec_IntSize(vLeaves), NULL, 1, 0 );
|
||||
assert( z != 0 );
|
||||
if ( ((z >> 63) & 1) == 0 )
|
||||
{
|
||||
// create first LUT
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (16+(i<<2))) & 7);
|
||||
if ( v == 6 && Vec_IntSize(vLeaves) == 5 )
|
||||
continue;
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v) );
|
||||
}
|
||||
Truth = (z & 0xffff);
|
||||
Truth |= (Truth << 16);
|
||||
Truth |= (Truth << 32);
|
||||
iObjLit1 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
// create second LUT
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (48+(i<<2))) & 7);
|
||||
if ( v == 6 && Vec_IntSize(vLeaves) == 5 )
|
||||
continue;
|
||||
if ( v == 7 )
|
||||
Vec_IntPush( vLeavesTemp, iObjLit1 );
|
||||
else
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v) );
|
||||
}
|
||||
Truth = ((z >> 32) & 0xffff);
|
||||
Truth |= (Truth << 16);
|
||||
Truth |= (Truth << 32);
|
||||
iObjLit2 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
// write packing
|
||||
Vec_IntPush( vPacking, 2 );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit1) );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit2) );
|
||||
Vec_IntAddToEntry( vPacking, 0, 1 );
|
||||
return iObjLit2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int Pla2Var[9];
|
||||
extern void If_PermUnpack( unsigned Value, int Pla2Var[9] );
|
||||
If_PermUnpack( (unsigned)(z >> 32), Pla2Var );
|
||||
|
||||
// create first data LUT
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
if ( Pla2Var[i] != 9 )
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, Pla2Var[i]) );
|
||||
}
|
||||
Truth = (z & 0xffff);
|
||||
Truth |= (Truth << 16);
|
||||
Truth |= (Truth << 32);
|
||||
iObjLit1 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
|
||||
// create second data LUT
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( i = 4; i < 8; i++ )
|
||||
{
|
||||
if ( Pla2Var[i] != 9 )
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, Pla2Var[i]) );
|
||||
}
|
||||
Truth = ((z >> 16) & 0xffff);
|
||||
Truth |= (Truth << 16);
|
||||
Truth |= (Truth << 32);
|
||||
iObjLit2 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
|
||||
// create MUX LUT (2-input MUX: select ? iObjLit2 : iObjLit1)
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
Vec_IntPush( vLeavesTemp, iObjLit1 ); // data 0
|
||||
Vec_IntPush( vLeavesTemp, iObjLit2 ); // data 1
|
||||
if ( Pla2Var[8] != 9 )
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, Pla2Var[8]) ); // select
|
||||
// MUX truth table: f = s ? d1 : d0 = ~s&d0 | s&d1 = 0xCACACACA for (d0,d1,s)
|
||||
Truth = ABC_CONST(0xCACACACACACACACA);
|
||||
iObjLit3 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
|
||||
// write packing - 3 LUTs packed together
|
||||
Vec_IntPush( vPacking, 3 );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit1) );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit2) );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit3) );
|
||||
Vec_IntAddToEntry( vPacking, 0, 1 );
|
||||
return iObjLit3;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Write the node into a file.]
|
||||
|
|
@ -1125,31 +1292,13 @@ int Gia_ManFromIfLogicCreateLutSpecial( Gia_Man_t * pNew, word * pRes, Vec_Int_t
|
|||
|
||||
***********************************************************************/
|
||||
int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp,
|
||||
word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking, int fCheck75, int fCheck44e )
|
||||
word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking, int fCheck75 )
|
||||
{
|
||||
int nLeaves = Vec_IntSize(vLeaves);
|
||||
int i, Length, nLutLeaf, nLutLeaf2, nLutRoot, iObjLit1, iObjLit2, iObjLit3;
|
||||
// workaround for the special case
|
||||
if ( fCheck75 )
|
||||
pStr = "54";
|
||||
// perform special case matching for 44
|
||||
if ( fCheck44e )
|
||||
{
|
||||
if ( Vec_IntSize(vLeaves) <= 4 )
|
||||
{
|
||||
// create mapping
|
||||
iObjLit1 = Gia_ManFromIfLogicCreateLut( pNew, pRes, vLeaves, vCover, vMapping, vMapping2 );
|
||||
// write packing
|
||||
if ( !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(iObjLit1))) && iObjLit1 > 1 )
|
||||
{
|
||||
Vec_IntPush( vPacking, 1 );
|
||||
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit1) );
|
||||
Vec_IntAddToEntry( vPacking, 0, 1 );
|
||||
}
|
||||
return iObjLit1;
|
||||
}
|
||||
return Gia_ManFromIfLogicCreateLutSpecial( pNew, pRes, vLeaves, vLeavesTemp, vCover, vMapping, vMapping2, vPacking );
|
||||
}
|
||||
if ( ((If_Man_t *)pIfMan)->pPars->fLut6Filter && Vec_IntSize(vLeaves) == 6 )
|
||||
{
|
||||
extern word If_Dec6Perform( word t, int fDerive );
|
||||
|
|
@ -1305,12 +1454,25 @@ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t
|
|||
{
|
||||
if ( Length == 2 )
|
||||
{
|
||||
if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
|
||||
if ( ((If_Man_t *)pIfMan)->pPars->fEnableStructN )
|
||||
{
|
||||
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
|
||||
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
|
||||
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
|
||||
return -1;
|
||||
if ( !If_CluCheckXXExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
|
||||
{
|
||||
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
|
||||
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
|
||||
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
|
||||
{
|
||||
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
|
||||
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
|
||||
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1408,6 +1570,90 @@ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t
|
|||
return iObjLit3;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Implements delay-driven decomposition of the cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManFromIfLogicHop( Gia_Man_t * pNew, If_Man_t * pIfMan, If_Cut_t * pCutBest, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2 )
|
||||
{
|
||||
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
|
||||
unsigned char decompArray[92];
|
||||
int val;
|
||||
|
||||
assert( pCutBest->nLeaves > pIfMan->pPars->nLutDecSize );
|
||||
|
||||
unsigned delayProfile = pCutBest->decDelay;
|
||||
val = acd_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
|
||||
assert( val == 0 );
|
||||
|
||||
// convert the LUT-structure into a set of logic nodes in Gia_Man_t
|
||||
unsigned char bytes_check = decompArray[0];
|
||||
assert( bytes_check <= 92 );
|
||||
|
||||
int byte_p = 2;
|
||||
unsigned char i, j, k, num_fanins, num_words, num_bytes;
|
||||
int iObjLits[5];
|
||||
int fanin;
|
||||
word *tt;
|
||||
|
||||
for ( i = 0; i < decompArray[1]; ++i )
|
||||
{
|
||||
num_fanins = decompArray[byte_p++];
|
||||
Vec_IntClear( vLeavesTemp );
|
||||
for ( j = 0; j < num_fanins; ++j )
|
||||
{
|
||||
fanin = (int)decompArray[byte_p++];
|
||||
if ( fanin < If_CutLeaveNum(pCutBest) )
|
||||
{
|
||||
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, fanin) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_IntPush( vLeavesTemp, iObjLits[fanin - If_CutLeaveNum(pCutBest)] );
|
||||
}
|
||||
}
|
||||
|
||||
/* extract the truth table */
|
||||
tt = pIfMan->puTempW;
|
||||
num_words = ( num_fanins <= 6 ) ? 1 : ( 1 << ( num_fanins - 6 ) );
|
||||
num_bytes = ( num_fanins <= 3 ) ? 1 : ( 1 << ( Abc_MinInt( (int)num_fanins, 6 ) - 3 ) );
|
||||
for ( j = 0; j < num_words; ++j )
|
||||
{
|
||||
tt[j] = 0;
|
||||
for ( k = 0; k < num_bytes; ++k )
|
||||
{
|
||||
tt[j] |= ( (word)(decompArray[byte_p++]) ) << ( k << 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/* extend truth table if size < 5 */
|
||||
assert( num_fanins != 1 );
|
||||
if ( num_fanins == 2 )
|
||||
{
|
||||
tt[0] |= tt[0] << 4;
|
||||
}
|
||||
while ( num_bytes < 4 )
|
||||
{
|
||||
tt[0] |= tt[0] << ( num_bytes << 3 );
|
||||
num_bytes <<= 1;
|
||||
}
|
||||
|
||||
iObjLits[i] = Gia_ManFromIfLogicCreateLut( pNew, tt, vLeavesTemp, vCover, vMapping, vMapping2 );
|
||||
}
|
||||
|
||||
/* check correct read */
|
||||
assert( byte_p == decompArray[0] );
|
||||
|
||||
return iObjLits[i-1];
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recursively derives the local AIG for the cut.]
|
||||
|
|
@ -1652,6 +1898,367 @@ void Gia_ManFromIfGetConfig( Vec_Int_t * vConfigs, If_Man_t * pIfMan, If_Cut_t *
|
|||
Vec_StrPush( vConfigsStr, '\n' );
|
||||
}
|
||||
}
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print configuration during encoding.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManConfigPrint( word Truth4, word z, int nLeaves )
|
||||
{
|
||||
static int Count = 0;
|
||||
int i;
|
||||
printf( "[%4d] Encoding (nLeaves=%d): ", Count++, nLeaves );
|
||||
// Simple LUT4 case (Truth4 != 0, z == 0)
|
||||
if ( z == 0 )
|
||||
{
|
||||
printf( "%04lX{", (unsigned long)(Truth4 & 0xFFFF) );
|
||||
for ( i = 0; i < nLeaves && i < 4; i++ )
|
||||
printf( "%c", 'a' + i );
|
||||
printf( "} [Cell 0, LUT4]\n" );
|
||||
return;
|
||||
}
|
||||
if ( ((z >> 63) & 1) == 0 )
|
||||
{
|
||||
// Extract truth tables
|
||||
word Truth1 = z & 0xFFFF;
|
||||
word Truth2 = (z >> 32) & 0xFFFF;
|
||||
printf( "h=%04lX{", (unsigned long)Truth1 );
|
||||
// First LUT4 inputs from bits 16-31
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (16 + (i << 2))) & 7);
|
||||
if ( v == 6 && nLeaves == 5 )
|
||||
printf( "0" ); // Constant 0 for 5-input cuts
|
||||
else if ( v == 7 )
|
||||
printf( "?" ); // Internal connection (shouldn't appear in first LUT)
|
||||
else if ( v <= 6 )
|
||||
printf( "%c", 'a' + v );
|
||||
else
|
||||
printf( "?" );
|
||||
}
|
||||
printf( "} ");
|
||||
printf( "i=%04lX{", (unsigned long)Truth2 );
|
||||
// Second LUT4 inputs from bits 48-63
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (48 + (i << 2))) & 7);
|
||||
if ( v == 6 && nLeaves == 5 )
|
||||
printf( "0" ); // Constant 0 for 5-input cuts
|
||||
else if ( v == 7 )
|
||||
printf( "h" ); // Output of first LUT
|
||||
else if ( v <= 6 )
|
||||
printf( "%c", 'a' + v );
|
||||
else
|
||||
printf( "?" );
|
||||
}
|
||||
printf( "} [Cell 1, S44]\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
int Pla2Var[9];
|
||||
extern void If_PermUnpack( unsigned Value, int Pla2Var[9] );
|
||||
If_PermUnpack( (unsigned)(z >> 32), Pla2Var );
|
||||
// Extract truth tables
|
||||
word Truth1 = z & 0xFFFF;
|
||||
word Truth2 = (z >> 16) & 0xFFFF;
|
||||
printf( "j=%04lX{", (unsigned long)Truth1 );
|
||||
// First LUT4 inputs
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
if ( Pla2Var[i] == 9 )
|
||||
printf( "0" ); // Will be encoded as constant 0
|
||||
else if ( Pla2Var[i] < 9 )
|
||||
printf( "%c", 'a' + Pla2Var[i] );
|
||||
else
|
||||
printf( "?" );
|
||||
}
|
||||
printf( "} ");
|
||||
printf( "k=%04lX{", (unsigned long)Truth2 );
|
||||
// Second LUT4 inputs
|
||||
for ( i = 4; i < 8; i++ )
|
||||
{
|
||||
if ( Pla2Var[i] == 9 )
|
||||
printf( "0" ); // Will be encoded as constant 0
|
||||
else if ( Pla2Var[i] < 9 )
|
||||
printf( "%c", 'a' + Pla2Var[i] );
|
||||
else
|
||||
printf( "?" );
|
||||
}
|
||||
printf( "} ");
|
||||
// final
|
||||
printf( "l=<" );
|
||||
if ( Pla2Var[8] == 9 )
|
||||
printf( "0" ); // Will be encoded as constant 0
|
||||
else if ( Pla2Var[8] < 9 )
|
||||
printf( "%c", 'a' + Pla2Var[8] );
|
||||
else
|
||||
printf( "?" );
|
||||
printf( "jk> [Cell 2, 9-input MUX]\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print cell configuration data.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManConfigPrint2( unsigned char * pConfigData, int nLeaves )
|
||||
{
|
||||
unsigned char CellId = pConfigData[0];
|
||||
int i;
|
||||
static int Count = 0;
|
||||
printf( "%6d : ", Count++ ); // Print instance number
|
||||
printf( "[Cell %d with %d leaves] ", CellId, nLeaves );
|
||||
if ( CellId == 0 )
|
||||
{
|
||||
assert( nLeaves <= 4 );
|
||||
// Extract 16-bit truth table
|
||||
word Truth = ((word)pConfigData[5] << 8) | pConfigData[6];
|
||||
printf( "e=%04lX{", (unsigned long)Truth );
|
||||
// Print as simple {abcd} since it's just a direct LUT4
|
||||
for ( i = 0; i < nLeaves; i++ )
|
||||
printf( "%c", 'a' + i );
|
||||
for ( ; i < 4; i++ )
|
||||
printf( "%c", '0' );
|
||||
printf( "}\n" );
|
||||
}
|
||||
else if ( CellId == 1 )
|
||||
{
|
||||
// First LUT4
|
||||
word Truth1 = ((word)pConfigData[8] << 8) | pConfigData[9];
|
||||
printf( "h=%04lX{", (unsigned long)Truth1 );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = pConfigData[1+i];
|
||||
if ( v == 0 )
|
||||
printf( "0");
|
||||
else if ( v == 1 )
|
||||
printf( "1");
|
||||
else if ( v >= 2 && v < 2 + nLeaves )
|
||||
printf( "%c", 'a' + (v-2));
|
||||
else
|
||||
printf( "?");
|
||||
}
|
||||
printf( "};");
|
||||
// Second LUT4
|
||||
word Truth2 = ((word)pConfigData[10] << 8) | pConfigData[11];
|
||||
printf( "i=%04lX{", (unsigned long)Truth2 );
|
||||
for ( i = 4; i < 7; i++ )
|
||||
{
|
||||
int v = pConfigData[1+i];
|
||||
if ( v == 0 )
|
||||
printf( "0");
|
||||
else if ( v == 1 )
|
||||
printf( "1");
|
||||
else if ( v >= 2 && v < 2 + nLeaves )
|
||||
printf( "%c", 'a' + (v-2));
|
||||
else if ( v == 9 )
|
||||
printf( "h"); // Output of first LUT
|
||||
else
|
||||
printf( "?");
|
||||
}
|
||||
printf( "h}\n" );
|
||||
}
|
||||
else if ( CellId == 2 )
|
||||
{
|
||||
// First LUT4
|
||||
word Truth1 = ((word)pConfigData[10] << 8) | pConfigData[11];
|
||||
printf( "j=%04lX{", (unsigned long)Truth1 );
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = pConfigData[1+i];
|
||||
if ( v == 0 )
|
||||
printf( "0");
|
||||
else if ( v == 1 )
|
||||
printf( "1");
|
||||
else if ( v >= 2 && v < 2 + nLeaves )
|
||||
printf( "%c", 'a' + (v-2));
|
||||
else
|
||||
printf( "?");
|
||||
}
|
||||
printf( "};");
|
||||
// Second LUT4
|
||||
word Truth2 = ((word)pConfigData[12] << 8) | pConfigData[13];
|
||||
printf( "k=%04lX{", (unsigned long)Truth2 );
|
||||
for ( i = 4; i < 8; i++ )
|
||||
{
|
||||
int v = pConfigData[1+i];
|
||||
if ( v == 0 )
|
||||
printf( "0");
|
||||
else if ( v == 1 )
|
||||
printf( "1");
|
||||
else if ( v >= 2 && v < 2 + nLeaves )
|
||||
printf( "%c", 'a' + (v-2));
|
||||
else
|
||||
printf( "?");
|
||||
}
|
||||
printf( "};");
|
||||
// final node
|
||||
printf( "l=<");
|
||||
int v = pConfigData[1+8];
|
||||
if ( v == 0 )
|
||||
printf( "0");
|
||||
else if ( v == 1 )
|
||||
printf( "1");
|
||||
else if ( v >= 2 && v < 2 + nLeaves )
|
||||
printf( "%c", 'a' + (v-2));
|
||||
else
|
||||
printf( "?");
|
||||
printf( "jk>\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Unknown cell type %d!\n", CellId );
|
||||
}
|
||||
}
|
||||
|
||||
static inline word Gia_ManFromIfPermuteTruth4( word Truth, int nLeaves, word z )
|
||||
{
|
||||
word TruthNew = 0;
|
||||
int i, k, x;
|
||||
assert( nLeaves >= 1 && nLeaves <= 4 );
|
||||
for ( i = 0; i < 16; i++ )
|
||||
{
|
||||
x = 0;
|
||||
for ( k = 0; k < nLeaves; k++ )
|
||||
{
|
||||
int v = (int)((z >> (2 * k)) & 3);
|
||||
x |= ((i >> k) & 1) << v;
|
||||
}
|
||||
TruthNew |= ((Truth >> x) & 1) << i;
|
||||
}
|
||||
return TruthNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive configurations.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * pTruth, int nLeaves, int fDelay )
|
||||
{
|
||||
int i, CellId;
|
||||
int startPos = Vec_StrSize(vConfigs2);
|
||||
If_LibCell_t * pCellLib = pIfMan && pIfMan->pPars ? pIfMan->pPars->pCellLib : NULL;
|
||||
assert( pCellLib != NULL );
|
||||
|
||||
// Determine cell type based on the number of leaves and configuration
|
||||
if ( nLeaves <= 4 ) // 7 bytes = 1 byte CellId + 4 bytes mapping + 2 bytes truth table
|
||||
{
|
||||
word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1, fDelay );
|
||||
int fHavePerm = (z != 0) && ((z & ABC_CONST(0x4000000000000000)) != 0);
|
||||
word Truth = pTruth[0];
|
||||
// Cell type 0: Simple LUT4
|
||||
CellId = 0;
|
||||
// Write CellId
|
||||
Vec_StrPush( vConfigs2, (char)CellId );
|
||||
// Write mapping
|
||||
for ( i = 0; i < nLeaves; i++ )
|
||||
{
|
||||
int v = fHavePerm ? (int)((z >> (2 * i)) & 3) : i;
|
||||
Vec_StrPush( vConfigs2, 2 + v );
|
||||
}
|
||||
for ( ; i < 4; i++ )
|
||||
Vec_StrPush( vConfigs2, 0 );
|
||||
// Write truth table (16 bits for LUT4)
|
||||
if ( fHavePerm )
|
||||
Truth = Gia_ManFromIfPermuteTruth4( Truth, nLeaves, z );
|
||||
Vec_StrPush( vConfigs2, (char)((Truth >> 8) & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)(Truth & 0xFF) );
|
||||
assert( startPos + pCellLib->pCellRecordSizes[CellId] == Vec_StrSize(vConfigs2) );
|
||||
//Gia_ManConfigPrint( Truth, 0, nLeaves );
|
||||
}
|
||||
else // 12 bytes = 1 byte CellId + 7 bytes mapping + 4 bytes truth tables
|
||||
{
|
||||
word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1, fDelay );
|
||||
//Gia_ManConfigPrint( 0, z, nLeaves );
|
||||
if ( ((z >> 63) & 1) == 0 )
|
||||
{
|
||||
CellId = 1;
|
||||
Vec_StrPush( vConfigs2, (char)CellId );
|
||||
// Write input mapping
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (16 + (i << 2))) & 7);
|
||||
if ( v == 6 && nLeaves == 5 )
|
||||
Vec_StrPush( vConfigs2, 0 );
|
||||
else
|
||||
Vec_StrPush( vConfigs2, 2+v );
|
||||
}
|
||||
int iSpecial = -1;
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
int v = (int)((z >> (48 + (i << 2))) & 7);
|
||||
if ( v == 6 && nLeaves == 5 )
|
||||
Vec_StrPush( vConfigs2, 0 );
|
||||
else if ( v != 7 )
|
||||
Vec_StrPush( vConfigs2, 2+v );
|
||||
else if ( v == 7 )
|
||||
iSpecial = i;
|
||||
}
|
||||
// Transform the truth table
|
||||
assert( iSpecial >= 0 );
|
||||
word Truth = (z >> 32) & 0xFFFF;
|
||||
Truth = Abc_Tt6Stretch( Truth, 4 );
|
||||
for ( int v = iSpecial; v < 3; v++ )
|
||||
Truth = Abc_Tt6SwapAdjacent( Truth, v );
|
||||
// Write truth tables
|
||||
word Truth1 = z & 0xFFFF;
|
||||
//word Truth2 = (z >> 32) & 0xFFFF;
|
||||
word Truth2 = Truth & 0xFFFF;
|
||||
Vec_StrPush( vConfigs2, (char)((Truth1 >> 8) & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)(Truth1 & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)((Truth2 >> 8) & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)(Truth2 & 0xFF) );
|
||||
assert( startPos + pCellLib->pCellRecordSizes[CellId] == Vec_StrSize(vConfigs2) );
|
||||
}
|
||||
else // 14 bytes = 1 byte CellId + 9 bytes mapping + 4 bytes truth tables
|
||||
{
|
||||
CellId = 2;
|
||||
int Pla2Var[9];
|
||||
extern void If_PermUnpack( unsigned Value, int Pla2Var[9] );
|
||||
If_PermUnpack( (unsigned)(z >> 32), Pla2Var );
|
||||
// Write CellId
|
||||
Vec_StrPush( vConfigs2, (char)CellId );
|
||||
// Write input mapping
|
||||
for ( i = 0; i < 9; i++ )
|
||||
{
|
||||
if ( Pla2Var[i] == 9 )
|
||||
Vec_StrPush( vConfigs2, 0 );
|
||||
else
|
||||
Vec_StrPush( vConfigs2, Pla2Var[i] + 2 );
|
||||
}
|
||||
// Write truth tables for the two LUT4s only (MUX is structural, not a LUT)
|
||||
word Truth1 = z & 0xFFFF;
|
||||
word Truth2 = (z >> 16) & 0xFFFF;
|
||||
Vec_StrPush( vConfigs2, (char)((Truth1 >> 8) & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)(Truth1 & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)((Truth2 >> 8) & 0xFF) );
|
||||
Vec_StrPush( vConfigs2, (char)(Truth2 & 0xFF) );
|
||||
assert( startPos + pCellLib->pCellRecordSizes[CellId] == Vec_StrSize(vConfigs2) );
|
||||
}
|
||||
}
|
||||
if ( pIfMan->pPars->fVerboseTrace )
|
||||
Gia_ManConfigPrint2( (unsigned char*)Vec_StrEntryP(vConfigs2, startPos), nLeaves );
|
||||
}
|
||||
int Gia_ManFromIfLogicFindCell( If_Man_t * pIfMan, Gia_Man_t * pNew, Gia_Man_t * pTemp, If_Cut_t * pCutBest, Ifn_Ntk_t * pNtkCell, int nLutMax, Vec_Int_t * vLeaves, Vec_Int_t * vLits, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vConfigs )
|
||||
{
|
||||
int iLit;
|
||||
|
|
@ -1845,18 +2452,19 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
If_Cut_t * pCutBest;
|
||||
If_Obj_t * pIfObj, * pIfLeaf;
|
||||
Vec_Int_t * vMapping, * vMapping2, * vPacking = NULL, * vConfigs = NULL;
|
||||
Vec_Str_t * vConfigs2 = NULL;
|
||||
Vec_Int_t * vLeaves, * vLeaves2, * vCover, * vLits;
|
||||
Vec_Str_t * vConfigsStr = NULL;
|
||||
Ifn_Ntk_t * pNtkCell = NULL;
|
||||
sat_solver * pSat = NULL;
|
||||
int i, k, Entry;
|
||||
assert( !pIfMan->pPars->fDeriveLuts || pIfMan->pPars->fTruth );
|
||||
// if ( pIfMan->pPars->fEnableCheck07 )
|
||||
// pIfMan->pPars->fDeriveLuts = 0;
|
||||
//if ( pIfMan->pPars->fEnableCheck07 )
|
||||
// pIfMan->pPars->fDeriveLuts = 0;
|
||||
// start mapping and packing
|
||||
vMapping = Vec_IntStart( If_ManObjNum(pIfMan) );
|
||||
vMapping2 = Vec_IntStart( 1 );
|
||||
if ( pIfMan->pPars->fDeriveLuts && (pIfMan->pPars->pLutStruct || pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u || pIfMan->pPars->fEnableCheck07) )
|
||||
if ( pIfMan->pPars->fDeriveLuts && (pIfMan->pPars->pLutStruct || pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u) )
|
||||
{
|
||||
vPacking = Vec_IntAlloc( 1000 );
|
||||
Vec_IntPush( vPacking, 0 );
|
||||
|
|
@ -1872,6 +2480,8 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
if ( fWriteConfigs )
|
||||
vConfigsStr = Vec_StrAlloc( 1000 );
|
||||
}
|
||||
if ( pIfMan->pPars->fEnableCheck07 )
|
||||
vConfigs2 = Vec_StrAlloc( 1000 );
|
||||
// create new manager
|
||||
pNew = Gia_ManStart( If_ManObjNum(pIfMan) );
|
||||
// iterate through nodes used in the mapping
|
||||
|
|
@ -1891,7 +2501,7 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
if ( !pIfMan->pPars->fUseTtPerm && !pIfMan->pPars->fDelayOpt && !pIfMan->pPars->fDelayOptLut && !pIfMan->pPars->fDsdBalance &&
|
||||
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserRecLib && !pIfMan->pPars->fUserSesLib && !pIfMan->pPars->nGateSize &&
|
||||
!pIfMan->pPars->fEnableCheck75 && !pIfMan->pPars->fEnableCheck75u && !pIfMan->pPars->fEnableCheck07 && !pIfMan->pPars->fUseDsdTune &&
|
||||
!pIfMan->pPars->fUseCofVars && !pIfMan->pPars->fUseAndVars )
|
||||
!pIfMan->pPars->fUseCofVars && !pIfMan->pPars->fUseAndVars && !pIfMan->pPars->fUseCheck1 && !pIfMan->pPars->fUseCheck2 && !pIfMan->pPars->fUserLutDec )
|
||||
If_CutRotatePins( pIfMan, pCutBest );
|
||||
// collect leaves of the best cut
|
||||
Vec_IntClear( vLeaves );
|
||||
|
|
@ -1943,6 +2553,10 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
{
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicCofVars( pNew, pIfMan, pCutBest, vLeaves, vLeaves2, vCover, vMapping, vMapping2 );
|
||||
}
|
||||
else if ( pIfMan->pPars->fUserLutDec && (int)pCutBest->nLeaves > pIfMan->pPars->nLutDecSize )
|
||||
{
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicHop( pNew, pIfMan, pCutBest, vLeaves, vLeaves2, vCover, vMapping, vMapping2 );
|
||||
}
|
||||
else if ( (pIfMan->pPars->fDeriveLuts && pIfMan->pPars->fTruth) || pIfMan->pPars->fUseDsd || pIfMan->pPars->fUseTtPerm || pIfMan->pPars->pFuncCell2 )
|
||||
{
|
||||
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
|
||||
|
|
@ -1951,10 +2565,30 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
if ( If_CutLeafBit(pCutBest, k) )
|
||||
Abc_TtFlip( pTruth, Abc_TtWordNum(pCutBest->nLeaves), k );
|
||||
// perform decomposition of the cut
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicNode( pIfMan, pNew, i, vLeaves, vLeaves2, pTruth, pIfMan->pPars->pLutStruct, vCover, vMapping, vMapping2, vPacking, (pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u), pIfMan->pPars->fEnableCheck07 );
|
||||
if ( pIfMan->pPars->fEnableCheck07 )
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicCreateLut( pNew, pTruth, vLeaves, vCover, vMapping, vMapping2 );
|
||||
else
|
||||
pIfObj->iCopy = Gia_ManFromIfLogicNode( pIfMan, pNew, i, vLeaves, vLeaves2, pTruth, pIfMan->pPars->pLutStruct, vCover, vMapping, vMapping2, vPacking, (pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u) );
|
||||
pIfObj->iCopy = Abc_LitNotCond( pIfObj->iCopy, pCutBest->fCompl );
|
||||
if ( vConfigs && Vec_IntSize(vLeaves) > 1 && !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(pIfObj->iCopy))) && pIfObj->iCopy > 1 )
|
||||
Gia_ManFromIfGetConfig( vConfigs, pIfMan, pCutBest, pIfObj->iCopy, vConfigsStr );
|
||||
else if ( vConfigs2 && Vec_IntSize(vLeaves) > 1 && !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(pIfObj->iCopy))) && pIfObj->iCopy > 1 ) {
|
||||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k )
|
||||
if ( Abc_LitIsCompl(pIfLeaf->iCopy) )
|
||||
Abc_TtFlip( pTruth, Abc_TtWordNum(pCutBest->nLeaves), k );
|
||||
if ( Abc_LitIsCompl(pIfObj->iCopy) ^ pCutBest->fCompl )
|
||||
Abc_TtNot( pTruth, Abc_TtWordNum(pCutBest->nLeaves) );
|
||||
if ( pIfMan->pPars->fDelayOptCell )
|
||||
{
|
||||
pIfMan->nCutLeavesCur = pCutBest->nLeaves;
|
||||
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k )
|
||||
{
|
||||
pIfMan->pCutLeavesCur[k] = pIfLeaf->Id;
|
||||
pIfMan->pCutLeafArrCur[k] = If_ObjCutBest(pIfLeaf)->Delay;
|
||||
}
|
||||
}
|
||||
Gia_ManFromIfGetConfig2( vConfigs2, pIfMan, pTruth, pCutBest->nLeaves, pIfMan->pPars->fDelayOptCell );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2011,11 +2645,14 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
|
|||
assert( pNew->vPacking == NULL );
|
||||
assert( pNew->vConfigs == NULL );
|
||||
assert( pNew->pCellStr == NULL );
|
||||
assert( pNew->vConfigs2== NULL );
|
||||
pNew->vMapping = vMapping;
|
||||
pNew->vPacking = vPacking;
|
||||
pNew->vConfigs = vConfigs;
|
||||
pNew->pCellStr = vConfigs ? Abc_UtilStrsav( If_DsdManGetCellStr(pIfMan->pIfDsdMan) ) : NULL;
|
||||
assert( !vConfigs || Vec_IntSize(vConfigs) == 2 + Vec_IntEntry(vConfigs, 0) * Vec_IntEntry(vConfigs, 1) );
|
||||
pNew->vConfigs2= vConfigs2;
|
||||
assert( !vConfigs || Vec_IntSize(vConfigs) == 2 + Vec_IntEntry(vConfigs, 0) * Vec_IntEntry(vConfigs, 1) );
|
||||
// vConfigs2 is now a byte vector, no fixed size relationship
|
||||
// verify that COs have mapping
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
|
|
@ -2104,7 +2741,7 @@ void Gia_ManMappingVerify( Gia_Man_t * p )
|
|||
continue;
|
||||
if ( !Gia_ObjIsLut(p, Gia_ObjId(p, pFanin)) )
|
||||
{
|
||||
Abc_Print( -1, "Gia_ManMappingVerify: CO driver %d does not have mapping.\n", Gia_ObjId(p, pFanin) );
|
||||
Abc_Print( -1, "Gia_ManMappingVerify: Buffer driver %d does not have mapping.\n", Gia_ObjId(p, pFanin) );
|
||||
Result = 0;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -2206,6 +2843,8 @@ void Gia_ManTransferPacking( Gia_Man_t * p, Gia_Man_t * pGia )
|
|||
}
|
||||
void Gia_ManTransferTiming( Gia_Man_t * p, Gia_Man_t * pGia )
|
||||
{
|
||||
if ( p == pGia )
|
||||
return;
|
||||
if ( pGia->vCiArrs || pGia->vCoReqs || pGia->vCoArrs || pGia->vCoAttrs )
|
||||
{
|
||||
p->vCiArrs = pGia->vCiArrs; pGia->vCiArrs = NULL;
|
||||
|
|
@ -2233,13 +2872,18 @@ void Gia_ManTransferTiming( Gia_Man_t * p, Gia_Man_t * pGia )
|
|||
p->vConfigs = pGia->vConfigs; pGia->vConfigs = NULL;
|
||||
p->pCellStr = pGia->pCellStr; pGia->pCellStr = NULL;
|
||||
}
|
||||
if ( pGia->pManTime == NULL || p == pGia )
|
||||
if ( pGia->vConfigs2 )
|
||||
{
|
||||
p->vConfigs2 = pGia->vConfigs2; pGia->vConfigs2 = NULL;
|
||||
}
|
||||
if ( pGia->pManTime == NULL )
|
||||
return;
|
||||
p->pManTime = pGia->pManTime; pGia->pManTime = NULL;
|
||||
p->pAigExtra = pGia->pAigExtra; pGia->pAigExtra = NULL;
|
||||
p->vRegClasses = pGia->vRegClasses; pGia->vRegClasses = NULL;
|
||||
p->vRegInits = pGia->vRegInits; pGia->vRegInits = NULL;
|
||||
p->nAnd2Delay = pGia->nAnd2Delay; pGia->nAnd2Delay = 0;
|
||||
p->pManTime = pGia->pManTime; pGia->pManTime = NULL;
|
||||
p->pAigExtra = pGia->pAigExtra; pGia->pAigExtra = NULL;
|
||||
p->vRegClasses = pGia->vRegClasses; pGia->vRegClasses = NULL;
|
||||
p->vRegInits = pGia->vRegInits; pGia->vRegInits = NULL;
|
||||
p->vFlopClasses = pGia->vFlopClasses; pGia->vFlopClasses = NULL;
|
||||
p->nAnd2Delay = pGia->nAnd2Delay; pGia->nAnd2Delay = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -2356,8 +3000,33 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars )
|
|||
pPars->pTimesReq[i] = EntryF;
|
||||
}
|
||||
*/
|
||||
if ( p->pManTime && pPars->pTimesArr == NULL )
|
||||
{
|
||||
Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
|
||||
pPars->pTimesArr = ABC_CALLOC( float, Gia_ManCiNum(p) );
|
||||
for ( i = 0; i < Gia_ManCiNum(p); i++ )
|
||||
pPars->pTimesArr[i] = Tim_ManGetCiArrival( pManTime, i );
|
||||
}
|
||||
if ( p->pManTime && pPars->pTimesReq == NULL )
|
||||
{
|
||||
Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
|
||||
int fHasFiniteReq = 0;
|
||||
for ( i = 0; i < Gia_ManCoNum(p); i++ )
|
||||
if ( Tim_ManGetCoRequired( pManTime, i ) < TIM_ETERNITY )
|
||||
{
|
||||
fHasFiniteReq = 1;
|
||||
break;
|
||||
}
|
||||
if ( fHasFiniteReq )
|
||||
{
|
||||
pPars->pTimesReq = ABC_CALLOC( float, Gia_ManCoNum(p) );
|
||||
for ( i = 0; i < Gia_ManCoNum(p); i++ )
|
||||
pPars->pTimesReq[i] = Tim_ManGetCoRequired( pManTime, i );
|
||||
}
|
||||
}
|
||||
ABC_FREE( p->pCellStr );
|
||||
Vec_IntFreeP( &p->vConfigs );
|
||||
Vec_StrFreeP( &p->vConfigs2 );
|
||||
// disable cut minimization when GIA strucure is needed
|
||||
if ( !pPars->fDelayOpt && !pPars->fDelayOptLut && !pPars->fDsdBalance && !pPars->fUserRecLib && !pPars->fUserSesLib && !pPars->fDeriveLuts && !pPars->fUseDsd && !pPars->fUseTtPerm && !pPars->pFuncCell2 )
|
||||
pPars->fCutMin = 0;
|
||||
|
|
@ -2422,7 +3091,7 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars )
|
|||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
// print delay trace
|
||||
if ( pPars->fVerboseTrace )
|
||||
if ( pPars->fVerboseTrace && !pPars->fEnableCheck07 )
|
||||
{
|
||||
pNew->pLutLib = pPars->pLutLib;
|
||||
Gia_ManDelayTraceLutPrint( pNew, 1 );
|
||||
|
|
@ -2642,6 +3311,85 @@ Gia_Man_t * Gia_ManDupHashMapping( Gia_Man_t * p )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Uniqifies AIG nodes within each mapped cut.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManDupCollectedCutNodes_rec( Gia_Man_t * p, int iLut, Vec_Int_t * vNodes )
|
||||
{
|
||||
if ( Gia_ObjUpdateTravIdCurrentId(p, iLut) )
|
||||
return;
|
||||
Gia_ManDupCollectedCutNodes_rec( p, Gia_ObjFaninId0p(p, Gia_ManObj(p, iLut)), vNodes );
|
||||
Gia_ManDupCollectedCutNodes_rec( p, Gia_ObjFaninId1p(p, Gia_ManObj(p, iLut)), vNodes );
|
||||
Vec_IntPush( vNodes, iLut );
|
||||
}
|
||||
void Gia_ManDupCollectedCutNodes( Gia_Man_t * p, int iLut, Vec_Int_t * vNodes )
|
||||
{
|
||||
Gia_ManIncrementTravId(p);
|
||||
Vec_IntClear( vNodes );
|
||||
int k, iFan;
|
||||
Gia_LutForEachFanin( p, iLut, iFan, k )
|
||||
Gia_ObjSetTravIdCurrentId(p, iFan);
|
||||
assert( !Gia_ObjIsTravIdCurrentId(p, iLut) );
|
||||
Gia_ManDupCollectedCutNodes_rec( p, iLut, vNodes );
|
||||
assert( Gia_ObjIsTravIdCurrentId(p, iLut) );
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupUnhashMapping( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
Vec_Int_t * vMapping;
|
||||
Gia_Obj_t * pObj, * pFanin;
|
||||
Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vMap = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
int i, k, iTempLit;
|
||||
assert( Gia_ManHasMapping(p) );
|
||||
// copy the old manager with hashing
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi( pNew );
|
||||
Gia_ManForEachLut( p, i )
|
||||
{
|
||||
Gia_ManDupCollectedCutNodes( p, i, vNodes );
|
||||
Gia_ManForEachObjVec( vNodes, p, pObj, k )
|
||||
Vec_IntWriteEntry( vMap, Gia_ObjId(p, pObj), pObj->Value );
|
||||
Gia_ManForEachObjVec( vNodes, p, pObj, k )
|
||||
pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
iTempLit = Gia_ManObj(p, i)->Value;
|
||||
Gia_ManForEachObjVec( vNodes, p, pObj, k )
|
||||
pObj->Value = Vec_IntEntry( vMap, Gia_ObjId(p, pObj) );
|
||||
Gia_ManObj(p, i)->Value = iTempLit;
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
// recreate mapping
|
||||
vMapping = Vec_IntAlloc( Vec_IntSize(p->vMapping) );
|
||||
Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 );
|
||||
Gia_ManForEachLut( p, i )
|
||||
{
|
||||
pObj = Gia_ManObj( p, i );
|
||||
Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) );
|
||||
Vec_IntPush( vMapping, Gia_ObjLutSize(p, i) );
|
||||
Gia_LutForEachFaninObj( p, i, pFanin, k )
|
||||
Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) );
|
||||
Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) );
|
||||
}
|
||||
Vec_IntFree( vMap );
|
||||
pNew->vMapping = vMapping;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
@ -2649,4 +3397,3 @@ Gia_Man_t * Gia_ManDupHashMapping( Gia_Man_t * p )
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ Vec_Wec_t * Gia_Iso4Gia( Gia_Man_t * p )
|
|||
Vec_WecForEachLevel( vLevs, vLevel, l )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
int RandC[2] = { Abc_Random(0), Abc_Random(0) };
|
||||
unsigned RandC[2] = { Abc_Random(0), Abc_Random(0) };
|
||||
if ( l == 0 )
|
||||
{
|
||||
Gia_ManForEachObjVec( vLevel, p, pObj, i )
|
||||
|
|
|
|||
|
|
@ -21,13 +21,18 @@
|
|||
#include "gia.h"
|
||||
#include "misc/vec/vecSet.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define unlink _unlink
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
#include "../lib/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1838,6 +1838,12 @@ static inline int Lf_ManDerivePart( Lf_Man_t * p, Gia_Man_t * pNew, Vec_Int_t *
|
|||
}
|
||||
pTruth = Lf_CutTruth( p, pCut );
|
||||
iLit = Kit_TruthToGia( pNew, (unsigned *)pTruth, Vec_IntSize(vLeaves), vCover, vLeaves, 0 );
|
||||
// do not create LUT in the simple case
|
||||
if ( Abc_Lit2Var(iLit) == 0 )
|
||||
return iLit;
|
||||
Vec_IntForEachEntry( vLeaves, iTemp, k )
|
||||
if ( Abc_Lit2Var(iLit) == Abc_Lit2Var(iTemp) )
|
||||
return iLit;
|
||||
// create mapping
|
||||
Vec_IntSetEntry( vMapping, Abc_Lit2Var(iLit), Vec_IntSize(vMapping2) );
|
||||
Vec_IntPush( vMapping2, Vec_IntSize(vLeaves) );
|
||||
|
|
@ -2306,8 +2312,8 @@ Gia_Man_t * Gia_ManPerformLfMapping( Gia_Man_t * p, Jf_Par_t * pPars, int fNorma
|
|||
Gia_ManTransferTiming( pNew, p );
|
||||
p = pNew;
|
||||
// set arrival and required times
|
||||
pPars->pTimesArr = Tim_ManGetArrTimes( (Tim_Man_t *)p->pManTime );
|
||||
pPars->pTimesReq = Tim_ManGetReqTimes( (Tim_Man_t *)p->pManTime );
|
||||
pPars->pTimesArr = Tim_ManGetArrTimes( (Tim_Man_t *)p->pManTime, Gia_ManRegNum(p) );
|
||||
pPars->pTimesReq = Tim_ManGetReqTimes( (Tim_Man_t *)p->pManTime, Gia_ManRegNum(p) );
|
||||
}
|
||||
else
|
||||
p = Gia_ManDup( p );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,304 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaLutCas.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [LUT cascade generator.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaLutCas.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include "sat/cnf/cnf.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "sat/cadical/cadicalSolver.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManGenSymFun_rec( Gia_Man_t * p, word Str, int nChars, Vec_Ptr_t * vStrs, Vec_Wec_t * vLits, Vec_Int_t * vIns )
|
||||
{
|
||||
if ( Str == 0 ) return 0;
|
||||
if ( Str == Abc_Tt6Mask(nChars) ) return 1;
|
||||
assert( nChars > 1 );
|
||||
Vec_Wrd_t * vStore = (Vec_Wrd_t *)Vec_PtrEntry(vStrs, nChars-1);
|
||||
Vec_Int_t * vValue = Vec_WecEntry(vLits, nChars-1);
|
||||
int Index;
|
||||
if ( (Index = Vec_WrdFind(vStore, Str)) >= 0 )
|
||||
return Vec_IntEntry(vValue, Index);
|
||||
word Str0 = Str & ~Abc_Tt6MaskI(nChars-1);
|
||||
word Str1 = Str >> 1;
|
||||
int Lit0 = Gia_ManGenSymFun_rec( p, Str0, nChars-1, vStrs, vLits, vIns );
|
||||
int Lit1 = Gia_ManGenSymFun_rec( p, Str1, nChars-1, vStrs, vLits, vIns );
|
||||
int Lit = Gia_ManAppendMux2( p, Vec_IntEntry(vIns, nChars-2), Lit1, Lit0 );
|
||||
Vec_WrdPush( vStore, Str );
|
||||
Vec_WrdPush( vStore, ~Str & Abc_Tt6Mask(nChars) );
|
||||
Vec_IntPush( vValue, Lit );
|
||||
Vec_IntPush( vValue, Abc_LitNot(Lit) );
|
||||
return Lit;
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenSymFun( Vec_Wrd_t * vFuns, int nChars, int fVerbose )
|
||||
{
|
||||
assert( nChars <= 64 );
|
||||
word Str; int i;
|
||||
Vec_Ptr_t * vStrs = Vec_PtrAlloc(nChars);
|
||||
for ( i = 0; i < nChars; i++ )
|
||||
Vec_PtrPush( vStrs, Vec_WrdAlloc(0) );
|
||||
Vec_Wec_t * vLits = Vec_WecStart(nChars);
|
||||
Vec_Int_t * vOuts = Vec_IntAlloc(Vec_WrdSize(vFuns));
|
||||
Gia_Man_t * pNew = Gia_ManStart( 10000 );
|
||||
pNew->pName = Abc_UtilStrsav( "sym" );
|
||||
Vec_Int_t * vIns = Vec_IntAlloc(nChars-1);
|
||||
for ( i = 0; i < nChars-1; i++ )
|
||||
Vec_IntPush(vIns, Gia_ManAppendCi(pNew));
|
||||
Vec_WrdForEachEntry( vFuns, Str, i )
|
||||
Vec_IntPush( vOuts, Gia_ManGenSymFun_rec(pNew, Str, nChars, vStrs, vLits, vIns ) );
|
||||
Vec_WrdForEachEntry( vFuns, Str, i )
|
||||
Gia_ManAppendCo(pNew, Vec_IntEntry(vOuts,i) );
|
||||
for ( i = 0; i < nChars; i++ )
|
||||
Vec_WrdFree( (Vec_Wrd_t *)Vec_PtrEntry(vStrs, i) );
|
||||
Vec_PtrFree(vStrs);
|
||||
Vec_WecFree(vLits);
|
||||
Vec_IntFree(vOuts);
|
||||
Vec_IntFree(vIns);
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Gia_LutCasSort( char * pStr, int iStart, int nChars )
|
||||
{
|
||||
int i, j;
|
||||
for ( i = iStart; i < iStart + nChars - 1; i++ )
|
||||
for ( j = i + 1; j < iStart + nChars; j++ )
|
||||
if ( pStr[i] > pStr[j] )
|
||||
ABC_SWAP( char, pStr[i], pStr[j] );
|
||||
}
|
||||
char * Gia_LutCasPerm( int nVars, int nLuts, int LutSize )
|
||||
{
|
||||
assert( nVars <= 26 && nLuts <= 100 );
|
||||
int nStrLen = nLuts * LutSize;
|
||||
char * pRes = ABC_CALLOC( char, nStrLen+1 );
|
||||
int i, j, iVar, pPerm[26], nVarCount[100] = {0};
|
||||
// create a random permutation
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
pPerm[i] = i;
|
||||
for ( i = nVars - 1; i > 0; i-- ) {
|
||||
j = rand() % (i + 1);
|
||||
ABC_SWAP( int, pPerm[i], pPerm[j] );
|
||||
}
|
||||
// assign the first variable
|
||||
for ( i = 0; i < nLuts; i++ ) {
|
||||
pRes[i * LutSize] = i ? '_' : 'a' + pPerm[0];
|
||||
nVarCount[i] = 1;
|
||||
}
|
||||
// First pass: distribute each variable (starting from the second in permutation) to at least one LUT
|
||||
for ( i = 1; i < nVars; i++ ) {
|
||||
// Find a LUT with space that doesn't have this variable
|
||||
int Tries = 0, iLut = rand() % nLuts;
|
||||
while ( nVarCount[iLut] >= LutSize && Tries++ < nLuts )
|
||||
iLut = (iLut + 1) % nLuts;
|
||||
// the variables are unique - no need to check this
|
||||
pRes[iLut * LutSize + nVarCount[iLut]] = 'a' + pPerm[i];
|
||||
nVarCount[iLut]++;
|
||||
}
|
||||
// Second pass: fill remaining slots with random variables (cycling through permutation)
|
||||
for ( i = 0; i < nLuts; i++ ) {
|
||||
while ( nVarCount[i] < LutSize ) {
|
||||
iVar = pPerm[rand() % nVars];
|
||||
// Check this LUT already has this variable
|
||||
for ( j = 0; j < nVarCount[i]; j++ )
|
||||
if ( pRes[i * LutSize + j] == 'a' + iVar )
|
||||
break;
|
||||
if ( j == nVarCount[i] ) { // does not have
|
||||
pRes[i * LutSize + nVarCount[i]] = 'a' + iVar;
|
||||
nVarCount[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sort inputs within each LUT (skip '_' for non-first LUTs)
|
||||
Gia_LutCasSort( pRes, 0, LutSize );
|
||||
for ( i = 1; i < nLuts; i++ )
|
||||
Gia_LutCasSort( pRes + i * LutSize, 1, LutSize-1 );
|
||||
return pRes;
|
||||
}
|
||||
int Gia_ManGenLutCas_rec( Gia_Man_t * pNew, Vec_Int_t * vCtrls, int iCtrl, Vec_Int_t * vDatas, int Shift, int Offset )
|
||||
{
|
||||
if ( iCtrl-- == 0 )
|
||||
return Vec_IntEntry( vDatas, Shift );
|
||||
int iLit0 = Gia_ManGenLutCas_rec( pNew, vCtrls, iCtrl, vDatas, Shift, Offset );
|
||||
int iLit1 = Gia_ManGenLutCas_rec( pNew, vCtrls, iCtrl, vDatas, Shift + (1<<iCtrl), Offset );
|
||||
return Gia_ManAppendMux( pNew, Vec_IntEntry(vCtrls, iCtrl+Offset), iLit1, iLit0 );
|
||||
}
|
||||
int Gia_ManGenWire( Gia_Man_t * pNew, Vec_Int_t * vCtrls, Vec_Int_t * vParams2, int iParam2 )
|
||||
{
|
||||
int nVars = Vec_IntSize(vCtrls);
|
||||
int nBits = Abc_Base2Log(nVars);
|
||||
while ( Vec_IntSize(vCtrls) < (1 << nBits) )
|
||||
Vec_IntPush( vCtrls, 0 );
|
||||
int iRes = Gia_ManGenLutCas_rec( pNew, vParams2, nBits, vCtrls, 0, iParam2 );
|
||||
Vec_IntShrink( vCtrls, nVars );
|
||||
return iRes;
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenLutCas( Gia_Man_t * p, char * pPermStr, int nVars, int nLuts, int LutSize, int Seed, int fVerbose )
|
||||
{
|
||||
if ( Seed )
|
||||
srand(Seed);
|
||||
else {
|
||||
#ifdef _WIN32
|
||||
unsigned int seed = (unsigned int)GetTickCount();
|
||||
#else
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
unsigned int seed = (unsigned int)(ts.tv_sec ^ ts.tv_nsec);
|
||||
#endif
|
||||
srand(seed);
|
||||
}
|
||||
int fOwnPerm = (pPermStr == NULL);
|
||||
char * pPerm = fOwnPerm ? Gia_LutCasPerm( nVars, nLuts, LutSize ) : pPermStr;
|
||||
int nParams = nLuts * (1 << LutSize);
|
||||
// count how many variables are unassigned in the permutation
|
||||
int nParams2 = 0;
|
||||
for ( int v = 0; v < strlen(pPerm); v++ )
|
||||
if ( pPerm[v] == '*' )
|
||||
nParams2 += Abc_Base2Log(nVars);
|
||||
if ( fVerbose )
|
||||
printf( "Generating AIG with %d parameters (%d functional + %d structural) and %d inputs using fanin assignment \"%s\".\n",
|
||||
nParams+nParams2, nParams, nParams2, nVars, pPerm );
|
||||
Gia_Man_t * pNew = Gia_ManStart( nParams + nVars );
|
||||
pNew->pName = Abc_UtilStrsav( pPerm );
|
||||
Vec_Int_t * vDatas = Vec_IntAlloc( nParams );
|
||||
Vec_Int_t * vWires = Vec_IntAlloc( nParams2 );
|
||||
Vec_Int_t * vCtrls = Vec_IntAlloc( nVars );
|
||||
for ( int i = 0; i < nParams; i++ )
|
||||
Vec_IntPush( vDatas, Gia_ManAppendCi(pNew) );
|
||||
for ( int i = 0; i < nParams2; i++ )
|
||||
Vec_IntPush( vWires, Gia_ManAppendCi(pNew) );
|
||||
for ( int i = 0; i < nVars; i++ )
|
||||
Vec_IntPush( vCtrls, Gia_ManAppendCi(pNew) );
|
||||
Vec_Int_t * vLits = Vec_IntStart( LutSize );
|
||||
Vec_IntWriteEntry( vLits, 0, pPerm[0] == '*' ? Gia_ManGenWire(pNew, vCtrls, vWires, 0) : Vec_IntEntry(vCtrls, (int)(pPerm[0]-'a')) );
|
||||
int iWireVars = pPerm[0] == '*' ? Abc_Base2Log(nVars) : 0;
|
||||
char * pCur = pPerm;
|
||||
for ( int i = 0; i < nLuts; i++ ) {
|
||||
assert( i == 0 || *pCur == '_' );
|
||||
pCur++;
|
||||
for ( int k = 1; k < LutSize; k++ ) {
|
||||
Vec_IntWriteEntry( vLits, k, *pCur == '*' ? Gia_ManGenWire(pNew, vCtrls, vWires, iWireVars) : Vec_IntEntry(vCtrls, (int)(*pCur - 'a')) );
|
||||
iWireVars += *pCur++ == '*' ? Abc_Base2Log(nVars) : 0;
|
||||
}
|
||||
Vec_IntWriteEntry( vLits, 0, Gia_ManGenLutCas_rec(pNew, vLits, LutSize, vDatas, i * (1 << LutSize), 0) );
|
||||
}
|
||||
assert( iWireVars == nParams2 );
|
||||
// if the AIG is given, create a miter
|
||||
int iLit = Vec_IntEntry(vLits, 0);
|
||||
if ( p ) {
|
||||
assert( Gia_ManCiNum(p) == nVars );
|
||||
assert( Gia_ManCoNum(p) == 1 );
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Vec_IntEntry(vCtrls, i);
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
iLit = Gia_ManAppendXor( pNew, iLit, Gia_ObjFanin0Copy(Gia_ManCo(p, 0)) );
|
||||
iLit = Abc_LitNot(iLit);
|
||||
}
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
Vec_IntFree( vDatas );
|
||||
Vec_IntFree( vCtrls );
|
||||
Vec_IntFree( vWires );
|
||||
Vec_IntFree( vLits );
|
||||
if ( fOwnPerm )
|
||||
ABC_FREE( pPerm );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/*
|
||||
int Gia_ManGenLutCasSolve( int nVars, int nLuts, int LutSize, char * pTtStr, int fVerbose )
|
||||
{
|
||||
extern Gia_Man_t * Gia_QbfQuantifyAll( Gia_Man_t * p, int nPars, int fAndAll, int fOrAll );
|
||||
assert( strlen(pTtStr) <= 1024 );
|
||||
word pTruth[64] = {0};
|
||||
int i, Id, nVars = Abc_TtReadHex( pTruth, pTtStr );
|
||||
assert( nVars <= 12 );
|
||||
int nParams = nLuts * (1 << LutSize);
|
||||
Gia_Man_t * pCas = Gia_ManGenLutCas( NULL, NULL, nVars, nLuts, LutSize, 0, fVerbose );
|
||||
Gia_Man_t * pCofs = Gia_QbfQuantifyAll( pCas, nParams, 0, 0 );
|
||||
Gia_ManFree( pCas );
|
||||
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCofs, 8, 0, 0, 0, 0 );
|
||||
cadical_solver* pSat = cadical_solver_new(void);
|
||||
cadical_solver_setnvars( pSat, pCnf->nVars );
|
||||
// add output literals
|
||||
assert( Gia_ManCoNum(pCofs) == (1 << nVars) );
|
||||
Gia_ManForEachCoId( pCofs, Id, i ) {
|
||||
int Lit = Abc_Var2Lit(pCnf->pVarNums[Id], Abc_TtGetBit(pTruth, i));
|
||||
int status = cadical_solver_addclause( pSat, &Lit, &Lit+1 );
|
||||
}
|
||||
for ( i = 0; i < pCnf->nClauses; i++ )
|
||||
if ( !cadical_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) {
|
||||
Cnf_DataFree( pCnf );
|
||||
return 0;
|
||||
}
|
||||
Cnf_DataFree( pCnf );
|
||||
Gia_ManFree( pCofs );
|
||||
int status = cadical_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
|
||||
for ( i = 0; i < nLuts; i++, printf(" ") )
|
||||
for ( k = 0; k < (1 << LutSize); k++ ) {
|
||||
int Value = cadical_solver_get_var_value(pSat, i*(1 << LutSize) + k);
|
||||
printf( "%d", Value );
|
||||
}
|
||||
cadical_solver_delete( pSat );
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
1140
src/aig/gia/giaMan.c
1140
src/aig/gia/giaMan.c
File diff suppressed because it is too large
Load Diff
|
|
@ -1789,7 +1789,7 @@ void Mf_ManOptimization( Mf_Man_t * p )
|
|||
Gia_Man_t * pGia = p->pGia0;
|
||||
int i, Count, nNodes = Mf_ManMappingFromMapping( p );
|
||||
Gia_ManLevelNum( pGia );
|
||||
Gia_ManStaticMappingFanoutStart( pGia );
|
||||
Gia_ManStaticMappingFanoutStart( pGia, NULL );
|
||||
Mf_ManPrintFanoutProfile( p, pGia->vFanoutNums );
|
||||
printf( "\nIndividual logic cones for mapping with %d nodes:\n", nNodes );
|
||||
Vec_IntForEachEntry( pGia->vFanoutNums, Count, i )
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ Sfm_Ntk_t * Gia_ManExtractMfs( Gia_Man_t * p )
|
|||
int nBoxes = Gia_ManBoxNum(p), nVars;
|
||||
int nRealPis = nBoxes ? Tim_ManPiNum(pManTime) : Gia_ManPiNum(p);
|
||||
int nRealPos = nBoxes ? Tim_ManPoNum(pManTime) : Gia_ManPoNum(p);
|
||||
int i, j, k, curCi, curCo, nBoxIns, nBoxOuts;
|
||||
int i, j, k, curCi, curCo, nBoxIns, nBoxOuts, w, nWords;
|
||||
int Id, iFan, nMfsVars, nBbIns = 0, nBbOuts = 0, Counter = 0;
|
||||
int nLutSizeMax = Gia_ManLutSizeMax( p );
|
||||
nLutSizeMax = Abc_MaxInt( nLutSizeMax, 6 );
|
||||
|
|
@ -113,15 +113,11 @@ Sfm_Ntk_t * Gia_ManExtractMfs( Gia_Man_t * p )
|
|||
pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ManObj(p, Id), vLeaves );
|
||||
nVars = Abc_TtMinBase( pTruth, Vec_IntArray(vArray), Vec_IntSize(vArray), Vec_IntSize(vLeaves) );
|
||||
Vec_IntShrink( vArray, nVars );
|
||||
if ( nVars <= 6 )
|
||||
Vec_WrdWriteEntry( vTruths, Counter, pTruth[0] );
|
||||
else
|
||||
{
|
||||
int w, nWords = Abc_Truth6WordNum( nVars );
|
||||
Vec_IntWriteEntry( vStarts, Counter, Vec_WrdSize(vTruths2) );
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
Vec_WrdPush( vTruths2, pTruth[w] );
|
||||
}
|
||||
Vec_WrdWriteEntry( vTruths, Counter, pTruth[0] );
|
||||
nWords = Abc_Truth6WordNum( nVars );
|
||||
Vec_IntWriteEntry( vStarts, Counter, Vec_WrdSize(vTruths2) );
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
Vec_WrdPush( vTruths2, pTruth[w] );
|
||||
if ( Gia_ObjLutIsMux(p, Id) )
|
||||
{
|
||||
Vec_StrWriteEntry( vFixed, Counter, (char)1 );
|
||||
|
|
@ -143,6 +139,8 @@ Sfm_Ntk_t * Gia_ManExtractMfs( Gia_Man_t * p )
|
|||
Vec_StrWriteEntry( vEmpty, Counter, (char)1 );
|
||||
uTruth = Gia_ObjFaninC0(pObj) ? ~uTruths6[0]: uTruths6[0];
|
||||
Vec_WrdWriteEntry( vTruths, Counter, uTruth );
|
||||
Vec_IntWriteEntry( vStarts, Counter, Vec_WrdSize(vTruths2) );
|
||||
Vec_WrdPush( vTruths2, uTruth );
|
||||
}
|
||||
Gia_ObjSetCopyArray( p, Gia_ObjId(p, pObj), Counter++ );
|
||||
}
|
||||
|
|
@ -292,15 +290,19 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
|
|||
int nBoxes = Gia_ManBoxNum(p);
|
||||
int nRealPis = nBoxes ? Tim_ManPiNum(pManTime) : Gia_ManPiNum(p);
|
||||
int nRealPos = nBoxes ? Tim_ManPoNum(pManTime) : Gia_ManPoNum(p);
|
||||
int i, k, Id, curCi, curCo, nBoxIns, nBoxOuts, iLitNew, iMfsId, iGroup, Fanin;
|
||||
int i, k, curCi, curCo, nBoxIns, nBoxOuts, iLitNew, iMfsId, iGroup, Fanin, iBox;
|
||||
int nMfsNodes;
|
||||
word * pTruth, uTruthVar = ABC_CONST(0xAAAAAAAAAAAAAAAA);
|
||||
Vec_Wec_t * vGroups = Vec_WecStart( nBoxes );
|
||||
Vec_Int_t * vMfs2Gia, * vMfs2Old;
|
||||
Vec_Int_t * vGroupMap;
|
||||
Vec_Int_t * vMfsTopo, * vCover, * vBoxesLeft;
|
||||
Vec_Int_t * vMfsTopo, * vCover, * vBoxesLeft, * vBoxKeep;
|
||||
Vec_Int_t * vArray, * vLeaves;
|
||||
Vec_Int_t * vMapping, * vMapping2;
|
||||
Vec_Int_t * vCoDrivers;
|
||||
Vec_Int_t * vPiBoxes = NULL;
|
||||
Vec_Int_t * vBbCiMap = NULL;
|
||||
Vec_Int_t * vBbOutLit = NULL;
|
||||
int nBbIns = 0, nBbOuts = 0;
|
||||
if ( pManTime ) Tim_ManBlackBoxIoNum( pManTime, &nBbIns, &nBbOuts );
|
||||
nMfsNodes = 1 + Gia_ManCiNum(p) + Gia_ManLutNum(p) + Gia_ManCoNum(p) + nBbIns + nBbOuts;
|
||||
|
|
@ -342,8 +344,40 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
|
|||
assert( curCo == Gia_ManCoNum(p) );
|
||||
|
||||
// collect nodes in the given order
|
||||
if ( nBbOuts > 0 )
|
||||
{
|
||||
int iBbOut = 0;
|
||||
vPiBoxes = Vec_IntStartFull( nBbOuts + nRealPis );
|
||||
vBbCiMap = Vec_IntStartFull( Gia_ManCiNum(p) );
|
||||
vBbOutLit = Vec_IntStartFull( nBbOuts );
|
||||
curCi = nRealPis;
|
||||
curCo = 0;
|
||||
for ( i = 0; i < nBoxes; i++ )
|
||||
{
|
||||
nBoxIns = Tim_ManBoxInputNum( pManTime, i );
|
||||
nBoxOuts = Tim_ManBoxOutputNum( pManTime, i );
|
||||
if ( Tim_ManBoxIsBlack(pManTime, i) )
|
||||
for ( k = 0; k < nBoxOuts; k++ )
|
||||
{
|
||||
assert( iBbOut < nBbOuts );
|
||||
Vec_IntWriteEntry( vPiBoxes, iBbOut, i );
|
||||
Vec_IntWriteEntry( vBbCiMap, curCi + k, iBbOut );
|
||||
iBbOut++;
|
||||
}
|
||||
curCo += nBoxIns;
|
||||
curCi += nBoxOuts;
|
||||
}
|
||||
curCo += nRealPos;
|
||||
assert( curCi == Gia_ManCiNum(p) );
|
||||
assert( curCo == Gia_ManCoNum(p) );
|
||||
assert( iBbOut == nBbOuts );
|
||||
}
|
||||
vBoxesLeft = Vec_IntAlloc( nBoxes );
|
||||
vMfsTopo = Sfm_NtkDfs( pNtk, vGroups, vGroupMap, vBoxesLeft, fAllBoxes );
|
||||
vMfsTopo = Sfm_NtkDfs( pNtk, vGroups, vGroupMap, vBoxesLeft, fAllBoxes, vPiBoxes );
|
||||
Vec_IntUniqify( vBoxesLeft ); // reduce to sorted unique indices expected by the timing manager
|
||||
vBoxKeep = Vec_IntStart( nBoxes );
|
||||
Vec_IntForEachEntry( vBoxesLeft, iBox, i )
|
||||
Vec_IntWriteEntry( vBoxKeep, iBox, 1 );
|
||||
assert( Vec_IntSize(vBoxesLeft) <= nBoxes );
|
||||
assert( Vec_IntSize(vMfsTopo) > 0 );
|
||||
|
||||
|
|
@ -362,13 +396,28 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
|
|||
|
||||
// map constant
|
||||
Vec_IntWriteEntry( vMfs2Gia, Gia_ObjCopyArray(p, 0), 0 );
|
||||
// map primary inputs
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
if ( i < nRealPis )
|
||||
Vec_IntWriteEntry( vMfs2Gia, Gia_ObjCopyArray(p, Id), Gia_ManAppendCi(pNew) );
|
||||
// map primary inputs (real ones and preserved box outputs)
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
{
|
||||
int iCiId = Gia_ObjId( p, pObj );
|
||||
int iBox = pManTime ? Tim_ManBoxForCi( pManTime, Gia_ObjCioId(pObj) ) : -1;
|
||||
int iBbOut = vBbCiMap ? Vec_IntEntry(vBbCiMap, i) : -1;
|
||||
if ( iBox >= 0 && !Vec_IntEntry(vBoxKeep, iBox) )
|
||||
{
|
||||
Vec_IntWriteEntry( vMfs2Gia, Gia_ObjCopyArray(p, iCiId), -1 );
|
||||
if ( iBbOut >= 0 && vBbOutLit )
|
||||
Vec_IntWriteEntry( vBbOutLit, iBbOut, -1 );
|
||||
continue;
|
||||
}
|
||||
iLitNew = Gia_ManAppendCi(pNew);
|
||||
Vec_IntWriteEntry( vMfs2Gia, Gia_ObjCopyArray(p, iCiId), iLitNew );
|
||||
if ( iBbOut >= 0 && vBbOutLit )
|
||||
Vec_IntWriteEntry( vBbOutLit, iBbOut, iLitNew );
|
||||
}
|
||||
// map internal nodes
|
||||
vLeaves = Vec_IntAlloc( 6 );
|
||||
vCover = Vec_IntAlloc( 1 << 16 );
|
||||
vCoDrivers = Vec_IntStartFull( Gia_ManCoNum(p) );
|
||||
Vec_IntForEachEntry( vMfsTopo, iMfsId, i )
|
||||
{
|
||||
pTruth = Sfm_NodeReadTruth( pNtk, iMfsId );
|
||||
|
|
@ -376,16 +425,21 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
|
|||
vArray = Sfm_NodeReadFanins( pNtk, iMfsId ); // belongs to pNtk
|
||||
if ( Vec_IntSize(vArray) == 1 && Vec_IntEntry(vArray,0) < nBbOuts ) // skip unreal inputs
|
||||
{
|
||||
// create CI for the output of black box
|
||||
assert( Abc_LitIsCompl(iGroup) );
|
||||
iLitNew = Gia_ManAppendCi( pNew );
|
||||
assert( vBbOutLit != NULL );
|
||||
iLitNew = Vec_IntEntry( vBbOutLit, Vec_IntEntry(vArray,0) );
|
||||
assert( iLitNew >= 0 );
|
||||
Vec_IntWriteEntry( vMfs2Gia, iMfsId, iLitNew );
|
||||
continue;
|
||||
}
|
||||
Vec_IntClear( vLeaves );
|
||||
Vec_IntForEachEntry( vArray, Fanin, k )
|
||||
{
|
||||
iLitNew = Vec_IntEntry( vMfs2Gia, Fanin ); assert( iLitNew >= 0 );
|
||||
if ( Fanin < nBbOuts )
|
||||
iLitNew = Vec_IntEntry( vBbOutLit, Fanin );
|
||||
else
|
||||
iLitNew = Vec_IntEntry( vMfs2Gia, Fanin );
|
||||
assert( iLitNew >= 0 );
|
||||
Vec_IntPush( vLeaves, iLitNew );
|
||||
}
|
||||
if ( iGroup == -1 ) // internal node
|
||||
|
|
@ -397,7 +451,9 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
|
|||
int nVarsNew;
|
||||
Abc_TtSimplify( pTruth, Vec_IntArray(vLeaves), Vec_IntSize(vLeaves), &nVarsNew );
|
||||
Vec_IntShrink( vLeaves, nVarsNew );
|
||||
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
|
||||
iLitNew = Gia_ManFromIfLogicCreateLut( pNew, pTruth, vLeaves, vCover, vMapping, vMapping2 );
|
||||
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
|
||||
if ( MapSize < Vec_IntSize(vMapping2) )
|
||||
{
|
||||
assert( Vec_IntEntryLast(vMapping2) == Abc_Lit2Var(iLitNew) );
|
||||
|
|
@ -405,38 +461,42 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
|
||||
iLitNew = Gia_ManFromIfLogicCreateLut( pNew, pTruth, vLeaves, vCover, vMapping, vMapping2 );
|
||||
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
|
||||
}
|
||||
}
|
||||
else if ( Abc_LitIsCompl(iGroup) ) // internal CI
|
||||
else if ( Abc_LitIsCompl(iGroup) ) // internal CI (box output)
|
||||
{
|
||||
//Dau_DsdPrintFromTruth( pTruth, Vec_IntSize(vLeaves) );
|
||||
iLitNew = Gia_ManAppendCi( pNew );
|
||||
iLitNew = Vec_IntEntry( vMfs2Gia, iMfsId );
|
||||
if ( iLitNew < 0 )
|
||||
continue;
|
||||
}
|
||||
else // internal CO
|
||||
{
|
||||
int iObjOld = Vec_IntEntry( vMfs2Old, iMfsId );
|
||||
int iCoIdx;
|
||||
assert( iObjOld >= 0 );
|
||||
assert( pTruth[0] == uTruthVar || pTruth[0] == ~uTruthVar );
|
||||
iLitNew = Gia_ManAppendCo( pNew, Abc_LitNotCond(Vec_IntEntry(vLeaves, 0), pTruth[0] == ~uTruthVar) );
|
||||
//printf("Group = %d. po = %d\n", iGroup>>1, iMfsId );
|
||||
iLitNew = Abc_LitNotCond( Vec_IntEntry(vLeaves, 0), pTruth[0] == ~uTruthVar );
|
||||
iCoIdx = Gia_ObjCioId( Gia_ManObj(p, iObjOld) );
|
||||
Vec_IntWriteEntry( vCoDrivers, iCoIdx, iLitNew );
|
||||
}
|
||||
Vec_IntWriteEntry( vMfs2Gia, iMfsId, iLitNew );
|
||||
}
|
||||
Vec_IntFree( vCover );
|
||||
Vec_IntFree( vLeaves );
|
||||
|
||||
// map primary outputs
|
||||
// map primary outputs (internal box inputs followed by real POs)
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
if ( i < Gia_ManCoNum(p) - nRealPos ) // internal COs
|
||||
if ( i < Gia_ManCoNum(p) - nRealPos )
|
||||
{
|
||||
iMfsId = Gia_ObjCopyArray( p, Gia_ObjId(p, pObj) );
|
||||
iGroup = Vec_IntEntry( vGroupMap, iMfsId );
|
||||
if ( Vec_IntFind(vMfsTopo, iGroup) >= 0 )
|
||||
{
|
||||
iLitNew = Vec_IntEntry( vMfs2Gia, iMfsId );
|
||||
if ( iLitNew < 0 )
|
||||
continue;
|
||||
assert( iLitNew >= 0 );
|
||||
}
|
||||
iLitNew = Vec_IntEntry( vCoDrivers, i );
|
||||
if ( iLitNew == -1 )
|
||||
continue;
|
||||
Gia_ManAppendCo( pNew, iLitNew );
|
||||
continue;
|
||||
}
|
||||
iLitNew = Vec_IntEntry( vMfs2Gia, Gia_ObjCopyArray(p, Gia_ObjFaninId0p(p, pObj)) );
|
||||
|
|
@ -479,6 +539,11 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
|
|||
Vec_IntFree( vMfs2Gia );
|
||||
Vec_IntFree( vMfs2Old );
|
||||
Vec_IntFree( vBoxesLeft );
|
||||
Vec_IntFree( vBoxKeep );
|
||||
Vec_IntFree( vCoDrivers );
|
||||
Vec_IntFreeP( &vPiBoxes );
|
||||
Vec_IntFreeP( &vBbCiMap );
|
||||
Vec_IntFreeP( &vBbOutLit );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
@ -497,7 +562,7 @@ Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars )
|
|||
{
|
||||
Sfm_Ntk_t * pNtk;
|
||||
Gia_Man_t * pNew;
|
||||
int nFaninMax, nNodes;
|
||||
int nFaninMax, nNodes = 0;
|
||||
assert( Gia_ManRegNum(p) == 0 );
|
||||
assert( p->vMapping != NULL );
|
||||
if ( p->pManTime != NULL && p->pAigExtra == NULL )
|
||||
|
|
@ -546,4 +611,3 @@ Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars )
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ Gia_Man_t * Vec_WrdReadTest( char * pFileName )
|
|||
void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO, int nIns, int nOuts )
|
||||
{
|
||||
int i, nSize, iLine, nLines, nWords;
|
||||
char pLine[1000];
|
||||
char pLine[2000];
|
||||
Vec_Wrd_t * vSimI, * vSimO;
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL )
|
||||
|
|
@ -214,7 +214,7 @@ void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO
|
|||
nWords = (nLines + 63)/64;
|
||||
vSimI = Vec_WrdStart( nIns *nWords );
|
||||
vSimO = Vec_WrdStart( nOuts*nWords );
|
||||
for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
|
||||
for ( iLine = 0; fgets( pLine, 2000, pFile ); iLine++ )
|
||||
{
|
||||
for ( i = 0; i < nIns; i++ )
|
||||
if ( pLine[nIns-1-i] == '1' )
|
||||
|
|
@ -233,7 +233,7 @@ void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO
|
|||
int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI )
|
||||
{
|
||||
int i, nSize, iLine, nLines, nWords, nIns;
|
||||
char pLine[1000];
|
||||
char pLine[2000];
|
||||
Vec_Wrd_t * vSimI;
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL )
|
||||
|
|
@ -241,7 +241,7 @@ int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI )
|
|||
printf( "Cannot open file \"%s\" for reading.\n", pFileName );
|
||||
return 0;
|
||||
}
|
||||
if ( !fgets(pLine, 1000, pFile) || (nIns = strlen(pLine)-1) < 1 )
|
||||
if ( !fgets(pLine, 2000, pFile) || (nIns = strlen(pLine)-1) < 1 )
|
||||
{
|
||||
printf( "Cannot find the number of inputs in file \"%s\".\n", pFileName );
|
||||
fclose( pFile );
|
||||
|
|
@ -259,7 +259,7 @@ int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI )
|
|||
nLines = nSize / (nIns + 1);
|
||||
nWords = (nLines + 63)/64;
|
||||
vSimI = Vec_WrdStart( nIns *nWords );
|
||||
for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
|
||||
for ( iLine = 0; fgets( pLine, 2000, pFile ); iLine++ )
|
||||
{
|
||||
for ( i = 0; i < nIns; i++ )
|
||||
if ( pLine[nIns-1-i] == '1' )
|
||||
|
|
|
|||
|
|
@ -182,13 +182,56 @@ void * Abc_FrameGiaOutputMiniAig( Abc_Frame_t * pAbc )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManReadMiniAigNames( char * pFileName, Gia_Man_t * pGia )
|
||||
{
|
||||
char * filename3 = Abc_UtilStrsavTwo( pFileName, ".ilo" );
|
||||
FILE * pFile = fopen( filename3, "rb" );
|
||||
if ( pFile )
|
||||
{
|
||||
char Buffer[5000], * pName; int i, iLines = 0;
|
||||
Vec_Ptr_t * vTemp = Vec_PtrAlloc( Gia_ManRegNum(pGia) );
|
||||
assert( pGia->vNamesIn == NULL );
|
||||
pGia->vNamesIn = Vec_PtrAlloc( Gia_ManCiNum(pGia) );
|
||||
assert( pGia->vNamesOut == NULL );
|
||||
pGia->vNamesOut = Vec_PtrAlloc( Gia_ManCoNum(pGia) );
|
||||
while ( fgets(Buffer, 5000, pFile) )
|
||||
{
|
||||
if ( Buffer[strlen(Buffer)-1] == '\n' )
|
||||
Buffer[strlen(Buffer)-1] = 0;
|
||||
if ( iLines < Gia_ManPiNum(pGia) )
|
||||
Vec_PtrPush( pGia->vNamesIn, Abc_UtilStrsav(Buffer) );
|
||||
else if ( iLines < Gia_ManCiNum(pGia) )
|
||||
Vec_PtrPush( vTemp, Abc_UtilStrsav(Buffer) );
|
||||
else
|
||||
Vec_PtrPush( pGia->vNamesOut, Abc_UtilStrsav(Buffer) );
|
||||
iLines++;
|
||||
}
|
||||
Vec_PtrForEachEntry( char *, vTemp, pName, i )
|
||||
{
|
||||
Vec_PtrPush( pGia->vNamesIn, Abc_UtilStrsav(pName) );
|
||||
Vec_PtrPush( pGia->vNamesOut, Abc_UtilStrsavTwo(pName, "_in") );
|
||||
}
|
||||
Vec_PtrFreeFree( vTemp );
|
||||
fclose( pFile );
|
||||
printf( "Read ILO names into file \"%s\".\n", filename3 );
|
||||
}
|
||||
ABC_FREE( filename3 );
|
||||
}
|
||||
Gia_Man_t * Gia_ManReadMiniAig( char * pFileName, int fGiaSimple )
|
||||
{
|
||||
Mini_Aig_t * p = Mini_AigLoad( pFileName );
|
||||
Gia_Man_t * pGia = Gia_ManFromMiniAig( p, NULL, fGiaSimple );
|
||||
Gia_Man_t * pTemp, * pGia = Gia_ManFromMiniAig( p, NULL, fGiaSimple );
|
||||
ABC_FREE( pGia->pName );
|
||||
pGia->pName = Extra_FileNameGeneric( pFileName );
|
||||
Mini_AigStop( p );
|
||||
Gia_ManReadMiniAigNames( pFileName, pGia );
|
||||
if ( !Gia_ManIsNormalized(pGia) )
|
||||
{
|
||||
pGia = Gia_ManDupNormalize( pTemp = pGia, 0 );
|
||||
ABC_SWAP( Vec_Ptr_t *, pTemp->vNamesIn, pGia->vNamesIn );
|
||||
ABC_SWAP( Vec_Ptr_t *, pTemp->vNamesOut, pGia->vNamesOut );
|
||||
Gia_ManStop( pTemp );
|
||||
}
|
||||
return pGia;
|
||||
}
|
||||
void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName )
|
||||
|
|
@ -512,6 +555,24 @@ char * Abc_FrameGiaOutputMiniLutAttr( Abc_Frame_t * pAbc, void * pMiniLut )
|
|||
printf( "Current network in ABC framework is not defined.\n" );
|
||||
return Gia_ManToMiniLutAttr( pGia, pMiniLut );
|
||||
}
|
||||
int * Abc_FrameGiaOutputMiniLutObj( Abc_Frame_t * pAbc )
|
||||
{
|
||||
int * pRes = NULL;
|
||||
if ( pAbc == NULL )
|
||||
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
|
||||
pAbc->vMiniLutObjs = Gia_ManDeriveBoxMapping( Abc_FrameReadGia( pAbc ) );
|
||||
if ( pAbc->vMiniLutObjs == NULL )
|
||||
printf( "MiniLut objects are not defined.\n" );
|
||||
pRes = Vec_IntReleaseArray( pAbc->vMiniLutObjs );
|
||||
Vec_IntFreeP( &pAbc->vMiniLutObjs );
|
||||
return pRes;
|
||||
}
|
||||
void Abc_FrameSetObjDelays( Abc_Frame_t * pAbc, int * pDelays, int nDelays )
|
||||
{
|
||||
Vec_IntFreeP( &pAbc->vObjDelays );
|
||||
pAbc->vObjDelays = Vec_IntAllocArrayCopy( pDelays, nDelays );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -681,6 +742,23 @@ int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc )
|
|||
Vec_IntFree( vSwitching );
|
||||
return pRes;
|
||||
}
|
||||
int * Abc_FrameReadMiniLutSwitching2( Abc_Frame_t * pAbc, int fRandPiFactor )
|
||||
{
|
||||
Vec_Int_t * vSwitching;
|
||||
int i, iObj, * pRes = NULL;
|
||||
if ( pAbc->pGiaMiniLut == NULL )
|
||||
{
|
||||
printf( "GIA derived from MiniLut is not available.\n" );
|
||||
return NULL;
|
||||
}
|
||||
vSwitching = Gia_ManComputeSwitchProbs2( pAbc->pGiaMiniLut, 48, 16, 0, fRandPiFactor );
|
||||
pRes = ABC_CALLOC( int, Vec_IntSize(pAbc->vCopyMiniLut) );
|
||||
Vec_IntForEachEntry( pAbc->vCopyMiniLut, iObj, i )
|
||||
if ( iObj >= 0 )
|
||||
pRes[i] = (int)(10000*Vec_FltEntry( (Vec_Flt_t *)vSwitching, Abc_Lit2Var(iObj) ));
|
||||
Vec_IntFree( vSwitching );
|
||||
return pRes;
|
||||
}
|
||||
int * Abc_FrameReadMiniLutSwitchingPo( Abc_Frame_t * pAbc )
|
||||
{
|
||||
Vec_Int_t * vSwitching;
|
||||
|
|
@ -726,6 +804,8 @@ Vec_Int_t * Gia_ManMapEquivAfterScorr( Gia_Man_t * p, Vec_Int_t * vMap )
|
|||
{
|
||||
if ( iObjLit == -1 )
|
||||
continue;
|
||||
// if ( Gia_ObjHasRepr(p, Abc_Lit2Var(iObjLit)) && !Gia_ObjProved(p, Abc_Lit2Var(iObjLit)) )
|
||||
// continue;
|
||||
iReprGia = Gia_ObjReprSelf( p, Abc_Lit2Var(iObjLit) );
|
||||
iReprMini = Vec_IntEntry( vGia2Mini, iReprGia );
|
||||
if ( iReprMini == -1 )
|
||||
|
|
@ -764,7 +844,17 @@ int * Abc_FrameReadMiniAigEquivClasses( Abc_Frame_t * pAbc )
|
|||
if ( pAbc->pGia2 == NULL )
|
||||
printf( "Internal GIA with equivalence classes is not available.\n" );
|
||||
if ( pAbc->pGia2->pReprs == NULL )
|
||||
{
|
||||
printf( "Equivalence classes of internal GIA are not available.\n" );
|
||||
return NULL;
|
||||
}
|
||||
else if ( 0 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 1; i < Gia_ManObjNum(pAbc->pGia2); i++ )
|
||||
if ( Gia_ObjHasRepr(pAbc->pGia2, i) )
|
||||
printf( "Obj %3d : Repr %3d Proved %d Failed %d\n", i, Gia_ObjRepr(pAbc->pGia2, i), Gia_ObjProved(pAbc->pGia2, i), Gia_ObjFailed(pAbc->pGia2, i) );
|
||||
}
|
||||
if ( Gia_ManObjNum(pAbc->pGia2) != Gia_ManObjNum(pAbc->pGiaMiniAig) )
|
||||
printf( "Internal GIA with equivalence classes is not directly derived from MiniAig.\n" );
|
||||
// derive the set of equivalent node pairs
|
||||
|
|
@ -1173,6 +1263,127 @@ void Gia_MiniAigGenerateFromFile()
|
|||
Mini_AigStop( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Str_t * Gia_ManRetimableF( Gia_Man_t * p, int * pRst, int * pSet, int * pEna )
|
||||
{
|
||||
Vec_Str_t * vStops = Vec_StrStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vTemps = Vec_IntStartFull( 3*Gia_ManObjNum(p) );
|
||||
Gia_Obj_t * pObj, * pObjRi, * pObjRo; int i;
|
||||
char * pStops = Vec_StrArray(vStops);
|
||||
assert( Gia_ManRegNum(p) > 0 );
|
||||
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) {
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 0, pRst[i] );
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 1, pSet[i] );
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 2, pEna[i] );
|
||||
}
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
int * pFan0 = Vec_IntEntryP( vTemps, 3*Gia_ObjFaninId0(pObj, i) );
|
||||
int * pFan1 = Vec_IntEntryP( vTemps, 3*Gia_ObjFaninId1(pObj, i) );
|
||||
int * pNode = Vec_IntEntryP( vTemps, 3*i );
|
||||
pStops[i] = (char)1;
|
||||
if ( pFan0[0] != -1 && pFan0[0] == pFan1[0] && pFan0[1] == pFan1[1] && pFan0[2] == pFan1[2] )
|
||||
pStops[i] = (char)0, pNode[0] = pFan0[0], pNode[1] = pFan0[1], pNode[2] = pFan0[2];
|
||||
}
|
||||
Vec_IntFree( vTemps );
|
||||
return vStops;
|
||||
}
|
||||
Vec_Str_t * Gia_ManRetimableB( Gia_Man_t * p, int * pRst, int * pSet, int * pEna )
|
||||
{
|
||||
Vec_Str_t * vStops = Vec_StrStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vTemps = Vec_IntStartFull( 3*Gia_ManObjNum(p) );
|
||||
Gia_Obj_t * pObj, * pObjRi, * pObjRo; int i, n, iFanout;
|
||||
char * pStops = Vec_StrArray(vStops);
|
||||
assert( Gia_ManRegNum(p) > 0 );
|
||||
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) {
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRi) + 0, pRst[i] );
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRi) + 1, pSet[i] );
|
||||
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRi) + 2, pEna[i] );
|
||||
}
|
||||
Gia_ManStaticFanoutStart( p );
|
||||
Gia_ManForEachAndReverse( p, pObj, i ) {
|
||||
int * pFan0 = Vec_IntEntryP( vTemps, 3*Gia_ObjFanoutId(p, i, 0) );
|
||||
int * pNode = Vec_IntEntryP( vTemps, 3*i );
|
||||
pStops[i] = (char)1;
|
||||
if ( pFan0[0] == -1 )
|
||||
continue;
|
||||
Gia_ObjForEachFanoutStaticId( p, i, iFanout, n ) {
|
||||
int * pFan1 = Vec_IntEntryP( vTemps, 3*iFanout );
|
||||
if ( pFan1[0] == -1 || pFan0[0] != pFan1[0] || pFan0[1] != pFan1[1] || pFan0[2] != pFan1[2] )
|
||||
break;
|
||||
}
|
||||
if ( n < Gia_ObjFanoutNum(p, pObj) )
|
||||
continue;
|
||||
pStops[i] = (char)0, pNode[0] = pFan0[0], pNode[1] = pFan0[1], pNode[2] = pFan0[2];
|
||||
}
|
||||
Gia_ManStaticFanoutStop( p );
|
||||
Vec_IntFree( vTemps );
|
||||
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) {
|
||||
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(pRst[i]))) ) pStops[Abc_Lit2Var(pRst[i])] = 1;
|
||||
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(pSet[i]))) ) pStops[Abc_Lit2Var(pSet[i])] = 1;
|
||||
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(pEna[i]))) ) pStops[Abc_Lit2Var(pEna[i])] = 1;
|
||||
}
|
||||
return vStops;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_FrameRemapLits( int * pLits, int nLits, Vec_Int_t * vMap )
|
||||
{
|
||||
for ( int i = 0; i < nLits; i++ )
|
||||
pLits[i] = Abc_Lit2LitL( Vec_IntArray(vMap), pLits[i] );
|
||||
}
|
||||
void Abc_FrameSetRetimingData( Abc_Frame_t * pAbc, int * pRst, int * pSet, int * pEna, int nRegs )
|
||||
{
|
||||
Gia_Man_t * pGia;
|
||||
int * pRstNew = ABC_CALLOC( int, nRegs );
|
||||
int * pSetNew = ABC_CALLOC( int, nRegs );
|
||||
int * pEnaNew = ABC_CALLOC( int, nRegs );
|
||||
if ( pAbc == NULL )
|
||||
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
|
||||
pGia = Abc_FrameReadGia( pAbc );
|
||||
if ( pGia == NULL )
|
||||
printf( "Current network in ABC framework is not defined.\n" );
|
||||
else {
|
||||
assert( nRegs == Gia_ManRegNum(pGia) );
|
||||
memmove( pRstNew, pRst, sizeof(int)*nRegs );
|
||||
memmove( pSetNew, pSet, sizeof(int)*nRegs );
|
||||
memmove( pEnaNew, pEna, sizeof(int)*nRegs );
|
||||
}
|
||||
if ( pAbc->vCopyMiniAig == NULL )
|
||||
printf( "Mapping of MiniAig nodes is not available.\n" );
|
||||
else {
|
||||
Abc_FrameRemapLits( pRstNew, nRegs, pAbc->vCopyMiniAig );
|
||||
Abc_FrameRemapLits( pSetNew, nRegs, pAbc->vCopyMiniAig );
|
||||
Abc_FrameRemapLits( pEnaNew, nRegs, pAbc->vCopyMiniAig );
|
||||
}
|
||||
assert( pGia->vStopsF == NULL );
|
||||
assert( pGia->vStopsB == NULL );
|
||||
pGia->vStopsF = Gia_ManRetimableF( pGia, pRstNew, pSetNew, pEnaNew );
|
||||
pGia->vStopsB = Gia_ManRetimableB( pGia, pRstNew, pSetNew, pEnaNew );
|
||||
ABC_FREE( pRstNew );
|
||||
ABC_FREE( pSetNew );
|
||||
ABC_FREE( pEnaNew );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -0,0 +1,916 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaMulFind.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Multiplier detection.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaMulFind.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManMulFindXors2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXor )
|
||||
{
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
return;
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
return;
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
if ( !pObj->fMark0 )
|
||||
{
|
||||
if ( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj)
|
||||
&& Gia_ObjRefNum(p, Gia_ObjFanin0(pObj)) >= 4
|
||||
&& Gia_ObjRefNum(p, Gia_ObjFanin1(pObj)) >= 4 )
|
||||
Vec_IntPushTwo( vXor, Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninId1p(p, pObj) );
|
||||
return;
|
||||
}
|
||||
Gia_Obj_t * pFan0, * pFan1;
|
||||
int RetValue = Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1);
|
||||
assert( RetValue );
|
||||
Gia_ManMulFindXors2_rec( p, Gia_Regular(pFan0), vXor );
|
||||
Gia_ManMulFindXors2_rec( p, Gia_Regular(pFan1), vXor );
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindXors2( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Wec_t * vXors = Vec_WecAlloc( 100 );
|
||||
Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj, * pFan0, * pFan1; int i;
|
||||
Gia_ManCreateRefs( p );
|
||||
Gia_ManCleanMark01( p );
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
|
||||
continue;
|
||||
Gia_Regular(pFan0)->fMark1 = 1;
|
||||
Gia_Regular(pFan1)->fMark1 = 1;
|
||||
pObj->fMark0 = 1;
|
||||
}
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
if ( pObj->fMark0 && !pObj->fMark1 ) {
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntClear( vTemp );
|
||||
Gia_ManMulFindXors2_rec( p, pObj, vTemp );
|
||||
if ( Vec_IntSize(vTemp) > 0 )
|
||||
Vec_IntAppend( Vec_WecPushLevel(vXors), vTemp );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vTemp );
|
||||
return vXors;
|
||||
}
|
||||
int Gia_ManMulFindMaxSize( Vec_Wec_t * vXors, Vec_Int_t * vUsed )
|
||||
{
|
||||
Vec_Int_t * vLevel; int i, iBest = -1, nBestSize = 0;
|
||||
Vec_WecForEachLevel( vXors, vLevel, i )
|
||||
if ( !Vec_IntEntry(vUsed, i) && nBestSize < Vec_IntSize(vLevel) )
|
||||
nBestSize = Vec_IntSize(vLevel), iBest = i;
|
||||
return iBest;
|
||||
}
|
||||
int Gia_ManMulFindGetOverlap( Vec_Int_t * p1, Vec_Int_t * p2 )
|
||||
{
|
||||
int i, k, ObjI, ObjK, Counter = 0;
|
||||
Vec_IntForEachEntry( p1, ObjI, i )
|
||||
Vec_IntForEachEntry( p2, ObjK, k )
|
||||
if ( ObjI == ObjK )
|
||||
Counter++;
|
||||
return Counter;
|
||||
}
|
||||
int Gia_ManMulFindGetOverlap2( Vec_Int_t * p1, Vec_Int_t * p2 )
|
||||
{
|
||||
int i, k, ObjI, ObjK, Counter = 0;
|
||||
Vec_IntForEachEntryStart( p1, ObjI, i, 1 )
|
||||
Vec_IntForEachEntry( p2, ObjK, k )
|
||||
if ( ObjI == ObjK )
|
||||
Counter++;
|
||||
return Counter;
|
||||
}
|
||||
int Gia_ManMulFindMaxOverlap( Vec_Wec_t * vXors, Vec_Int_t * vUsed, Vec_Int_t * vFound )
|
||||
{
|
||||
Vec_Int_t * vLevel; int i, iBest = -1, nThisSize, nBestSize = 0;
|
||||
Vec_WecForEachLevel( vXors, vLevel, i )
|
||||
if ( !Vec_IntEntry(vUsed, i) && nBestSize < (nThisSize = Gia_ManMulFindGetOverlap(vFound, vLevel)) )
|
||||
nBestSize = nThisSize, iBest = i;
|
||||
return iBest;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindSets( Gia_Man_t * p, Vec_Wec_t * vXors )
|
||||
{
|
||||
Vec_Wec_t * vSets = Vec_WecAlloc( 100 );
|
||||
Vec_Int_t * vUsed = Vec_IntStart( Vec_WecSize(vXors) );
|
||||
Vec_Int_t * vFound = Vec_IntAlloc( 100 ); int Item, k, Obj;
|
||||
while ( (Item = Gia_ManMulFindMaxSize(vXors, vUsed)) != -1 ) {
|
||||
Vec_Int_t * vTemp = Vec_WecEntry(vXors, Item);
|
||||
Vec_Int_t * vNew = Vec_WecPushLevel( vSets );
|
||||
Vec_IntPush( vNew, Item );
|
||||
Vec_IntWriteEntry( vUsed, Item, 1 );
|
||||
Vec_IntClear( vFound );
|
||||
Vec_IntAppend( vFound, vTemp );
|
||||
while ( (Item = Gia_ManMulFindMaxOverlap(vXors, vUsed, vFound)) != -1 ) {
|
||||
Vec_IntPush( vNew, Item );
|
||||
Vec_IntWriteEntry( vUsed, Item, 1 );
|
||||
vTemp = Vec_WecEntry(vXors, Item);
|
||||
Vec_IntForEachEntry( vTemp, Obj, k )
|
||||
Vec_IntPushUnique( vFound, Obj );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vUsed );
|
||||
Vec_IntFree( vFound );
|
||||
return vSets;
|
||||
}
|
||||
int Gia_ManMulFindOne( Gia_Man_t * p, Vec_Wec_t * vXors, Vec_Int_t * vSet, Vec_Int_t * vMap, Vec_Int_t * vA, Vec_Int_t * vB, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vObjs = Vec_IntAlloc( 100 ); int i, j, Obj, Obj1, Obj2;
|
||||
Vec_IntForEachEntry( vSet, Obj, i )
|
||||
Vec_IntAppend( vObjs, Vec_WecEntry(vXors, Obj) );
|
||||
Vec_IntForEachEntry( vObjs, Obj, i )
|
||||
Vec_IntAddToEntry( vMap, Obj, 1 );
|
||||
Vec_IntForEachEntry( vSet, Obj, i ) {
|
||||
Vec_Int_t * vTemp = Vec_WecEntry(vXors, Obj); int k = 0;
|
||||
Vec_IntForEachEntryDouble( vTemp, Obj1, Obj2, j )
|
||||
if ( Vec_IntEntry(vMap, Obj1) > 1 || Vec_IntEntry(vMap, Obj2) > 1 )
|
||||
Vec_IntWriteEntry(vTemp, k++, Obj1), Vec_IntWriteEntry(vTemp, k++, Obj2);
|
||||
Vec_IntShrink( vTemp, k );
|
||||
}
|
||||
Vec_IntForEachEntry( vObjs, Obj, i )
|
||||
Vec_IntWriteEntry( vMap, Obj, 0 );
|
||||
Vec_IntClear( vObjs );
|
||||
Vec_IntForEachEntry( vSet, Obj, i )
|
||||
Vec_IntAppend( vObjs, Vec_WecEntry(vXors, Obj) );
|
||||
if ( Vec_IntSize(vObjs) == 0 ) {
|
||||
Vec_IntFree(vObjs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vec_IntClear( vA );
|
||||
Vec_IntClear( vB );
|
||||
Vec_IntPush( vA, Vec_IntPop(vObjs) );
|
||||
Vec_IntPush( vB, Vec_IntPop(vObjs) );
|
||||
while ( Vec_IntSize(vObjs) > 0 ) {
|
||||
int k = 0;
|
||||
Vec_IntForEachEntryDouble( vObjs, Obj1, Obj2, j ) {
|
||||
if ( Vec_IntFind(vA, Obj1) >= 0 )
|
||||
Vec_IntPushUnique(vB, Obj2);
|
||||
else if ( Vec_IntFind(vA, Obj2) >= 0 )
|
||||
Vec_IntPushUnique(vB, Obj1);
|
||||
else if ( Vec_IntFind(vB, Obj1) >= 0 )
|
||||
Vec_IntPushUnique(vA, Obj2);
|
||||
else if ( Vec_IntFind(vB, Obj2) >= 0 )
|
||||
Vec_IntPushUnique(vA, Obj1);
|
||||
else {
|
||||
Vec_IntWriteEntry(vObjs, k++, Obj1);
|
||||
Vec_IntWriteEntry(vObjs, k++, Obj2);
|
||||
}
|
||||
}
|
||||
Vec_IntShrink( vObjs, k );
|
||||
}
|
||||
Vec_IntSort( vA, 0 );
|
||||
Vec_IntSort( vB, 0 );
|
||||
Vec_IntClear( vObjs );
|
||||
Vec_IntForEachEntry( vSet, Obj, i )
|
||||
Vec_IntAppend( vObjs, Vec_WecEntry(vXors, Obj) );
|
||||
Vec_IntForEachEntryDouble( vObjs, Obj1, Obj2, j )
|
||||
if ( !((Vec_IntFind(vA, Obj1) >= 0 && Vec_IntFind(vB, Obj2) >= 0) ||
|
||||
(Vec_IntFind(vA, Obj2) >= 0 && Vec_IntFind(vB, Obj1) >= 0)) ) {
|
||||
if ( fVerbose )
|
||||
printf( "Internal verification failed.\n" );
|
||||
Vec_IntFree( vObjs );
|
||||
Vec_IntClear( vA );
|
||||
Vec_IntClear( vB );
|
||||
return 0;
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "Generated system with %d+%d+%d=%d variables and %d equations.\n",
|
||||
Vec_IntSize(vA),Vec_IntSize(vB),Vec_IntSize(vSet),
|
||||
Vec_IntSize(vA)+Vec_IntSize(vB)+Vec_IntSize(vSet), Vec_IntSize(vObjs)/2 );
|
||||
Vec_IntFree( vObjs );
|
||||
return 1;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindAInputs2( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vMuls = Vec_WecAlloc( 10 );
|
||||
Vec_Wec_t * vXors = Gia_ManMulFindXors2( p );
|
||||
Vec_Wec_t * vSets = Gia_ManMulFindSets( p, vXors );
|
||||
Vec_Int_t * vMap = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vA = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vB = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vSet; int i;
|
||||
Vec_WecForEachLevel( vSets, vSet, i )
|
||||
{
|
||||
if ( !Gia_ManMulFindOne(p, vXors, vSet, vMap, vA, vB, fVerbose) )
|
||||
continue;
|
||||
Vec_IntAppend( Vec_WecPushLevel(vMuls), vA );
|
||||
Vec_IntAppend( Vec_WecPushLevel(vMuls), vB );
|
||||
Vec_WecPushLevel(vMuls);
|
||||
}
|
||||
Vec_WecFree( vXors );
|
||||
Vec_WecFree( vSets );
|
||||
Vec_IntFree( vMap );
|
||||
Vec_IntFree( vA );
|
||||
Vec_IntFree( vB );
|
||||
return vMuls;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManMulFindAddEntry1( Vec_Int_t * vPairs, int Obj )
|
||||
{
|
||||
int Entry, Sum, k;
|
||||
Vec_IntForEachEntryDouble( vPairs, Entry, Sum, k )
|
||||
if ( Obj == Entry ) {
|
||||
Vec_IntAddToEntry( vPairs, k+1, 1 );
|
||||
break;
|
||||
}
|
||||
if ( k == Vec_IntSize(vPairs) )
|
||||
Vec_IntPushTwo( vPairs, Obj, 1 );
|
||||
}
|
||||
Vec_Int_t * Gia_ManMulFindCounts( Vec_Wec_t * vCuts4, Vec_Int_t * vSet )
|
||||
{
|
||||
Vec_Int_t * vCounts = Vec_IntAlloc( 10 );
|
||||
int i, k, Obj, Item;
|
||||
Vec_IntForEachEntry( vSet, Item, i ) {
|
||||
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
|
||||
Vec_IntForEachEntryStart( vCut, Obj, k, 1 )
|
||||
Gia_ManMulFindAddEntry1( vCounts, Obj );
|
||||
}
|
||||
return vCounts;
|
||||
}
|
||||
int Gia_ManMulFindNextEntry( Vec_Wec_t * vCuts4, Vec_Int_t * vSet, int Entry )
|
||||
{
|
||||
int i, Item;
|
||||
Vec_IntForEachEntry( vSet, Item, i ) {
|
||||
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
|
||||
if ( Vec_IntSize(vCut) == 0 )
|
||||
continue;
|
||||
assert( Vec_IntSize(vCut) == 3 );
|
||||
int RetValue = -1;
|
||||
if ( Vec_IntEntry(vCut, 1) == Entry )
|
||||
RetValue = Vec_IntEntry(vCut, 2);
|
||||
if ( Vec_IntEntry(vCut, 2) == Entry )
|
||||
RetValue = Vec_IntEntry(vCut, 1);
|
||||
if ( RetValue == -1 )
|
||||
continue;
|
||||
Vec_IntClear( vCut );
|
||||
return RetValue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
void Gia_ManMulFindArg1( Vec_Wec_t * vCuts4, Vec_Int_t * vSet, Vec_Int_t * vArg1 )
|
||||
{
|
||||
Vec_Int_t * vCounts = Gia_ManMulFindCounts( vCuts4, vSet );
|
||||
int Entry = -1, Sum, k;
|
||||
Vec_IntClear( vArg1 );
|
||||
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k )
|
||||
if ( Sum == 1 ) {
|
||||
Vec_IntPush( vArg1, Entry );
|
||||
break;
|
||||
}
|
||||
assert( Entry != -1 );
|
||||
while ( (Entry = Gia_ManMulFindNextEntry(vCuts4, vSet, Entry)) != -1 )
|
||||
Vec_IntPush( vArg1, Entry );
|
||||
Vec_IntFree( vCounts );
|
||||
}
|
||||
int Gia_ManMulFindNextEntryCount( Vec_Int_t * vCounts, int Entry0 )
|
||||
{
|
||||
int Entry, Sum, k;
|
||||
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k )
|
||||
if ( Entry == Entry0 )
|
||||
return Sum;
|
||||
return -1;
|
||||
}
|
||||
int Gia_ManMulFindNextEntry2( Vec_Wec_t * vCuts4, Vec_Int_t * vSet, int Entry, Vec_Int_t * vCounts, int * pEntry0, int * pEntry1 )
|
||||
{
|
||||
int i, Item;
|
||||
Vec_IntForEachEntry( vSet, Item, i ) {
|
||||
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
|
||||
if ( Vec_IntSize(vCut) == 0 )
|
||||
continue;
|
||||
assert( Vec_IntSize(vCut) == 4 );
|
||||
int Entry0, Entry1, iPlace = Vec_IntFind( vCut, Entry );
|
||||
if ( iPlace == -1 )
|
||||
continue;
|
||||
if ( iPlace == 1 )
|
||||
Entry0 = Vec_IntEntry(vCut, 2), Entry1 = Vec_IntEntry(vCut, 3);
|
||||
else if ( iPlace == 2 )
|
||||
Entry0 = Vec_IntEntry(vCut, 1), Entry1 = Vec_IntEntry(vCut, 3);
|
||||
else if ( iPlace == 3 )
|
||||
Entry0 = Vec_IntEntry(vCut, 1), Entry1 = Vec_IntEntry(vCut, 2);
|
||||
else assert( 0 );
|
||||
int Count0 = Gia_ManMulFindNextEntryCount(vCounts, Entry0);
|
||||
int Count1 = Gia_ManMulFindNextEntryCount(vCounts, Entry1);
|
||||
*pEntry0 = Count0 <= Count1 ? Entry0 : Entry1;
|
||||
*pEntry1 = Count0 <= Count1 ? Entry1 : Entry0;
|
||||
// remove entries
|
||||
Vec_IntForEachEntry( vSet, Item, i ) {
|
||||
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
|
||||
if ( Vec_IntSize(vCut) == 0 )
|
||||
continue;
|
||||
if ( Vec_IntFind( vCut, Entry ) >= 0 )
|
||||
Vec_IntClear( vCut );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void Gia_ManMulFindArg2( Vec_Wec_t * vCuts5, Vec_Int_t * vSet, Vec_Int_t * vArg2, int Entry0, int Entry1 )
|
||||
{
|
||||
Vec_Int_t * vCounts = Gia_ManMulFindCounts( vCuts5, vSet );
|
||||
int Entry, Sum, k, SumMin = ABC_INFINITY, SumMax = 0;
|
||||
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k ) {
|
||||
SumMin = Abc_MinInt( SumMin, Sum );
|
||||
SumMax = Abc_MaxInt( SumMax, Sum );
|
||||
}
|
||||
Vec_IntClear( vArg2 );
|
||||
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k )
|
||||
if ( Entry == Entry0 || Entry == Entry1 ) {
|
||||
Vec_IntPush( vArg2, Entry == Entry0 ? Entry1 : Entry0 );
|
||||
Vec_IntPush( vArg2, Entry );
|
||||
break;
|
||||
}
|
||||
Entry = Vec_IntEntry(vArg2, 1);
|
||||
while ( Gia_ManMulFindNextEntry2(vCuts5, vSet, Entry, vCounts, &Entry0, &Entry1) )
|
||||
Vec_IntPushTwo( vArg2, Entry0, Entry1 ), Entry = Entry1;
|
||||
Vec_IntFree( vCounts );
|
||||
}
|
||||
void Gia_ManMulFindAddEntry( Vec_Int_t * vPairs, int Obj0, int Obj1 )
|
||||
{
|
||||
int Entry0, Entry1, Sum, k;
|
||||
Vec_IntForEachEntryTriple( vPairs, Entry0, Entry1, Sum, k )
|
||||
if ( Obj0 == Entry0 && Obj1 == Entry1 ) {
|
||||
Vec_IntAddToEntry( vPairs, k+2, 1 );
|
||||
break;
|
||||
}
|
||||
if ( k == Vec_IntSize(vPairs) )
|
||||
Vec_IntPushThree( vPairs, Obj0, Obj1, 1 );
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindBInputs2( Gia_Man_t * p, Vec_Wec_t * vCuts4, Vec_Wec_t * vCuts5, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vRes = Vec_WecAlloc( 10 );
|
||||
Vec_Int_t * vPairs = Vec_IntAlloc( 1000 );
|
||||
Vec_Int_t * vSet = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vCut, * vArg1, * vArg2;
|
||||
int i, j, k, n, Entry0, Entry1, Sum, Obj0, Obj1;
|
||||
Vec_WecForEachLevel( vCuts4, vCut, i )
|
||||
Vec_IntForEachEntryStart( vCut, Obj0, j, 1 )
|
||||
Vec_IntForEachEntryStart( vCut, Obj1, k, j+1 )
|
||||
Gia_ManMulFindAddEntry( vPairs, Obj0, Obj1 );
|
||||
Vec_IntForEachEntryTriple( vPairs, Entry0, Entry1, Sum, n ) {
|
||||
if ( Sum < 3 )
|
||||
continue;
|
||||
Vec_IntClear( vSet );
|
||||
Vec_WecForEachLevel( vCuts4, vCut, i )
|
||||
Vec_IntForEachEntryStart( vCut, Obj0, j, 1 )
|
||||
Vec_IntForEachEntryStart( vCut, Obj1, k, j+1 )
|
||||
if ( Obj0 == Entry0 && Obj1 == Entry1 ) {
|
||||
Vec_IntPush( vSet, i );
|
||||
Vec_IntDrop( vCut, k );
|
||||
Vec_IntDrop( vCut, j );
|
||||
j = k = Vec_IntSize(vCut);
|
||||
}
|
||||
vArg1 = Vec_WecPushLevel(vRes);
|
||||
vArg2 = Vec_WecPushLevel(vRes);
|
||||
Vec_WecPushLevel(vRes);
|
||||
Gia_ManMulFindArg1( vCuts4, vSet, vArg1 );
|
||||
// find overlapping with arg1 and remove nodes in arg1
|
||||
Vec_IntClear( vSet );
|
||||
Vec_WecForEachLevel( vCuts5, vCut, i )
|
||||
if ( Gia_ManMulFindGetOverlap2(vCut, vArg1) ) {
|
||||
k = 1;
|
||||
Vec_IntForEachEntryStart( vCut, Obj0, j, 1 )
|
||||
if ( Vec_IntFind(vArg1, Obj0) == -1 )
|
||||
Vec_IntWriteEntry( vCut, k++, Obj0 );
|
||||
Vec_IntShrink( vCut, k );
|
||||
Vec_IntPush( vSet, i );
|
||||
}
|
||||
Gia_ManMulFindArg2( vCuts5, vSet, vArg2, Entry0, Entry1 );
|
||||
}
|
||||
Vec_IntFree( vSet );
|
||||
Vec_IntFree( vPairs );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManMulFindOverlap( Vec_Int_t * p1, Vec_Int_t * p2 )
|
||||
{
|
||||
int i, k, ObjI, ObjK, Counter = 0;
|
||||
Vec_IntForEachEntry( p1, ObjI, i )
|
||||
Vec_IntForEachEntry( p2, ObjK, k )
|
||||
if ( ObjI == ObjK )
|
||||
Counter++;
|
||||
return Counter;
|
||||
}
|
||||
void Gia_ManMulFindAssignGroup( Vec_Int_t * vTemp, int iGroup, Vec_Int_t * vMap )
|
||||
{
|
||||
int k, Obj;
|
||||
Vec_IntForEachEntry( vTemp, Obj, k ) {
|
||||
//assert( Vec_IntEntry(vMap, Obj) == -1 || Vec_IntEntry(vMap, Obj) == iGroup );
|
||||
Vec_IntWriteEntry(vMap, Obj, iGroup);
|
||||
}
|
||||
Vec_IntPush( vTemp, iGroup );
|
||||
}
|
||||
Vec_Int_t * Gia_ManMulFindGroups( Vec_Wec_t * p, int nObjs, int fUseMap )
|
||||
{
|
||||
Vec_Int_t * vIndex = Vec_IntAlloc( 100 ), * vTemp;
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( nObjs ); int i, Counter, nGroups = 0;
|
||||
Vec_Int_t * vUngrouped = Vec_IntStartNatural( Vec_WecSize(p) );
|
||||
while ( Vec_IntSize(vUngrouped) ) {
|
||||
int k, Obj, Item = Vec_IntPop(vUngrouped);
|
||||
vTemp = Vec_WecEntry(p, Item);
|
||||
Gia_ManMulFindAssignGroup( vTemp, nGroups, vMap );
|
||||
int fChanges = 1;
|
||||
while ( fChanges ) {
|
||||
fChanges = 0;
|
||||
Vec_IntForEachEntry( vUngrouped, Item, i ) {
|
||||
vTemp = Vec_WecEntry(p, Item);
|
||||
Counter = 0;
|
||||
Vec_IntForEachEntry( vTemp, Obj, k )
|
||||
if ( Vec_IntEntry(vMap, Obj) >= 0 )
|
||||
Counter++;
|
||||
if ( Counter < 1 )
|
||||
continue;
|
||||
Gia_ManMulFindAssignGroup( vTemp, nGroups, vMap );
|
||||
Vec_IntDrop( vUngrouped, i-- );
|
||||
fChanges = 1;
|
||||
}
|
||||
}
|
||||
nGroups++;
|
||||
}
|
||||
Vec_IntFree( vUngrouped );
|
||||
Vec_IntFree( vMap );
|
||||
if ( fUseMap )
|
||||
Vec_WecForEachLevel( p, vTemp, i )
|
||||
Vec_IntPushTwo( vTemp, i, Vec_IntPop(vTemp) );
|
||||
Vec_WecSortByLastInt( p, 0 );
|
||||
Counter = 0;
|
||||
Vec_IntPush( vIndex, 0 );
|
||||
Vec_WecForEachLevel( p, vTemp, i )
|
||||
if ( Vec_IntPop(vTemp) != Counter )
|
||||
Vec_IntPush( vIndex, i ), Counter++;
|
||||
Vec_IntPush( vIndex, Vec_WecSize(p) );
|
||||
assert( Vec_WecSize(p) == 0 || Vec_IntSize(vIndex) == nGroups + 1 );
|
||||
return vIndex;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindXors( Gia_Man_t * p, Vec_Wec_t * vCuts3, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vXors = Vec_WecAlloc( 10 );
|
||||
Vec_Int_t * vIndex = Gia_ManMulFindGroups( vCuts3, Gia_ManObjNum(p), 0 );
|
||||
Vec_Int_t * vAll = Vec_IntAlloc( 100 );
|
||||
Vec_Bit_t * vSigs[2] = { Vec_BitStart(Gia_ManObjNum(p)), Vec_BitStart(Gia_ManObjNum(p)) };
|
||||
Vec_Int_t * vTemp; int g, c, k, Obj, Start;
|
||||
Vec_IntForEachEntryStop( vIndex, Start, g, Vec_IntSize(vIndex)-1 ) {
|
||||
Vec_WecForEachLevelStartStop( vCuts3, vTemp, c, Start, Vec_IntEntry(vIndex, g+1) )
|
||||
Vec_IntForEachEntry( vTemp, Obj, k )
|
||||
if ( !Vec_BitEntry(vSigs[k==0], Obj) ) {
|
||||
Vec_BitWriteEntry( vSigs[k==0], Obj, 1 );
|
||||
Vec_IntPush( vAll, Obj );
|
||||
}
|
||||
Vec_Int_t * vIns = Vec_WecPushLevel( vXors );
|
||||
Vec_Int_t * vOuts = Vec_WecPushLevel( vXors );
|
||||
Vec_IntForEachEntry( vAll, Obj, k ) {
|
||||
if ( Vec_BitEntry(vSigs[0], Obj) && !Vec_BitEntry(vSigs[1], Obj) )
|
||||
Vec_IntPush( vIns, Obj );
|
||||
if ( !Vec_BitEntry(vSigs[0], Obj) && Vec_BitEntry(vSigs[1], Obj) )
|
||||
Vec_IntPush( vOuts, Obj );
|
||||
Vec_BitWriteEntry( vSigs[0], Obj, 0 );
|
||||
Vec_BitWriteEntry( vSigs[1], Obj, 0 );
|
||||
}
|
||||
Vec_IntClear( vAll );
|
||||
}
|
||||
return vXors;
|
||||
}
|
||||
Vec_Int_t * Gia_ManFindMulDetectOrder( Vec_Wec_t * vAll, int iStart, int iStop )
|
||||
{
|
||||
Vec_Int_t * vOrder = Vec_IntAlloc( iStop - iStart );
|
||||
Vec_Int_t * vUsed = Vec_IntStart( iStop ), * vTemp;
|
||||
int i, nMatches = 0, iNext = -1;
|
||||
Vec_WecForEachLevelStartStop( vAll, vTemp, i, iStart, iStop )
|
||||
if ( Vec_IntSize(vTemp) == 2 )
|
||||
nMatches++, iNext = i;
|
||||
if ( nMatches == 1 ) {
|
||||
while ( Vec_IntSize(vOrder) < iStop - iStart ) {
|
||||
Vec_IntPush( vOrder, iNext );
|
||||
Vec_IntWriteEntry( vUsed, iNext, 1 );
|
||||
nMatches = 0;
|
||||
Vec_WecForEachLevelStartStop( vAll, vTemp, i, iStart, iStop ) {
|
||||
if ( Vec_IntEntry(vUsed, i) )
|
||||
continue;
|
||||
Vec_Int_t * vLast = Vec_WecEntry(vAll, Vec_IntEntryLast(vOrder));
|
||||
if ( Gia_ManMulFindOverlap(vTemp, vLast) == Vec_IntSize(vLast) && Vec_IntSize(vTemp) == Vec_IntSize(vLast) + 2 )
|
||||
nMatches++, iNext = i;
|
||||
}
|
||||
if ( nMatches != 1 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vUsed );
|
||||
if ( Vec_IntSize(vOrder) == 0 )
|
||||
Vec_IntFreeP( &vOrder );
|
||||
return vOrder;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindAInputs( Gia_Man_t * p, Vec_Wec_t * vXors, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vRes = Vec_WecAlloc( 10 );
|
||||
Vec_Wec_t * vAll = Vec_WecAlloc( Vec_WecSize(vXors)/2 );
|
||||
Gia_Obj_t * pObj; Vec_Int_t * vIns, * vOuts, * vTemp, * vIndex, * vOrder; int i, k, g, Start, Entry, Entry0, Entry1;
|
||||
Gia_ManCreateRefs( p );
|
||||
Vec_WecForEachLevelDouble( vXors, vIns, vOuts, i ) {
|
||||
vTemp = Vec_WecPushLevel( vAll );
|
||||
Gia_ManForEachObjVec( vIns, p, pObj, k )
|
||||
if ( Gia_ObjIsAnd(pObj)
|
||||
&& !Gia_ObjFaninC0(pObj) && Gia_ObjRefNum(p, Gia_ObjFanin0(pObj)) >= 4
|
||||
&& !Gia_ObjFaninC1(pObj) && Gia_ObjRefNum(p, Gia_ObjFanin1(pObj)) >= 4 )
|
||||
Vec_IntPushTwo( vTemp, Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninId1p(p, pObj) );
|
||||
if ( Vec_IntSize(vTemp) == 0 )
|
||||
Vec_WecShrink(vAll, Vec_WecSize(vAll)-1);
|
||||
}
|
||||
vIndex = Gia_ManMulFindGroups( vAll, Gia_ManObjNum(p), 0 );
|
||||
Vec_IntForEachEntryStop( vIndex, Start, g, Vec_IntSize(vIndex)-1 ) {
|
||||
vOrder = Gia_ManFindMulDetectOrder( vAll, Start, Vec_IntEntry(vIndex, g+1) );
|
||||
if ( vOrder == NULL )
|
||||
continue;
|
||||
Vec_Int_t * vIn0 = Vec_WecPushLevel( vRes );
|
||||
Vec_Int_t * vIn1 = Vec_WecPushLevel( vRes );
|
||||
Vec_Int_t * vOut = Vec_WecPushLevel( vRes );
|
||||
vTemp = Vec_WecEntry( vAll, Vec_IntEntry(vOrder, 0) );
|
||||
assert( Vec_IntSize(vTemp) == 2 );
|
||||
Vec_IntPush( vIn0, Vec_IntEntry(vTemp, 0) );
|
||||
Vec_IntPush( vIn1, Vec_IntEntry(vTemp, 1) );
|
||||
Vec_IntForEachEntryStart( vOrder, Entry, i, 1 ) {
|
||||
vTemp = Vec_WecEntry( vAll, Entry );
|
||||
Vec_IntForEachEntryDouble( vTemp, Entry0, Entry1, k ) {
|
||||
if ( Vec_IntFind(vIn0, Entry0) >= 0 && Vec_IntFind(vIn1, Entry1) == -1 )
|
||||
Vec_IntPush( vIn1, Entry1 );
|
||||
else if ( Vec_IntFind(vIn0, Entry0) == -1 && Vec_IntFind(vIn1, Entry1) >= 0 )
|
||||
Vec_IntPush( vIn0, Entry0 );
|
||||
else
|
||||
assert( (Vec_IntFind(vIn0, Entry0) >= 0 && Vec_IntFind(vIn1, Entry1) >= 0) ||
|
||||
(Vec_IntFind(vIn0, Entry1) >= 0 && Vec_IntFind(vIn1, Entry0) >= 0) );
|
||||
}
|
||||
}
|
||||
Vec_IntReverseOrder( vIn0 );
|
||||
Vec_IntReverseOrder( vIn1 );
|
||||
vOut = NULL;
|
||||
}
|
||||
Vec_IntFree( vIndex );
|
||||
Vec_WecFree( vAll );
|
||||
return vRes;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindBInputs( Gia_Man_t * p, Vec_Wec_t * vCuts4, Vec_Wec_t * vCuts5, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vRes = Vec_WecAlloc( 10 ); Vec_Int_t * vTemp; int g, c, k, Obj, Start;
|
||||
Vec_Int_t * vIndex = Gia_ManMulFindGroups( vCuts4, Gia_ManObjNum(p), 0 );
|
||||
Vec_IntForEachEntryStop( vIndex, Start, g, Vec_IntSize(vIndex)-1 ) {
|
||||
Vec_Int_t * vAll = Vec_IntAlloc ( 100 );
|
||||
Vec_WecForEachLevelStartStop( vCuts4, vTemp, c, Start, Vec_IntEntry(vIndex, g+1) )
|
||||
Vec_IntForEachEntryStart( vTemp, Obj, k, 1 )
|
||||
Vec_IntPush( vAll, Obj );
|
||||
Vec_IntUniqify( vAll );
|
||||
int GroupSize = Vec_IntEntry(vIndex, g+1) - Start;
|
||||
Vec_Int_t * vCnt = Vec_IntStart( Vec_IntSize(vAll) );
|
||||
Vec_WecForEachLevelStartStop( vCuts4, vTemp, c, Start, Vec_IntEntry(vIndex, g+1) )
|
||||
Vec_IntForEachEntryStart( vTemp, Obj, k, 1 )
|
||||
Vec_IntAddToEntry( vCnt, Vec_IntFind(vAll, Obj), 1 );
|
||||
if ( Vec_IntCountEntry(vCnt, 1) != 2 || Vec_IntCountEntry(vCnt, 2) != GroupSize-1 || Vec_IntCountEntry(vCnt, GroupSize) != 2 ) {
|
||||
printf( "Detection of group %d failed.\n", g );
|
||||
continue;
|
||||
}
|
||||
Vec_Int_t * vIn1 = Vec_WecPushLevel( vRes );
|
||||
Vec_Int_t * vIn2 = Vec_WecPushLevel( vRes );
|
||||
Vec_Int_t * vOut = Vec_WecPushLevel( vRes );
|
||||
Vec_IntForEachEntry( vAll, Obj, k )
|
||||
if ( Vec_IntEntry(vCnt, k) <= 2 )
|
||||
Vec_IntPush( vIn1, Obj );
|
||||
else
|
||||
Vec_IntPush( vIn2, Obj );
|
||||
Vec_IntSort( vIn1, 0 );
|
||||
Vec_IntSort( vIn2, 0 );
|
||||
// TODO: check chain in[i] -> in[i+1]
|
||||
Vec_WecForEachLevel( vCuts5, vTemp, c ) {
|
||||
Vec_IntShift( vTemp, 1 );
|
||||
if ( Gia_ManMulFindOverlap(vTemp, vIn1) >= 2 )
|
||||
Vec_IntForEachEntryStart( vTemp, Obj, k, 1 )
|
||||
if ( Vec_IntFind(vIn1, Obj) == -1 ) {
|
||||
Vec_IntPushUnique(vIn2, Obj);
|
||||
}
|
||||
Vec_IntShift( vTemp, -1 );
|
||||
}
|
||||
Vec_IntSort( vIn2, 0 );
|
||||
vOut = NULL;
|
||||
}
|
||||
Vec_IntFree( vIndex );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManMulFindTfo( Gia_Man_t * p, Vec_Int_t * vIn0, Vec_Int_t * vIn1, int fLits )
|
||||
{
|
||||
Vec_Int_t * vTfo = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj; int i, Obj;
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntForEachEntry( vIn0, Obj, i )
|
||||
Gia_ObjSetTravIdCurrentId( p, fLits ? Abc_Lit2Var(Obj) : Obj );
|
||||
Vec_IntForEachEntry( vIn1, Obj, i )
|
||||
Gia_ObjSetTravIdCurrentId( p, fLits ? Abc_Lit2Var(Obj) : Obj );
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, i) )
|
||||
continue;
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) && Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) )
|
||||
Gia_ObjSetTravIdCurrentId( p, i ), Vec_IntPush( vTfo, i );
|
||||
}
|
||||
return vTfo;
|
||||
}
|
||||
Vec_Wrd_t * Gia_ManMulFindSimCone( Gia_Man_t * p, Vec_Int_t * vIn0, Vec_Int_t * vIn1, Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, Vec_Int_t * vTfo, int fLits )
|
||||
{
|
||||
Vec_Wrd_t * vRes = Vec_WrdAlloc( Vec_IntSize(vTfo) );
|
||||
Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(p) );
|
||||
Gia_Obj_t * pObj; int i, Obj;
|
||||
Vec_IntForEachEntry( vIn0, Obj, i )
|
||||
Vec_WrdWriteEntry( vSims, fLits ? Abc_Lit2Var(Obj) : Obj, (fLits && Abc_LitIsCompl(Obj)) ? ~Vec_WrdEntry(vSim0, i) : Vec_WrdEntry(vSim0, i) );
|
||||
Vec_IntForEachEntry( vIn1, Obj, i )
|
||||
Vec_WrdWriteEntry( vSims, fLits ? Abc_Lit2Var(Obj) : Obj, (fLits && Abc_LitIsCompl(Obj)) ? ~Vec_WrdEntry(vSim1, i) : Vec_WrdEntry(vSim1, i) );
|
||||
Gia_ManForEachObjVec( vTfo, p, pObj, i ) {
|
||||
word Sim0 = Vec_WrdEntry(vSims, Gia_ObjFaninId0p(p, pObj) );
|
||||
word Sim1 = Vec_WrdEntry(vSims, Gia_ObjFaninId1p(p, pObj) );
|
||||
Vec_WrdWriteEntry( vSims, Gia_ObjId(p, pObj), (Gia_ObjFaninC0(pObj) ? ~Sim0 : Sim0) & (Gia_ObjFaninC1(pObj) ? ~Sim1 : Sim1) );
|
||||
}
|
||||
Vec_IntForEachEntry( vTfo, Obj, i )
|
||||
Vec_WrdPush( vRes, Vec_WrdEntry(vSims, Obj) );
|
||||
Vec_WrdFree( vSims );
|
||||
return vRes;
|
||||
}
|
||||
iword Gia_ManMulFindGetArg( Vec_Wrd_t * vSim, int i, int fSigned )
|
||||
{
|
||||
int w; iword Res = 0; word Word = 0;
|
||||
Vec_WrdForEachEntry( vSim, Word, w )
|
||||
if ( (Word >> i) & 1 )
|
||||
Res |= ((iword)1 << w);
|
||||
if ( fSigned && ((Word >> i) & 1) )
|
||||
Res |= ~(iword)0 << Vec_WrdSize(vSim);
|
||||
return Res;
|
||||
}
|
||||
void Gia_ManMulFindSetArg( Vec_Wrd_t * vSim, int i, iword iNum )
|
||||
{
|
||||
int w; word * pWords = Vec_WrdArray(vSim);
|
||||
for ( w = 0; w < Vec_WrdSize(vSim); w++ )
|
||||
if ( (iNum >> w) & 1 )
|
||||
pWords[w] |= (word)1 << i;
|
||||
}
|
||||
Vec_Wrd_t * Gia_ManMulFindSim( Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, int fSigned )
|
||||
{
|
||||
assert( Vec_WrdSize(vSim0) + Vec_WrdSize(vSim1) <= 62 );
|
||||
Vec_Wrd_t * vRes = Vec_WrdStart( Vec_WrdSize(vSim0) + Vec_WrdSize(vSim1) );
|
||||
for ( int i = 0; i < 64; i++ )
|
||||
{
|
||||
iword a = Gia_ManMulFindGetArg( vSim0, i, fSigned );
|
||||
iword b = Gia_ManMulFindGetArg( vSim1, i, fSigned );
|
||||
Gia_ManMulFindSetArg( vRes, i, a * b );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
Vec_Wrd_t * Gia_ManMulFindSim2( Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, int fSigned )
|
||||
{
|
||||
extern word * product_many(word *pInfo1, int nBits1, word *pInfo2, int nBits2, int fSigned );
|
||||
word * pRes = product_many( Vec_WrdArray(vSim0), Vec_WrdSize(vSim0), Vec_WrdArray(vSim1), Vec_WrdSize(vSim1), fSigned );
|
||||
return Vec_WrdAllocArray( pRes, Vec_WrdSize(vSim0) + Vec_WrdSize(vSim1) );
|
||||
}
|
||||
int Gia_ManMulFindOutputs( Gia_Man_t * p, Vec_Wec_t * vTerms, int fLits, int fVerbose )
|
||||
{
|
||||
//abctime clkTotal = Abc_Clock();
|
||||
int nDetected = 0;
|
||||
Abc_Random(1);
|
||||
for ( int m = 0; m < Vec_WecSize(vTerms)/3; m++ ) {
|
||||
Vec_Int_t * vIn0 = Vec_WecEntry(vTerms, 3*m+0);
|
||||
Vec_Int_t * vIn1 = Vec_WecEntry(vTerms, 3*m+1);
|
||||
Vec_Int_t * vOut = Vec_WecEntry(vTerms, 3*m+2);
|
||||
Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Vec_IntSize(vIn0) );
|
||||
Vec_Wrd_t * vSim1 = Vec_WrdStartRandom( Vec_IntSize(vIn1) );
|
||||
Vec_Wrd_t * vSimU = Gia_ManMulFindSim2( vSim0, vSim1, 0 );
|
||||
Vec_Wrd_t * vSimS = Gia_ManMulFindSim2( vSim0, vSim1, 1 );
|
||||
Vec_Int_t * vTfo = Gia_ManMulFindTfo( p, vIn0, vIn1, fLits );
|
||||
Vec_Wrd_t * vSims = Gia_ManMulFindSimCone( p, vIn0, vIn1, vSim0, vSim1, vTfo, fLits );
|
||||
Vec_Int_t * vOutU = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vOutS = Vec_IntAlloc( 100 );
|
||||
word Word; int w, iPlace;
|
||||
Vec_WrdForEachEntry( vSimU, Word, w ) {
|
||||
if ( (iPlace = Vec_WrdFind(vSims, Word)) >= 0 )
|
||||
Vec_IntPush( vOutU, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 0) );
|
||||
else if ( (iPlace = Vec_WrdFind(vSims, ~Word)) >= 0 )
|
||||
Vec_IntPush( vOutU, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 1) );
|
||||
else
|
||||
Vec_IntPush( vOutU, -1 );
|
||||
}
|
||||
Vec_WrdForEachEntry( vSimS, Word, w ) {
|
||||
if ( (iPlace = Vec_WrdFind(vSims, Word)) >= 0 )
|
||||
Vec_IntPush( vOutS, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 0) );
|
||||
else if ( (iPlace = Vec_WrdFind(vSims, ~Word)) >= 0 )
|
||||
Vec_IntPush( vOutS, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 1) );
|
||||
else
|
||||
Vec_IntPush( vOutS, -1 );
|
||||
}
|
||||
assert( Vec_IntSize(vOut) == 0 );
|
||||
if ( Vec_IntCountEntry(vOutU, -1) < Vec_IntSize(vOutU) ||
|
||||
Vec_IntCountEntry(vOutS, -1) < Vec_IntSize(vOutS) )
|
||||
{
|
||||
if ( Vec_IntCountEntry(vOutU, -1) < Vec_IntCountEntry(vOutS, -1) ) {
|
||||
Vec_IntAppend( vOut, vOutU ), Vec_IntPush(vOut, 0);
|
||||
nDetected = Vec_IntSize(vOutU) - Vec_IntCountEntry(vOutU, -1);
|
||||
}
|
||||
else {
|
||||
Vec_IntAppend( vOut, vOutS ), Vec_IntPush(vOut, 1);
|
||||
nDetected = Vec_IntSize(vOutS) - Vec_IntCountEntry(vOutS, -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_IntClear(vIn0);
|
||||
Vec_IntClear(vIn1);
|
||||
}
|
||||
Vec_WrdFree( vSim0 );
|
||||
Vec_WrdFree( vSim1 );
|
||||
Vec_WrdFree( vSimU );
|
||||
Vec_WrdFree( vSimS );
|
||||
Vec_WrdFree( vSims );
|
||||
Vec_IntFree( vTfo );
|
||||
Vec_IntFree( vOutU );
|
||||
Vec_IntFree( vOutS );
|
||||
}
|
||||
Vec_WecRemoveEmpty( vTerms );
|
||||
//Abc_PrintTime( 1, "Output detection time", Abc_Clock() - clkTotal );
|
||||
return nDetected;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Gia_ManMulFindCuts( Gia_Man_t * p, int nCutNum, int fVerbose )
|
||||
{
|
||||
extern Vec_Mem_t * Dau_CollectNpnFunctions( word * p, int nVars, int fVerbose );
|
||||
extern Vec_Ptr_t * Gia_ManMatchCutsArray( Vec_Ptr_t * vTtMems, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose );
|
||||
word pTruths[3] = { ABC_CONST(0x6969696969696969), ABC_CONST(0x35C035C035C035C0), ABC_CONST(0xF335ACC0F335ACC0) };
|
||||
Vec_Ptr_t * vTtMems = Vec_PtrAlloc( 3 ); Vec_Mem_t * vTtMem; int i;
|
||||
for ( i = 0; i < 3; i++ )
|
||||
Vec_PtrPush( vTtMems, Dau_CollectNpnFunctions( pTruths+i, i+3, fVerbose ) );
|
||||
Vec_Ptr_t * vAll = Gia_ManMatchCutsArray( vTtMems, p, 5, nCutNum, fVerbose );
|
||||
Vec_PtrForEachEntry( Vec_Mem_t *, vTtMems, vTtMem, i )
|
||||
Vec_MemHashFree( vTtMem ), Vec_MemFree( vTtMem );
|
||||
Vec_PtrFree( vTtMems );
|
||||
return vAll;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindA( Gia_Man_t * p, Vec_Wec_t * vCuts3, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vXors = Gia_ManMulFindXors( p, vCuts3, fVerbose );
|
||||
Vec_Wec_t * vTerms = Gia_ManMulFindAInputs2( p, fVerbose );
|
||||
if ( Vec_WecSize(vTerms) )
|
||||
Gia_ManMulFindOutputs( p, vTerms, 0, fVerbose );
|
||||
Vec_WecFree( vXors );
|
||||
return vTerms;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManMulFindB( Gia_Man_t * p, Vec_Wec_t * vCuts4, Vec_Wec_t * vCuts5, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vTerms = Vec_WecAlloc( 12 );
|
||||
if ( Vec_WecSize(vCuts4) && Vec_WecSize(vCuts5) )
|
||||
vTerms = Gia_ManMulFindBInputs2( p, vCuts4, vCuts5, fVerbose );
|
||||
if ( Vec_WecSize(vTerms) )
|
||||
Gia_ManMulFindOutputs( p, vTerms, 0, fVerbose );
|
||||
return vTerms;
|
||||
}
|
||||
void Gia_ManMulFindPrintSet( Vec_Int_t * vSet, int fLit, int fSkipLast )
|
||||
{
|
||||
int i, Temp, Limit = Vec_IntSize(vSet) - fSkipLast;
|
||||
printf( "{" );
|
||||
if ( Vec_IntSize(vSet) > 16 ) {
|
||||
Vec_IntForEachEntryStop( vSet, Temp, i, 4 ) {
|
||||
if ( Temp == -1 )
|
||||
printf( "n/a%s", i < Limit-1 ? " ":"" );
|
||||
else
|
||||
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
|
||||
}
|
||||
printf( "... " );
|
||||
Vec_IntForEachEntryStartStop( vSet, Temp, i, Limit-4, Limit ) {
|
||||
if ( Temp == -1 )
|
||||
printf( "n/a%s", i < Limit-1 ? " ":"" );
|
||||
else
|
||||
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
Vec_IntForEachEntryStop( vSet, Temp, i, Limit ) {
|
||||
if ( Temp == -1 )
|
||||
printf( "n/a%s", i < Limit-1 ? " ":"" );
|
||||
else
|
||||
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
|
||||
}
|
||||
}
|
||||
printf( "}" );
|
||||
}
|
||||
void Gia_ManMulFindPrintOne( Vec_Wec_t * vTerms, int m, int fBooth, int fInputLits )
|
||||
{
|
||||
Vec_Int_t * vIn0 = Vec_WecEntry(vTerms, 3*m+0);
|
||||
Vec_Int_t * vIn1 = Vec_WecEntry(vTerms, 3*m+1);
|
||||
Vec_Int_t * vOut = Vec_WecEntry(vTerms, 3*m+2);
|
||||
printf( "%sooth %s%ssigned %d x %d: ",
|
||||
fBooth==1 ? "B" : "Non-b",
|
||||
fBooth>=1 ? "radix-4 " : "",
|
||||
Vec_IntEntryLast(vOut) ? "" : "un",
|
||||
Vec_IntSize(vIn0), Vec_IntSize(vIn1) );
|
||||
Gia_ManMulFindPrintSet( vIn0, fInputLits, 0 );
|
||||
printf( " * " );
|
||||
Gia_ManMulFindPrintSet( vIn1, fInputLits, 0 );
|
||||
printf( " = " );
|
||||
Gia_ManMulFindPrintSet( vOut, 1, 1 );
|
||||
printf( "\n" );
|
||||
}
|
||||
void Gia_ManMulFind( Gia_Man_t * p, int nCutNum, int fVerbose )
|
||||
{
|
||||
Vec_Ptr_t * vAll = Gia_ManMulFindCuts( p, nCutNum, fVerbose ); int m;
|
||||
Vec_Wec_t * vCuts3 = (Vec_Wec_t *)Vec_PtrEntry(vAll, 0);
|
||||
Vec_Wec_t * vCuts4 = (Vec_Wec_t *)Vec_PtrEntry(vAll, 1);
|
||||
Vec_Wec_t * vCuts5 = (Vec_Wec_t *)Vec_PtrEntry(vAll, 2);
|
||||
Vec_Wec_t * vTermsB = Gia_ManMulFindB( p, vCuts4, vCuts5, fVerbose );
|
||||
Vec_Wec_t * vTermsA = Gia_ManMulFindA( p, vCuts3, fVerbose );
|
||||
printf( "Detected %d booth and %d non-booth multipliers.\n", Vec_WecSize(vTermsB)/3, Vec_WecSize(vTermsA)/3 );
|
||||
for ( m = 0; m < Vec_WecSize(vTermsA)/3; m++ )
|
||||
Gia_ManMulFindPrintOne( vTermsA, m, 0, 0 );
|
||||
for ( m = 0; m < Vec_WecSize(vTermsB)/3; m++ )
|
||||
Gia_ManMulFindPrintOne( vTermsB, m, 1, 0 );
|
||||
Vec_WecFree( vTermsB );
|
||||
Vec_WecFree( vTermsA );
|
||||
Vec_WecFree( vCuts3 );
|
||||
Vec_WecFree( vCuts4 );
|
||||
Vec_WecFree( vCuts5 );
|
||||
Vec_PtrFree( vAll );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -1,27 +1,32 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cba.c]
|
||||
FileName [giaMulFind3.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Hierarchical word-level netlist.]
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Multiplier detection.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - July 21, 2015.]
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cba.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: giaMulFind3.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cba.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "gia.h"
|
||||
#include "misc/vec/vecHsh.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -30,23 +35,14 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManMulFindNew( Gia_Man_t * p, int nABits, int nFanLim, int fLits, int fVerbose )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -147,6 +147,73 @@ Gia_Man_t * Gia_ManDupMuxes( Gia_Man_t * p, int Limit )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates AIG with XORs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManCreateXors( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Man_t * pNew; Gia_Obj_t * pObj, * pFan0, * pFan1;
|
||||
Vec_Int_t * vRefs = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
int i, iLit0, iLit1, nXors = 0, nObjs = 0;
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
pObj->fMark0 = 0;
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
|
||||
{
|
||||
Vec_IntAddToEntry( vRefs, Gia_ObjId(p, Gia_Regular(pFan0)), 1 );
|
||||
Vec_IntAddToEntry( vRefs, Gia_ObjId(p, Gia_Regular(pFan1)), 1 );
|
||||
pObj->fMark0 = 1;
|
||||
nXors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0(pObj, i), 1 );
|
||||
Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1(pObj, i), 1 );
|
||||
}
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), 1 );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
nObjs += Vec_IntEntry(vRefs, i) > 0;
|
||||
pNew = Gia_ManStart( 1 + Gia_ManCiNum(p) + Gia_ManCoNum(p) + nObjs );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachObj1( p, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
pObj->Value = Gia_ManAppendCi( pNew );
|
||||
else if ( Gia_ObjIsCo(pObj) )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
else if ( Gia_ObjIsBuf(pObj) )
|
||||
pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
else if ( pObj->fMark0 )
|
||||
{
|
||||
Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1);
|
||||
iLit0 = Abc_LitNotCond( Gia_Regular(pFan0)->Value, Gia_IsComplement(pFan0) );
|
||||
iLit1 = Abc_LitNotCond( Gia_Regular(pFan1)->Value, Gia_IsComplement(pFan1) );
|
||||
pObj->Value = Gia_ManAppendXorReal( pNew, iLit0, iLit1 );
|
||||
}
|
||||
else if ( Vec_IntEntry(vRefs, i) > 0 )
|
||||
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
}
|
||||
assert( pNew->nObjs == pNew->nObjsAlloc );
|
||||
pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjs );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
Vec_IntFree( vRefs );
|
||||
//printf( "Created %d XORs.\n", nXors );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives GIA without MUXes.]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,869 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaNewBdd.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Implementation of transduction method.]
|
||||
|
||||
Author [Yukio Miyasaka]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 2023.]
|
||||
|
||||
Revision [$Id: giaNewBdd.h,v 1.00 2023/05/10 00:00:00 Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__aig__gia__giaNewBdd_h
|
||||
#define ABC__aig__gia__giaNewBdd_h
|
||||
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace NewBdd {
|
||||
|
||||
typedef unsigned short var;
|
||||
typedef int bvar;
|
||||
typedef unsigned lit;
|
||||
typedef unsigned short ref;
|
||||
typedef unsigned long long size;
|
||||
typedef unsigned edge;
|
||||
typedef unsigned uniq;
|
||||
typedef unsigned cac;
|
||||
static inline var VarMax() { return std::numeric_limits<var>::max(); }
|
||||
static inline bvar BvarMax() { return std::numeric_limits<bvar>::max(); }
|
||||
static inline lit LitMax() { return std::numeric_limits<lit>::max(); }
|
||||
static inline ref RefMax() { return std::numeric_limits<ref>::max(); }
|
||||
static inline size SizeMax() { return std::numeric_limits<size>::max(); }
|
||||
static inline uniq UniqHash(lit Arg0, lit Arg1) { return Arg0 + 4256249 * Arg1; }
|
||||
static inline cac CacHash(lit Arg0, lit Arg1) { return Arg0 + 4256249 * Arg1; }
|
||||
|
||||
static inline void fatal_error(const char* message) {
|
||||
std::cerr << message << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
class Cache {
|
||||
private:
|
||||
cac nSize;
|
||||
cac nMax;
|
||||
cac Mask;
|
||||
size nLookups;
|
||||
size nHits;
|
||||
size nThold;
|
||||
double HitRate;
|
||||
int nVerbose;
|
||||
std::vector<lit> vCache;
|
||||
|
||||
public:
|
||||
Cache(int nCacheSizeLog, int nCacheMaxLog, int nVerbose): nVerbose(nVerbose) {
|
||||
if(nCacheMaxLog < nCacheSizeLog)
|
||||
fatal_error("nCacheMax must not be smaller than nCacheSize");
|
||||
nMax = (cac)1 << nCacheMaxLog;
|
||||
if(!(nMax << 1))
|
||||
fatal_error("Memout (nCacheMax) in init");
|
||||
nSize = (cac)1 << nCacheSizeLog;
|
||||
if(nVerbose)
|
||||
std::cout << "Allocating " << nSize << " cache entries" << std::endl;
|
||||
vCache.resize(nSize * 3);
|
||||
Mask = nSize - 1;
|
||||
nLookups = 0;
|
||||
nHits = 0;
|
||||
nThold = (nSize == nMax)? SizeMax(): nSize;
|
||||
HitRate = 1;
|
||||
}
|
||||
~Cache() {
|
||||
if(nVerbose)
|
||||
std::cout << "Free " << nSize << " cache entries" << std::endl;
|
||||
}
|
||||
inline lit Lookup(lit x, lit y) {
|
||||
nLookups++;
|
||||
if(nLookups > nThold) {
|
||||
double NewHitRate = (double)nHits / nLookups;
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Cache Hits: " << std::setw(10) << nHits << ", "
|
||||
<< "Lookups: " << std::setw(10) << nLookups << ", "
|
||||
<< "Rate: " << std::setw(10) << NewHitRate
|
||||
<< std::endl;
|
||||
if(NewHitRate > HitRate)
|
||||
Resize();
|
||||
if(nSize == nMax)
|
||||
nThold = SizeMax();
|
||||
else {
|
||||
nThold <<= 1;
|
||||
if(!nThold)
|
||||
nThold = SizeMax();
|
||||
}
|
||||
HitRate = NewHitRate;
|
||||
}
|
||||
cac i = (CacHash(x, y) & Mask) * 3;
|
||||
if(vCache[i] == x && vCache[i + 1] == y) {
|
||||
if(nVerbose >= 3)
|
||||
std::cout << "Cache hit: "
|
||||
<< "x = " << std::setw(10) << x << ", "
|
||||
<< "y = " << std::setw(10) << y << ", "
|
||||
<< "z = " << std::setw(10) << vCache[i + 2] << ", "
|
||||
<< "hash = " << std::hex << (CacHash(x, y) & Mask) << std::dec
|
||||
<< std::endl;
|
||||
nHits++;
|
||||
return vCache[i + 2];
|
||||
}
|
||||
return LitMax();
|
||||
}
|
||||
inline void Insert(lit x, lit y, lit z) {
|
||||
cac i = (CacHash(x, y) & Mask) * 3;
|
||||
vCache[i] = x;
|
||||
vCache[i + 1] = y;
|
||||
vCache[i + 2] = z;
|
||||
if(nVerbose >= 3)
|
||||
std::cout << "Cache ent: "
|
||||
<< "x = " << std::setw(10) << x << ", "
|
||||
<< "y = " << std::setw(10) << y << ", "
|
||||
<< "z = " << std::setw(10) << z << ", "
|
||||
<< "hash = " << std::hex << (CacHash(x, y) & Mask) << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
inline void Clear() {
|
||||
std::fill(vCache.begin(), vCache.end(), 0);
|
||||
}
|
||||
void Resize() {
|
||||
cac nSizeOld = nSize;
|
||||
nSize <<= 1;
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Reallocating " << nSize << " cache entries" << std::endl;
|
||||
vCache.resize(nSize * 3);
|
||||
Mask = nSize - 1;
|
||||
for(cac j = 0; j < nSizeOld; j++) {
|
||||
cac i = j * 3;
|
||||
if(vCache[i] || vCache[i + 1]) {
|
||||
cac hash = (CacHash(vCache[i], vCache[i + 1]) & Mask) * 3;
|
||||
vCache[hash] = vCache[i];
|
||||
vCache[hash + 1] = vCache[i + 1];
|
||||
vCache[hash + 2] = vCache[i + 2];
|
||||
if(nVerbose >= 3)
|
||||
std::cout << "Cache mov: "
|
||||
<< "x = " << std::setw(10) << vCache[i] << ", "
|
||||
<< "y = " << std::setw(10) << vCache[i + 1] << ", "
|
||||
<< "z = " << std::setw(10) << vCache[i + 2] << ", "
|
||||
<< "hash = " << std::hex << (CacHash(vCache[i], vCache[i + 1]) & Mask) << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Param {
|
||||
int nObjsAllocLog;
|
||||
int nObjsMaxLog;
|
||||
int nUniqueSizeLog;
|
||||
double UniqueDensity;
|
||||
int nCacheSizeLog;
|
||||
int nCacheMaxLog;
|
||||
int nCacheVerbose;
|
||||
bool fCountOnes;
|
||||
int nGbc;
|
||||
bvar nReo;
|
||||
double MaxGrowth;
|
||||
bool fReoVerbose;
|
||||
int nVerbose;
|
||||
std::vector<var> *pVar2Level;
|
||||
Param() {
|
||||
nObjsAllocLog = 20;
|
||||
nObjsMaxLog = 25;
|
||||
nUniqueSizeLog = 10;
|
||||
UniqueDensity = 4;
|
||||
nCacheSizeLog = 15;
|
||||
nCacheMaxLog = 20;
|
||||
nCacheVerbose = 0;
|
||||
fCountOnes = false;
|
||||
nGbc = 0;
|
||||
nReo = BvarMax();
|
||||
MaxGrowth = 1.2;
|
||||
fReoVerbose = false;
|
||||
nVerbose = 0;
|
||||
pVar2Level = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class Man {
|
||||
private:
|
||||
var nVars;
|
||||
bvar nObjs;
|
||||
bvar nObjsAlloc;
|
||||
bvar nObjsMax;
|
||||
bvar RemovedHead;
|
||||
int nGbc;
|
||||
bvar nReo;
|
||||
double MaxGrowth;
|
||||
bool fReoVerbose;
|
||||
int nVerbose;
|
||||
std::vector<var> vVars;
|
||||
std::vector<var> Var2Level;
|
||||
std::vector<var> Level2Var;
|
||||
std::vector<lit> vObjs;
|
||||
std::vector<bvar> vNexts;
|
||||
std::vector<bool> vMarks;
|
||||
std::vector<ref> vRefs;
|
||||
std::vector<edge> vEdges;
|
||||
std::vector<double> vOneCounts;
|
||||
std::vector<uniq> vUniqueMasks;
|
||||
std::vector<bvar> vUniqueCounts;
|
||||
std::vector<bvar> vUniqueTholds;
|
||||
std::vector<std::vector<bvar> > vvUnique;
|
||||
Cache *cache;
|
||||
|
||||
public:
|
||||
inline lit Bvar2Lit(bvar a) const { return (lit)a << 1; }
|
||||
inline lit Bvar2Lit(bvar a, bool c) const { return ((lit)a << 1) ^ (lit)c; }
|
||||
inline bvar Lit2Bvar(lit x) const { return (bvar)(x >> 1); }
|
||||
inline var VarOfBvar(bvar a) const { return vVars[a]; }
|
||||
inline lit ThenOfBvar(bvar a) const { return vObjs[Bvar2Lit(a)]; }
|
||||
inline lit ElseOfBvar(bvar a) const { return vObjs[Bvar2Lit(a, true)]; }
|
||||
inline ref RefOfBvar(bvar a) const { return vRefs[a]; }
|
||||
inline lit Const0() const { return (lit)0; }
|
||||
inline lit Const1() const { return (lit)1; }
|
||||
inline bool IsConst0(lit x) const { return x == Const0(); }
|
||||
inline bool IsConst1(lit x) const { return x == Const1(); }
|
||||
inline lit IthVar(var v) const { return Bvar2Lit((bvar)v + 1); }
|
||||
inline lit LitRegular(lit x) const { return x & ~(lit)1; }
|
||||
inline lit LitIrregular(lit x) const { return x | (lit)1; }
|
||||
inline lit LitNot(lit x) const { return x ^ (lit)1; }
|
||||
inline lit LitNotCond(lit x, bool c) const { return x ^ (lit)c; }
|
||||
inline bool LitIsCompl(lit x) const { return x & (lit)1; }
|
||||
inline bool LitIsEq(lit x, lit y) const { return x == y; }
|
||||
inline var Var(lit x) const { return vVars[Lit2Bvar(x)]; }
|
||||
inline var Level(lit x) const { return Var2Level[Var(x)]; }
|
||||
inline lit Then(lit x) const { return LitNotCond(vObjs[LitRegular(x)], LitIsCompl(x)); }
|
||||
inline lit Else(lit x) const { return LitNotCond(vObjs[LitIrregular(x)], LitIsCompl(x)); }
|
||||
inline ref Ref(lit x) const { return vRefs[Lit2Bvar(x)]; }
|
||||
inline double OneCount(lit x) const {
|
||||
if(vOneCounts.empty())
|
||||
fatal_error("fCountOnes was not set");
|
||||
if(LitIsCompl(x))
|
||||
return std::pow(2.0, nVars) - vOneCounts[Lit2Bvar(x)];
|
||||
return vOneCounts[Lit2Bvar(x)];
|
||||
}
|
||||
|
||||
public:
|
||||
inline void IncRef(lit x) { if(!vRefs.empty() && Ref(x) != RefMax()) vRefs[Lit2Bvar(x)]++; }
|
||||
inline void DecRef(lit x) { if(!vRefs.empty() && Ref(x) != RefMax()) vRefs[Lit2Bvar(x)]--; }
|
||||
|
||||
private:
|
||||
inline bool Mark(lit x) const { return vMarks[Lit2Bvar(x)]; }
|
||||
inline edge Edge(lit x) const { return vEdges[Lit2Bvar(x)]; }
|
||||
inline void SetMark(lit x) { vMarks[Lit2Bvar(x)] = true; }
|
||||
inline void ResetMark(lit x) { vMarks[Lit2Bvar(x)] = false; }
|
||||
inline void IncEdge(lit x) { vEdges[Lit2Bvar(x)]++; }
|
||||
inline void DecEdge(lit x) { vEdges[Lit2Bvar(x)]--; }
|
||||
inline bool MarkOfBvar(bvar a) const { return vMarks[a]; }
|
||||
inline edge EdgeOfBvar(bvar a) const { return vEdges[a]; }
|
||||
inline void SetVarOfBvar(bvar a, var v) { vVars[a] = v; }
|
||||
inline void SetThenOfBvar(bvar a, lit x) { vObjs[Bvar2Lit(a)] = x; }
|
||||
inline void SetElseOfBvar(bvar a, lit x) { vObjs[Bvar2Lit(a, true)] = x; }
|
||||
inline void SetMarkOfBvar(bvar a) { vMarks[a] = true; }
|
||||
inline void ResetMarkOfBvar(bvar a) { vMarks[a] = false; }
|
||||
inline void RemoveBvar(bvar a) {
|
||||
var v = VarOfBvar(a);
|
||||
SetVarOfBvar(a, VarMax());
|
||||
std::vector<bvar>::iterator q = vvUnique[v].begin() + (UniqHash(ThenOfBvar(a), ElseOfBvar(a)) & vUniqueMasks[v]);
|
||||
for(; *q; q = vNexts.begin() + *q)
|
||||
if(*q == a)
|
||||
break;
|
||||
bvar next = vNexts[*q];
|
||||
vNexts[*q] = RemovedHead;
|
||||
RemovedHead = *q;
|
||||
*q = next;
|
||||
vUniqueCounts[v]--;
|
||||
}
|
||||
|
||||
private:
|
||||
void SetMark_rec(lit x) {
|
||||
if(x < 2 || Mark(x))
|
||||
return;
|
||||
SetMark(x);
|
||||
SetMark_rec(Then(x));
|
||||
SetMark_rec(Else(x));
|
||||
}
|
||||
void ResetMark_rec(lit x) {
|
||||
if(x < 2 || !Mark(x))
|
||||
return;
|
||||
ResetMark(x);
|
||||
ResetMark_rec(Then(x));
|
||||
ResetMark_rec(Else(x));
|
||||
}
|
||||
bvar CountNodes_rec(lit x) {
|
||||
if(x < 2 || Mark(x))
|
||||
return 0;
|
||||
SetMark(x);
|
||||
return 1 + CountNodes_rec(Then(x)) + CountNodes_rec(Else(x));
|
||||
}
|
||||
void CountEdges_rec(lit x) {
|
||||
if(x < 2)
|
||||
return;
|
||||
IncEdge(x);
|
||||
if(Mark(x))
|
||||
return;
|
||||
SetMark(x);
|
||||
CountEdges_rec(Then(x));
|
||||
CountEdges_rec(Else(x));
|
||||
}
|
||||
void CountEdges() {
|
||||
vEdges.resize(nObjsAlloc);
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
CountEdges_rec(Bvar2Lit(a));
|
||||
for(bvar a = 1; a <= (bvar)nVars; a++)
|
||||
vEdges[a]++;
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
ResetMark_rec(Bvar2Lit(a));
|
||||
}
|
||||
|
||||
public:
|
||||
bool Resize() {
|
||||
if(nObjsAlloc == nObjsMax)
|
||||
return false;
|
||||
lit nObjsAllocLit = (lit)nObjsAlloc << 1;
|
||||
if(nObjsAllocLit > (lit)BvarMax())
|
||||
nObjsAlloc = BvarMax();
|
||||
else
|
||||
nObjsAlloc = (bvar)nObjsAllocLit;
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Reallocating " << nObjsAlloc << " nodes" << std::endl;
|
||||
vVars.resize(nObjsAlloc);
|
||||
vObjs.resize((lit)nObjsAlloc * 2);
|
||||
vNexts.resize(nObjsAlloc);
|
||||
vMarks.resize(nObjsAlloc);
|
||||
if(!vRefs.empty())
|
||||
vRefs.resize(nObjsAlloc);
|
||||
if(!vEdges.empty())
|
||||
vEdges.resize(nObjsAlloc);
|
||||
if(!vOneCounts.empty())
|
||||
vOneCounts.resize(nObjsAlloc);
|
||||
return true;
|
||||
}
|
||||
void ResizeUnique(var v) {
|
||||
uniq nUniqueSize, nUniqueSizeOld;
|
||||
nUniqueSize = nUniqueSizeOld = vvUnique[v].size();
|
||||
nUniqueSize <<= 1;
|
||||
if(!nUniqueSize) {
|
||||
vUniqueTholds[v] = BvarMax();
|
||||
return;
|
||||
}
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Reallocating " << nUniqueSize << " unique table entries for Var " << v << std::endl;
|
||||
vvUnique[v].resize(nUniqueSize);
|
||||
vUniqueMasks[v] = nUniqueSize - 1;
|
||||
for(uniq i = 0; i < nUniqueSizeOld; i++) {
|
||||
std::vector<bvar>::iterator q, tail, tail1, tail2;
|
||||
q = tail1 = vvUnique[v].begin() + i;
|
||||
tail2 = q + nUniqueSizeOld;
|
||||
while(*q) {
|
||||
uniq hash = UniqHash(ThenOfBvar(*q), ElseOfBvar(*q)) & vUniqueMasks[v];
|
||||
if(hash == i)
|
||||
tail = tail1;
|
||||
else
|
||||
tail = tail2;
|
||||
if(tail != q)
|
||||
*tail = *q, *q = 0;
|
||||
q = vNexts.begin() + *tail;
|
||||
if(tail == tail1)
|
||||
tail1 = q;
|
||||
else
|
||||
tail2 = q;
|
||||
}
|
||||
}
|
||||
vUniqueTholds[v] <<= 1;
|
||||
if((lit)vUniqueTholds[v] > (lit)BvarMax())
|
||||
vUniqueTholds[v] = BvarMax();
|
||||
}
|
||||
bool Gbc() {
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Garbage collect" << std::endl;
|
||||
if(!vEdges.empty()) {
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(!EdgeOfBvar(a) && VarOfBvar(a) != VarMax())
|
||||
RemoveBvar(a);
|
||||
} else {
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
SetMark_rec(Bvar2Lit(a));
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(!MarkOfBvar(a) && VarOfBvar(a) != VarMax())
|
||||
RemoveBvar(a);
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
ResetMark_rec(Bvar2Lit(a));
|
||||
}
|
||||
cache->Clear();
|
||||
return RemovedHead;
|
||||
}
|
||||
|
||||
private:
|
||||
inline lit UniqueCreateInt(var v, lit x1, lit x0) {
|
||||
std::vector<bvar>::iterator p, q;
|
||||
p = q = vvUnique[v].begin() + (UniqHash(x1, x0) & vUniqueMasks[v]);
|
||||
for(; *q; q = vNexts.begin() + *q)
|
||||
if(VarOfBvar(*q) == v && ThenOfBvar(*q) == x1 && ElseOfBvar(*q) == x0)
|
||||
return Bvar2Lit(*q);
|
||||
bvar next = *p;
|
||||
if(nObjs < nObjsAlloc)
|
||||
*p = nObjs++;
|
||||
else if(RemovedHead)
|
||||
*p = RemovedHead, RemovedHead = vNexts[*p];
|
||||
else
|
||||
return LitMax();
|
||||
SetVarOfBvar(*p, v);
|
||||
SetThenOfBvar(*p, x1);
|
||||
SetElseOfBvar(*p, x0);
|
||||
vNexts[*p] = next;
|
||||
if(!vOneCounts.empty())
|
||||
vOneCounts[*p] = OneCount(x1) / 2 + OneCount(x0) / 2;
|
||||
if(nVerbose >= 3) {
|
||||
std::cout << "Create node " << std::setw(10) << *p << ": "
|
||||
<< "Var = " << std::setw(6) << v << ", "
|
||||
<< "Then = " << std::setw(10) << x1 << ", "
|
||||
<< "Else = " << std::setw(10) << x0;
|
||||
if(!vOneCounts.empty())
|
||||
std::cout << ", Ones = " << std::setw(10) << vOneCounts[*q];
|
||||
std::cout << std::endl;
|
||||
}
|
||||
vUniqueCounts[v]++;
|
||||
if(vUniqueCounts[v] > vUniqueTholds[v]) {
|
||||
bvar a = *p;
|
||||
ResizeUnique(v);
|
||||
return Bvar2Lit(a);
|
||||
}
|
||||
return Bvar2Lit(*p);
|
||||
}
|
||||
inline lit UniqueCreate(var v, lit x1, lit x0) {
|
||||
if(x1 == x0)
|
||||
return x1;
|
||||
lit x;
|
||||
while(true) {
|
||||
if(!LitIsCompl(x0))
|
||||
x = UniqueCreateInt(v, x1, x0);
|
||||
else
|
||||
x = UniqueCreateInt(v, LitNot(x1), LitNot(x0));
|
||||
if(x == LitMax()) {
|
||||
bool fRemoved = false;
|
||||
if(nGbc > 1)
|
||||
fRemoved = Gbc();
|
||||
if(!Resize() && !fRemoved && (nGbc != 1 || !Gbc()))
|
||||
fatal_error("Memout (node)");
|
||||
} else
|
||||
break;
|
||||
}
|
||||
return LitIsCompl(x0)? LitNot(x): x;
|
||||
}
|
||||
lit And_rec(lit x, lit y) {
|
||||
if(x == 0 || y == 1)
|
||||
return x;
|
||||
if(x == 1 || y == 0)
|
||||
return y;
|
||||
if(Lit2Bvar(x) == Lit2Bvar(y))
|
||||
return (x == y)? x: 0;
|
||||
if(x > y)
|
||||
std::swap(x, y);
|
||||
lit z = cache->Lookup(x, y);
|
||||
if(z != LitMax())
|
||||
return z;
|
||||
var v;
|
||||
lit x0, x1, y0, y1;
|
||||
if(Level(x) < Level(y))
|
||||
v = Var(x), x1 = Then(x), x0 = Else(x), y0 = y1 = y;
|
||||
else if(Level(x) > Level(y))
|
||||
v = Var(y), x0 = x1 = x, y1 = Then(y), y0 = Else(y);
|
||||
else
|
||||
v = Var(x), x1 = Then(x), x0 = Else(x), y1 = Then(y), y0 = Else(y);
|
||||
lit z1 = And_rec(x1, y1);
|
||||
IncRef(z1);
|
||||
lit z0 = And_rec(x0, y0);
|
||||
IncRef(z0);
|
||||
z = UniqueCreate(v, z1, z0);
|
||||
DecRef(z1);
|
||||
DecRef(z0);
|
||||
cache->Insert(x, y, z);
|
||||
return z;
|
||||
}
|
||||
|
||||
private:
|
||||
bvar Swap(var i) {
|
||||
var v1 = Level2Var[i];
|
||||
var v2 = Level2Var[i + 1];
|
||||
bvar f = 0;
|
||||
bvar diff = 0;
|
||||
for(std::vector<bvar>::iterator p = vvUnique[v1].begin(); p != vvUnique[v1].end(); p++) {
|
||||
std::vector<bvar>::iterator q = p;
|
||||
while(*q) {
|
||||
if(!EdgeOfBvar(*q)) {
|
||||
SetVarOfBvar(*q, VarMax());
|
||||
bvar next = vNexts[*q];
|
||||
vNexts[*q] = RemovedHead;
|
||||
RemovedHead = *q;
|
||||
*q = next;
|
||||
vUniqueCounts[v1]--;
|
||||
continue;
|
||||
}
|
||||
lit f1 = ThenOfBvar(*q);
|
||||
lit f0 = ElseOfBvar(*q);
|
||||
if(Var(f1) == v2 || Var(f0) == v2) {
|
||||
DecEdge(f1);
|
||||
if(Var(f1) == v2 && !Edge(f1))
|
||||
DecEdge(Then(f1)), DecEdge(Else(f1)), diff--;
|
||||
DecEdge(f0);
|
||||
if(Var(f0) == v2 && !Edge(f0))
|
||||
DecEdge(Then(f0)), DecEdge(Else(f0)), diff--;
|
||||
bvar next = vNexts[*q];
|
||||
vNexts[*q] = f;
|
||||
f = *q;
|
||||
*q = next;
|
||||
vUniqueCounts[v1]--;
|
||||
continue;
|
||||
}
|
||||
q = vNexts.begin() + *q;
|
||||
}
|
||||
}
|
||||
while(f) {
|
||||
lit f1 = ThenOfBvar(f);
|
||||
lit f0 = ElseOfBvar(f);
|
||||
lit f00, f01, f10, f11;
|
||||
if(Var(f1) == v2)
|
||||
f11 = Then(f1), f10 = Else(f1);
|
||||
else
|
||||
f10 = f11 = f1;
|
||||
if(Var(f0) == v2)
|
||||
f01 = Then(f0), f00 = Else(f0);
|
||||
else
|
||||
f00 = f01 = f0;
|
||||
if(f11 == f01)
|
||||
f1 = f11;
|
||||
else {
|
||||
f1 = UniqueCreate(v1, f11, f01);
|
||||
if(!Edge(f1))
|
||||
IncEdge(f11), IncEdge(f01), diff++;
|
||||
}
|
||||
IncEdge(f1);
|
||||
IncRef(f1);
|
||||
if(f10 == f00)
|
||||
f0 = f10;
|
||||
else {
|
||||
f0 = UniqueCreate(v1, f10, f00);
|
||||
if(!Edge(f0))
|
||||
IncEdge(f10), IncEdge(f00), diff++;
|
||||
}
|
||||
IncEdge(f0);
|
||||
DecRef(f1);
|
||||
SetVarOfBvar(f, v2);
|
||||
SetThenOfBvar(f, f1);
|
||||
SetElseOfBvar(f, f0);
|
||||
std::vector<bvar>::iterator q = vvUnique[v2].begin() + (UniqHash(f1, f0) & vUniqueMasks[v2]);
|
||||
lit next = vNexts[f];
|
||||
vNexts[f] = *q;
|
||||
*q = f;
|
||||
vUniqueCounts[v2]++;
|
||||
f = next;
|
||||
}
|
||||
Var2Level[v1] = i + 1;
|
||||
Var2Level[v2] = i;
|
||||
Level2Var[i] = v2;
|
||||
Level2Var[i + 1] = v1;
|
||||
return diff;
|
||||
}
|
||||
void Sift() {
|
||||
bvar count = CountNodes();
|
||||
std::vector<var> sift_order(nVars);
|
||||
for(var v = 0; v < nVars; v++)
|
||||
sift_order[v] = v;
|
||||
for(var i = 0; i < nVars; i++) {
|
||||
var max_j = i;
|
||||
for(var j = i + 1; j < nVars; j++)
|
||||
if(vUniqueCounts[sift_order[j]] > vUniqueCounts[sift_order[max_j]])
|
||||
max_j = j;
|
||||
if(max_j != i)
|
||||
std::swap(sift_order[max_j], sift_order[i]);
|
||||
}
|
||||
for(var v = 0; v < nVars; v++) {
|
||||
bvar lev = Var2Level[sift_order[v]];
|
||||
bool UpFirst = lev < (bvar)(nVars / 2);
|
||||
bvar min_lev = lev;
|
||||
bvar min_diff = 0;
|
||||
bvar diff = 0;
|
||||
bvar thold = count * (MaxGrowth - 1);
|
||||
if(fReoVerbose)
|
||||
std::cout << "Sift " << sift_order[v] << " : Level = " << lev << " Count = " << count << " Thold = " << thold << std::endl;
|
||||
if(UpFirst) {
|
||||
lev--;
|
||||
for(; lev >= 0; lev--) {
|
||||
diff += Swap(lev);
|
||||
if(fReoVerbose)
|
||||
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
|
||||
if(diff < min_diff)
|
||||
min_lev = lev, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
|
||||
else if(diff > thold) {
|
||||
lev--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lev++;
|
||||
}
|
||||
for(; lev < (bvar)nVars - 1; lev++) {
|
||||
diff += Swap(lev);
|
||||
if(fReoVerbose)
|
||||
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
|
||||
if(diff <= min_diff)
|
||||
min_lev = lev + 1, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
|
||||
else if(diff > thold) {
|
||||
lev++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lev--;
|
||||
if(UpFirst) {
|
||||
for(; lev >= min_lev; lev--) {
|
||||
diff += Swap(lev);
|
||||
if(fReoVerbose)
|
||||
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
|
||||
}
|
||||
} else {
|
||||
for(; lev >= 0; lev--) {
|
||||
diff += Swap(lev);
|
||||
if(fReoVerbose)
|
||||
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
|
||||
if(diff <= min_diff)
|
||||
min_lev = lev, min_diff = diff, thold = (count + diff) * (MaxGrowth - 1);
|
||||
else if(diff > thold) {
|
||||
lev--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
lev++;
|
||||
for(; lev < min_lev; lev++) {
|
||||
diff += Swap(lev);
|
||||
if(fReoVerbose)
|
||||
std::cout << "\tSwap " << lev << " : Diff = " << diff << " Thold = " << thold << std::endl;
|
||||
}
|
||||
}
|
||||
count += min_diff;
|
||||
if(fReoVerbose)
|
||||
std::cout << "Sifted " << sift_order[v] << " : Level = " << min_lev << " Count = " << count << " Thold = " << thold << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Man(int nVars_, Param p) {
|
||||
nVerbose = p.nVerbose;
|
||||
// parameter sanity check
|
||||
if(p.nObjsMaxLog < p.nObjsAllocLog)
|
||||
fatal_error("nObjsMax must not be smaller than nObjsAlloc");
|
||||
if(nVars_ >= (int)VarMax())
|
||||
fatal_error("Memout (nVars) in init");
|
||||
nVars = nVars_;
|
||||
lit nObjsMaxLit = (lit)1 << p.nObjsMaxLog;
|
||||
if(!nObjsMaxLit)
|
||||
fatal_error("Memout (nObjsMax) in init");
|
||||
if(nObjsMaxLit > (lit)BvarMax())
|
||||
nObjsMax = BvarMax();
|
||||
else
|
||||
nObjsMax = (bvar)nObjsMaxLit;
|
||||
lit nObjsAllocLit = (lit)1 << p.nObjsAllocLog;
|
||||
if(!nObjsAllocLit)
|
||||
fatal_error("Memout (nObjsAlloc) in init");
|
||||
if(nObjsAllocLit > (lit)BvarMax())
|
||||
nObjsAlloc = BvarMax();
|
||||
else
|
||||
nObjsAlloc = (bvar)nObjsAllocLit;
|
||||
if(nObjsAlloc <= (bvar)nVars)
|
||||
fatal_error("nObjsAlloc must be larger than nVars");
|
||||
uniq nUniqueSize = (uniq)1 << p.nUniqueSizeLog;
|
||||
if(!nUniqueSize)
|
||||
fatal_error("Memout (nUniqueSize) in init");
|
||||
// allocation
|
||||
if(nVerbose)
|
||||
std::cout << "Allocating " << nObjsAlloc << " nodes and " << nVars << " x " << nUniqueSize << " unique table entries" << std::endl;
|
||||
vVars.resize(nObjsAlloc);
|
||||
vObjs.resize((lit)nObjsAlloc * 2);
|
||||
vNexts.resize(nObjsAlloc);
|
||||
vMarks.resize(nObjsAlloc);
|
||||
vvUnique.resize(nVars);
|
||||
vUniqueMasks.resize(nVars);
|
||||
vUniqueCounts.resize(nVars);
|
||||
vUniqueTholds.resize(nVars);
|
||||
for(var v = 0; v < nVars; v++) {
|
||||
vvUnique[v].resize(nUniqueSize);
|
||||
vUniqueMasks[v] = nUniqueSize - 1;
|
||||
if((lit)(nUniqueSize * p.UniqueDensity) > (lit)BvarMax())
|
||||
vUniqueTholds[v] = BvarMax();
|
||||
else
|
||||
vUniqueTholds[v] = (bvar)(nUniqueSize * p.UniqueDensity);
|
||||
}
|
||||
if(p.fCountOnes) {
|
||||
if(nVars > 1023)
|
||||
fatal_error("nVars must be less than 1024 to count ones");
|
||||
vOneCounts.resize(nObjsAlloc);
|
||||
}
|
||||
// set up cache
|
||||
cache = new Cache(p.nCacheSizeLog, p.nCacheMaxLog, p.nCacheVerbose);
|
||||
// create nodes for variables
|
||||
nObjs = 1;
|
||||
vVars[0] = VarMax();
|
||||
for(var v = 0; v < nVars; v++)
|
||||
UniqueCreateInt(v, 1, 0);
|
||||
// set up variable order
|
||||
Var2Level.resize(nVars);
|
||||
Level2Var.resize(nVars);
|
||||
for(var v = 0; v < nVars; v++) {
|
||||
if(p.pVar2Level)
|
||||
Var2Level[v] = (*p.pVar2Level)[v];
|
||||
else
|
||||
Var2Level[v] = v;
|
||||
Level2Var[Var2Level[v]] = v;
|
||||
}
|
||||
// set other parameters
|
||||
RemovedHead = 0;
|
||||
nGbc = p.nGbc;
|
||||
nReo = p.nReo;
|
||||
MaxGrowth = p.MaxGrowth;
|
||||
fReoVerbose = p.fReoVerbose;
|
||||
if(nGbc || nReo != BvarMax())
|
||||
vRefs.resize(nObjsAlloc);
|
||||
}
|
||||
~Man() {
|
||||
if(nVerbose) {
|
||||
std::cout << "Free " << nObjsAlloc << " nodes (" << nObjs << " live nodes)" << std::endl;
|
||||
std::cout << "Free {";
|
||||
std::string delim;
|
||||
for(var v = 0; v < nVars; v++) {
|
||||
std::cout << delim << vvUnique[v].size();
|
||||
delim = ", ";
|
||||
}
|
||||
std::cout << "} unique table entries" << std::endl;
|
||||
if(!vRefs.empty())
|
||||
std::cout << "Free " << vRefs.size() << " refs" << std::endl;
|
||||
}
|
||||
delete cache;
|
||||
}
|
||||
void Reorder() {
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Reorder" << std::endl;
|
||||
int nGbc_ = nGbc;
|
||||
nGbc = 0;
|
||||
CountEdges();
|
||||
Sift();
|
||||
vEdges.clear();
|
||||
cache->Clear();
|
||||
nGbc = nGbc_;
|
||||
}
|
||||
inline lit And(lit x, lit y) {
|
||||
if(nObjs > nReo) {
|
||||
Reorder();
|
||||
while(nReo < nObjs) {
|
||||
nReo <<= 1;
|
||||
if((lit)nReo > (lit)BvarMax())
|
||||
nReo = BvarMax();
|
||||
}
|
||||
}
|
||||
return And_rec(x, y);
|
||||
}
|
||||
inline lit Or(lit x, lit y) {
|
||||
return LitNot(And(LitNot(x), LitNot(y)));
|
||||
}
|
||||
|
||||
public:
|
||||
void SetRef(std::vector<lit> const &vLits) {
|
||||
vRefs.clear();
|
||||
vRefs.resize(nObjsAlloc);
|
||||
for(size_t i = 0; i < vLits.size(); i++)
|
||||
IncRef(vLits[i]);
|
||||
}
|
||||
void RemoveRefIfUnused() {
|
||||
if(!nGbc && nReo == BvarMax())
|
||||
vRefs.clear();
|
||||
}
|
||||
void TurnOnReo(int nReo_ = 0, std::vector<lit> const *vLits = NULL) {
|
||||
if(nReo_)
|
||||
nReo = nReo_;
|
||||
else
|
||||
nReo = nObjs << 1;
|
||||
if((lit)nReo > (lit)BvarMax())
|
||||
nReo = BvarMax();
|
||||
if(vRefs.empty()) {
|
||||
if(vLits)
|
||||
SetRef(*vLits);
|
||||
else
|
||||
vRefs.resize(nObjsAlloc);
|
||||
}
|
||||
}
|
||||
void TurnOffReo() {
|
||||
nReo = BvarMax();
|
||||
}
|
||||
var GetNumVars() const {
|
||||
return nVars;
|
||||
}
|
||||
void GetOrdering(std::vector<int> &Var2Level_) {
|
||||
Var2Level_.resize(nVars);
|
||||
for(var v = 0; v < nVars; v++)
|
||||
Var2Level_[v] = Var2Level[v];
|
||||
}
|
||||
bvar CountNodes() {
|
||||
bvar count = 1;
|
||||
if(!vEdges.empty()) {
|
||||
for(bvar a = 1; a < nObjs; a++)
|
||||
if(EdgeOfBvar(a))
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
for(bvar a = 1; a <= (bvar)nVars; a++) {
|
||||
count++;
|
||||
SetMarkOfBvar(a);
|
||||
}
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
count += CountNodes_rec(Bvar2Lit(a));
|
||||
for(bvar a = 1; a <= (bvar)nVars; a++)
|
||||
ResetMarkOfBvar(a);
|
||||
for(bvar a = (bvar)nVars + 1; a < nObjs; a++)
|
||||
if(RefOfBvar(a))
|
||||
ResetMark_rec(Bvar2Lit(a));
|
||||
return count;
|
||||
}
|
||||
bvar CountNodes(std::vector<lit> const &vLits) {
|
||||
bvar count = 1;
|
||||
for(size_t i = 0; i < vLits.size(); i++)
|
||||
count += CountNodes_rec(vLits[i]);
|
||||
for(size_t i = 0; i < vLits.size(); i++)
|
||||
ResetMark_rec(vLits[i]);
|
||||
return count;
|
||||
}
|
||||
void PrintStats() {
|
||||
bvar nRemoved = 0;
|
||||
bvar a = RemovedHead;
|
||||
while(a)
|
||||
a = vNexts[a], nRemoved++;
|
||||
bvar nLive = 1;
|
||||
for(var v = 0; v < nVars; v++)
|
||||
nLive += vUniqueCounts[v];
|
||||
std::cout << "ref: " << std::setw(10) << (vRefs.empty()? 0: CountNodes()) << ", "
|
||||
<< "used: " << std::setw(10) << nObjs << ", "
|
||||
<< "live: " << std::setw(10) << nLive << ", "
|
||||
<< "dead: " << std::setw(10) << nRemoved << ", "
|
||||
<< "alloc: " << std::setw(10) << nObjsAlloc
|
||||
<< std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaNewTt.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Implementation of transduction method.]
|
||||
|
||||
Author [Yukio Miyasaka]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 2023.]
|
||||
|
||||
Revision [$Id: giaNewTt.h,v 1.00 2023/05/10 00:00:00 Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__aig__gia__giaNewTt_h
|
||||
#define ABC__aig__gia__giaNewTt_h
|
||||
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <bitset>
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace NewTt {
|
||||
|
||||
typedef int bvar;
|
||||
typedef unsigned lit;
|
||||
typedef unsigned short ref;
|
||||
typedef unsigned long long size;
|
||||
|
||||
static inline bvar BvarMax() { return std::numeric_limits<bvar>::max(); }
|
||||
static inline lit LitMax() { return std::numeric_limits<lit>::max(); }
|
||||
static inline ref RefMax() { return std::numeric_limits<ref>::max(); }
|
||||
static inline size SizeMax() { return std::numeric_limits<size>::max(); }
|
||||
|
||||
static void fatal_error(const char* message) {
|
||||
std::cerr << message << std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
struct Param {
|
||||
int nObjsAllocLog;
|
||||
int nObjsMaxLog;
|
||||
int nVerbose;
|
||||
bool fCountOnes;
|
||||
int nGbc;
|
||||
int nReo; // dummy
|
||||
std::vector<int> *pVar2Level; // dummy
|
||||
Param() {
|
||||
nObjsAllocLog = 15;
|
||||
nObjsMaxLog = 20;
|
||||
nVerbose = 0;
|
||||
fCountOnes = false;
|
||||
nGbc = 0;
|
||||
nReo = BvarMax();
|
||||
}
|
||||
};
|
||||
|
||||
class Man {
|
||||
private:
|
||||
typedef unsigned long long word;
|
||||
typedef std::bitset<64> bsw;
|
||||
static inline int ww() { return 64; } // word width
|
||||
static inline int lww() { return 6; } // log word width
|
||||
static inline word one() {return 0xffffffffffffffffull; }
|
||||
static inline word vars(int i) {
|
||||
static const word vars[] = {0xaaaaaaaaaaaaaaaaull,
|
||||
0xccccccccccccccccull,
|
||||
0xf0f0f0f0f0f0f0f0ull,
|
||||
0xff00ff00ff00ff00ull,
|
||||
0xffff0000ffff0000ull,
|
||||
0xffffffff00000000ull};
|
||||
return vars[i];
|
||||
}
|
||||
static inline word ones(int i) {
|
||||
static const word ones[] = {0x0000000000000001ull,
|
||||
0x0000000000000003ull,
|
||||
0x000000000000000full,
|
||||
0x00000000000000ffull,
|
||||
0x000000000000ffffull,
|
||||
0x00000000ffffffffull,
|
||||
0xffffffffffffffffull};
|
||||
return ones[i];
|
||||
}
|
||||
|
||||
private:
|
||||
int nVars;
|
||||
bvar nObjs;
|
||||
bvar nObjsAlloc;
|
||||
bvar nObjsMax;
|
||||
size nSize;
|
||||
size nTotalSize;
|
||||
std::vector<word> vVals;
|
||||
std::vector<bvar> vDeads;
|
||||
std::vector<ref> vRefs;
|
||||
int nGbc;
|
||||
int nVerbose;
|
||||
|
||||
public:
|
||||
inline lit Bvar2Lit(bvar a) const { return (lit)a << 1; }
|
||||
inline bvar Lit2Bvar(lit x) const { return (bvar)(x >> 1); }
|
||||
inline lit IthVar(int v) const { return ((lit)v + 1) << 1; }
|
||||
inline lit LitNot(lit x) const { return x ^ (lit)1; }
|
||||
inline lit LitNotCond(lit x, bool c) const { return x ^ (lit)c; }
|
||||
inline bool LitIsCompl(lit x) const { return x & (lit)1; }
|
||||
inline ref Ref(lit x) const { return vRefs[Lit2Bvar(x)]; }
|
||||
inline lit Const0() const { return (lit)0; }
|
||||
inline lit Const1() const { return (lit)1; }
|
||||
inline bool IsConst0(lit x) const {
|
||||
bvar a = Lit2Bvar(x);
|
||||
word c = LitIsCompl(x)? one(): 0;
|
||||
for(size j = 0; j < nSize; j++)
|
||||
if(vVals[nSize * a + j] ^ c)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
inline bool IsConst1(lit x) const {
|
||||
bvar a = Lit2Bvar(x);
|
||||
word c = LitIsCompl(x)? one(): 0;
|
||||
for(size j = 0; j < nSize; j++)
|
||||
if(~(vVals[nSize * a + j] ^ c))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
inline bool LitIsEq(lit x, lit y) const {
|
||||
if(x == y)
|
||||
return true;
|
||||
if(x == LitMax() || y == LitMax())
|
||||
return false;
|
||||
bvar xvar = Lit2Bvar(x);
|
||||
bvar yvar = Lit2Bvar(y);
|
||||
word c = LitIsCompl(x) ^ LitIsCompl(y)? one(): 0;
|
||||
for(size j = 0; j < nSize; j++)
|
||||
if(vVals[nSize * xvar + j] ^ vVals[nSize * yvar + j] ^ c)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
inline size OneCount(lit x) const {
|
||||
bvar a = Lit2Bvar(x);
|
||||
size count = 0;
|
||||
if(nVars > 6) {
|
||||
for(size j = 0; j < nSize; j++)
|
||||
count += bsw(vVals[nSize * a + j]).count();
|
||||
} else
|
||||
count = bsw(vVals[nSize * a] & ones(nVars)).count();
|
||||
return LitIsCompl(x)? ((size)1 << nVars) - count: count;
|
||||
}
|
||||
|
||||
public:
|
||||
inline void IncRef(lit x) { if(!vRefs.empty() && Ref(x) != RefMax()) vRefs[Lit2Bvar(x)]++; }
|
||||
inline void DecRef(lit x) { if(!vRefs.empty() && Ref(x) != RefMax()) vRefs[Lit2Bvar(x)]--; }
|
||||
|
||||
public:
|
||||
bool Resize() {
|
||||
if(nObjsAlloc == nObjsMax)
|
||||
return false;
|
||||
lit nObjsAllocLit = (lit)nObjsAlloc << 1;
|
||||
if(nObjsAllocLit > (lit)BvarMax())
|
||||
nObjsAlloc = BvarMax();
|
||||
else
|
||||
nObjsAlloc = (bvar)nObjsAllocLit;
|
||||
nTotalSize = nTotalSize << 1;
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Reallocating " << nObjsAlloc << " nodes" << std::endl;
|
||||
vVals.resize(nTotalSize);
|
||||
if(!vRefs.empty())
|
||||
vRefs.resize(nObjsAlloc);
|
||||
return true;
|
||||
}
|
||||
bool Gbc() {
|
||||
if(nVerbose >= 2)
|
||||
std::cout << "Garbage collect" << std::endl;
|
||||
for(bvar a = nVars + 1; a < nObjs; a++)
|
||||
if(!vRefs[a])
|
||||
vDeads.push_back(a);
|
||||
return vDeads.size();
|
||||
}
|
||||
|
||||
public:
|
||||
Man(int nVars, Param p): nVars(nVars) {
|
||||
if(p.nObjsMaxLog < p.nObjsAllocLog)
|
||||
fatal_error("nObjsMax must not be smaller than nObjsAlloc");
|
||||
if(nVars >= lww())
|
||||
nSize = 1ull << (nVars - lww());
|
||||
else
|
||||
nSize = 1;
|
||||
if(!nSize)
|
||||
fatal_error("Memout (nVars) in init");
|
||||
if(!(nSize << p.nObjsMaxLog))
|
||||
fatal_error("Memout (nObjsMax) in init");
|
||||
lit nObjsMaxLit = (lit)1 << p.nObjsMaxLog;
|
||||
if(!nObjsMaxLit)
|
||||
fatal_error("Memout (nObjsMax) in init");
|
||||
if(nObjsMaxLit > (lit)BvarMax())
|
||||
nObjsMax = BvarMax();
|
||||
else
|
||||
nObjsMax = (bvar)nObjsMaxLit;
|
||||
lit nObjsAllocLit = (lit)1 << p.nObjsAllocLog;
|
||||
if(!nObjsAllocLit)
|
||||
fatal_error("Memout (nObjsAlloc) in init");
|
||||
if(nObjsAllocLit > (lit)BvarMax())
|
||||
nObjsAlloc = BvarMax();
|
||||
else
|
||||
nObjsAlloc = (bvar)nObjsAllocLit;
|
||||
if(nObjsAlloc <= (bvar)nVars)
|
||||
fatal_error("nObjsAlloc must be larger than nVars");
|
||||
nTotalSize = nSize << p.nObjsAllocLog;
|
||||
vVals.resize(nTotalSize);
|
||||
if(p.fCountOnes && nVars > 63)
|
||||
fatal_error("nVars must be less than 64 to count ones");
|
||||
nObjs = 1;
|
||||
for(int i = 0; i < 6 && i < nVars; i++) {
|
||||
for(size j = 0; j < nSize; j++)
|
||||
vVals[nSize * nObjs + j] = vars(i);
|
||||
nObjs++;
|
||||
}
|
||||
for(int i = 0; i < nVars - 6; i++) {
|
||||
for(size j = 0; j < nSize; j += (2ull << i))
|
||||
for(size k = 0; k < (1ull << i); k++)
|
||||
vVals[nSize * nObjs + j + k] = one();
|
||||
nObjs++;
|
||||
}
|
||||
nVerbose = p.nVerbose;
|
||||
nGbc = p.nGbc;
|
||||
if(nGbc || p.nReo != BvarMax())
|
||||
vRefs.resize(nObjsAlloc);
|
||||
}
|
||||
inline lit And(lit x, lit y) {
|
||||
bvar xvar = Lit2Bvar(x);
|
||||
bvar yvar = Lit2Bvar(y);
|
||||
word xcompl = LitIsCompl(x)? one(): 0;
|
||||
word ycompl = LitIsCompl(y)? one(): 0;
|
||||
unsigned j;
|
||||
if(nObjs >= nObjsAlloc && vDeads.empty()) {
|
||||
bool fRemoved = false;
|
||||
if(nGbc > 1)
|
||||
fRemoved = Gbc();
|
||||
if(!Resize() && !fRemoved && (nGbc != 1 || !Gbc()))
|
||||
fatal_error("Memout (node)");
|
||||
}
|
||||
bvar zvar;
|
||||
if(nObjs < nObjsAlloc)
|
||||
zvar = nObjs++;
|
||||
else
|
||||
zvar = vDeads.back(), vDeads.resize(vDeads.size() - 1);
|
||||
for(j = 0; j < nSize; j++)
|
||||
vVals[nSize * zvar + j] = (vVals[nSize * xvar + j] ^ xcompl) & (vVals[nSize * yvar + j] ^ ycompl);
|
||||
return zvar << 1;
|
||||
}
|
||||
inline lit Or(lit x, lit y) {
|
||||
return LitNot(And(LitNot(x), LitNot(y)));
|
||||
}
|
||||
void Reorder() {} // dummy
|
||||
|
||||
public:
|
||||
void SetRef(std::vector<lit> const &vLits) {
|
||||
vRefs.clear();
|
||||
vRefs.resize(nObjsAlloc);
|
||||
for(size_t i = 0; i < vLits.size(); i++)
|
||||
IncRef(vLits[i]);
|
||||
}
|
||||
void RemoveRefIfUnused() {
|
||||
if(!nGbc)
|
||||
vRefs.clear();
|
||||
}
|
||||
void TurnOffReo() {}
|
||||
int GetNumVars() const {
|
||||
return nVars;
|
||||
}
|
||||
void PrintNode(lit x) const {
|
||||
bvar a = Lit2Bvar(x);
|
||||
word c = LitIsCompl(x)? one(): 0;
|
||||
for(size j = 0; j < nSize; j++)
|
||||
std::cout << bsw(vVals[nSize * a + j] ^ c);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#endif
|
||||
|
|
@ -30,6 +30,12 @@
|
|||
#include "opt/dau/dau.h"
|
||||
#include "misc/util/utilNam.h"
|
||||
#include "map/scl/sclCon.h"
|
||||
#include "misc/tim/tim.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
# define __builtin_popcount __popcnt
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -82,6 +88,7 @@ struct Nf_Man_t_
|
|||
{
|
||||
// user data
|
||||
Gia_Man_t * pGia; // derived manager
|
||||
Tim_Man_t * pManTim; // timing manager
|
||||
Jf_Par_t * pPars; // parameters
|
||||
// matching
|
||||
Vec_Mem_t * vTtMem; // truth tables
|
||||
|
|
@ -223,7 +230,7 @@ void Nf_StoCreateGateAdd( Vec_Mem_t * vTtMem, Vec_Wec_t * vTt2Match, Mio_Cell2_t
|
|||
if ( fPinQuick ) // reduce the number of matches agressively
|
||||
{
|
||||
Vec_IntForEachEntryDouble( vArray, GateId, Entry, i )
|
||||
if ( GateId == (int)pCell->Id && Abc_TtBitCount8[Nf_Int2Cfg(Entry).Phase] == Abc_TtBitCount8[Mat.Phase] )
|
||||
if ( GateId == (int)pCell->Id && __builtin_popcount( Nf_Int2Cfg(Entry).Phase & 0xff ) == __builtin_popcount( Mat.Phase & 0xff ) )
|
||||
return;
|
||||
}
|
||||
else // reduce the number of matches less agressively
|
||||
|
|
@ -379,6 +386,7 @@ Nf_Man_t * Nf_StoCreate( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
p = ABC_CALLOC( Nf_Man_t, 1 );
|
||||
p->clkStart = Abc_Clock();
|
||||
p->pGia = pGia;
|
||||
p->pManTim = (Tim_Man_t *)pGia->pManTime;
|
||||
p->pPars = pPars;
|
||||
p->pNfObjs = ABC_CALLOC( Nf_Obj_t, Gia_ManObjNum(pGia) );
|
||||
p->iCur = 2;
|
||||
|
|
@ -956,21 +964,42 @@ void Nf_ObjMergeOrder( Nf_Man_t * p, int iObj )
|
|||
}
|
||||
void Nf_ManComputeCuts( Nf_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, iFanin;
|
||||
Gia_ManForEachAnd( p->pGia, pObj, i )
|
||||
Gia_Obj_t * pObj; int i, iFanin, arrTime;
|
||||
float CutFlow = 0, CutFlowAve = 0; int fFirstCi = 0, nCutFlow = 0;
|
||||
if ( p->pManTim )
|
||||
Tim_ManIncrementTravId( p->pManTim );
|
||||
Gia_ManForEachObjWithBoxes( p->pGia, pObj, i )
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
{
|
||||
iFanin = Gia_ObjFaninId0(pObj, i);
|
||||
Nf_ObjSetCutFlow( p, i, Nf_ObjCutFlow(p, iFanin) );
|
||||
Nf_ObjSetCutDelay( p, i, Nf_ObjCutDelay(p, iFanin) );
|
||||
}
|
||||
else
|
||||
else if ( Gia_ObjIsAnd(pObj) )
|
||||
Nf_ObjMergeOrder( p, i );
|
||||
else if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
if ( fFirstCi ) {
|
||||
CutFlowAve = CutFlow / nCutFlow;
|
||||
CutFlow = 0;
|
||||
nCutFlow = 0;
|
||||
fFirstCi = 0;
|
||||
}
|
||||
arrTime = Tim_ManGetCiArrival( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
Nf_ObjSetCutFlow( p, i, CutFlowAve ); // approximation!
|
||||
Nf_ObjSetCutDelay( p, i, arrTime );
|
||||
}
|
||||
else if ( Gia_ObjIsCo(pObj) )
|
||||
{
|
||||
iFanin = Gia_ObjFaninId0(pObj, i);
|
||||
CutFlow += Nf_ObjCutFlow(p, iFanin);
|
||||
arrTime = Nf_ObjCutDelay(p, iFanin);
|
||||
Tim_ManSetCoArrival( p->pManTim, Gia_ObjCioId(pObj), arrTime );
|
||||
nCutFlow++;
|
||||
fFirstCi = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -1143,7 +1172,10 @@ void Nf_ManCutMatchOne( Nf_Man_t * p, int iObj, int * pCut, int * pCutSet )
|
|||
if ( ArrivalA + pC->iDelays[k] <= Required && Required != SCL_INFINITY )
|
||||
{
|
||||
Delay = Abc_MaxInt( Delay, ArrivalA + pC->iDelays[k] );
|
||||
AreaF += pBestF[iFanin]->M[fComplF][1].F;
|
||||
if ( AreaF >= (float)1e32 || pBestF[iFanin]->M[fComplF][1].F >= (float)1e32 )
|
||||
AreaF = (float)1e32;
|
||||
else
|
||||
AreaF += pBestF[iFanin]->M[fComplF][1].F;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1382,14 +1414,36 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj )
|
|||
}
|
||||
*/
|
||||
}
|
||||
static inline Nf_Mat_t * Nf_ObjMatchBest( Nf_Man_t * p, int i, int c )
|
||||
{
|
||||
Nf_Mat_t * pD = Nf_ObjMatchD(p, i, c);
|
||||
Nf_Mat_t * pA = Nf_ObjMatchA(p, i, c);
|
||||
assert( pD->fBest != pA->fBest );
|
||||
//assert( Nf_ObjMapRefNum(p, i, c) > 0 );
|
||||
if ( pA->fBest )
|
||||
return pA;
|
||||
if ( pD->fBest )
|
||||
return pD;
|
||||
return NULL;
|
||||
}
|
||||
void Nf_ManComputeMapping( Nf_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Gia_ManForEachAnd( p->pGia, pObj, i )
|
||||
Gia_Obj_t * pObj; int i, arrTime;
|
||||
if ( p->pManTim )
|
||||
Tim_ManIncrementTravId( p->pManTim );
|
||||
Gia_ManForEachObjWithBoxes( p->pGia, pObj, i )
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
Nf_ObjPrepareBuf( p, pObj );
|
||||
else
|
||||
else if ( Gia_ObjIsAnd(pObj) )
|
||||
Nf_ManCutMatch( p, i );
|
||||
else if ( Gia_ObjIsCi(pObj) ) {
|
||||
arrTime = Tim_ManGetCiArrival( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
Nf_ObjPrepareCi( p, i, arrTime );
|
||||
}
|
||||
else if ( Gia_ObjIsCo(pObj) ) {
|
||||
arrTime = Nf_ObjMatchD( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj) )->D;
|
||||
Tim_ManSetCoArrival( p->pManTim, Gia_ObjCioId(pObj), arrTime );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1404,18 +1458,6 @@ void Nf_ManComputeMapping( Nf_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Nf_Mat_t * Nf_ObjMatchBest( Nf_Man_t * p, int i, int c )
|
||||
{
|
||||
Nf_Mat_t * pD = Nf_ObjMatchD(p, i, c);
|
||||
Nf_Mat_t * pA = Nf_ObjMatchA(p, i, c);
|
||||
assert( pD->fBest != pA->fBest );
|
||||
//assert( Nf_ObjMapRefNum(p, i, c) > 0 );
|
||||
if ( pA->fBest )
|
||||
return pA;
|
||||
if ( pD->fBest )
|
||||
return pD;
|
||||
return NULL;
|
||||
}
|
||||
void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
|
|
@ -1425,7 +1467,7 @@ void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
|
|||
Vec_IntFill( &p->vRequired, nLits, SCL_INFINITY );
|
||||
// compute delay
|
||||
p->pPars->MapDelay = 0;
|
||||
Gia_ManForEachCo( p->pGia, pObj, i )
|
||||
Gia_ManForEachCoWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
Required = Nf_ObjMatchD( p, Gia_ObjFaninId0p(p->pGia, pObj), Gia_ObjFaninC0(pObj) )->D;
|
||||
p->pPars->MapDelay = Abc_MaxInt( p->pPars->MapDelay, Required );
|
||||
|
|
@ -1445,7 +1487,9 @@ void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
|
|||
}
|
||||
//assert( p->pPars->MapDelayTarget == 0 );
|
||||
// set required times
|
||||
Gia_ManForEachCo( p->pGia, pObj, i )
|
||||
if ( p->pManTim )
|
||||
Tim_ManIncrementTravId( p->pManTim );
|
||||
Gia_ManForEachCoWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
iObj = Gia_ObjFaninId0p(p->pGia, pObj);
|
||||
fCompl = Gia_ObjFaninC0(pObj);
|
||||
|
|
@ -1470,6 +1514,13 @@ void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
|
|||
Nf_ObjUpdateRequired( p, iObj, fCompl, Required );
|
||||
if ( fPropCompl && iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
|
||||
Nf_ObjUpdateRequired( p, iObj, !fCompl, Required - p->InvDelayI );
|
||||
|
||||
if ( p->pManTim == NULL )
|
||||
continue;
|
||||
if ( fPropCompl && iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
|
||||
Tim_ManSetCoRequired( p->pManTim, Gia_ObjCioId(pObj), Required - p->InvDelayI );
|
||||
else
|
||||
Tim_ManSetCoRequired( p->pManTim, Gia_ObjCioId(pObj), Required );
|
||||
//Nf_ObjMapRefInc( p, Gia_ObjFaninId0p(p->pGia, pObj), Gia_ObjFaninC0(pObj));
|
||||
}
|
||||
}
|
||||
|
|
@ -1523,7 +1574,7 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
|
|||
float * pFlowRefs = Vec_FltArray( &p->vFlowRefs );
|
||||
int * pMapRefs = Vec_IntArray( &p->vMapRefs );
|
||||
int nLits = 2*Gia_ManObjNum(p->pGia);
|
||||
int i, c, Id, nRefs[2];
|
||||
int i, c, Id, nRefs[2], reqTime;
|
||||
Gia_Obj_t * pObj;
|
||||
Nf_Mat_t * pD, * pA, * pM;
|
||||
Nf_Mat_t * pDs[2], * pAs[2], * pMs[2];
|
||||
|
|
@ -1541,7 +1592,7 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
|
|||
p->nInvs = 0;
|
||||
p->pPars->MapAreaF = 0;
|
||||
p->pPars->Area = p->pPars->Edge = 0;
|
||||
Gia_ManForEachAndReverse( p->pGia, pObj, i )
|
||||
Gia_ManForEachObjReverseWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
{
|
||||
|
|
@ -1558,6 +1609,27 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
|
|||
Nf_ObjMapRefInc( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj));
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
if ( Nf_ObjMapRefNum(p, i, 1) )
|
||||
{
|
||||
Nf_ObjMapRefInc( p, i, 0 );
|
||||
Nf_ObjUpdateRequired( p, i, 0, Nf_ObjRequired(p, i, 1) - p->InvDelayI );
|
||||
p->pPars->MapAreaF += p->InvAreaF;
|
||||
p->pPars->Edge++;
|
||||
p->pPars->Area++;
|
||||
p->nInvs++;
|
||||
}
|
||||
Tim_ManSetCiRequired( p->pManTim, Gia_ObjCioId(pObj), Nf_ObjRequired(p, i, 0) );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
{
|
||||
reqTime = Tim_ManGetCoRequired( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
Nf_ObjUpdateRequired( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj), reqTime );
|
||||
Nf_ObjMapRefInc( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj));
|
||||
continue;
|
||||
}
|
||||
// skip if this node is not used
|
||||
for ( c = 0; c < 2; c++ )
|
||||
nRefs[c] = Nf_ObjMapRefNum(p, i, c);
|
||||
|
|
@ -1660,7 +1732,7 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
|
|||
// - required times are propagated correctly
|
||||
// - references are set correctly
|
||||
}
|
||||
Gia_ManForEachCiId( p->pGia, Id, i )
|
||||
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
|
||||
if ( Nf_ObjMapRefNum(p, Id, 1) )
|
||||
{
|
||||
Nf_ObjMapRefInc( p, Id, 0 );
|
||||
|
|
@ -1860,7 +1932,9 @@ void Nf_ManResetMatches( Nf_Man_t * p, int Round )
|
|||
Nf_Mat_t * pDc, * pAc, * pMfan, * pM[2];
|
||||
int i, c, Arrival;
|
||||
// go through matches in the topo order
|
||||
Gia_ManForEachAnd( p->pGia, pObj, i )
|
||||
if ( p->pManTim )
|
||||
Tim_ManIncrementTravId( p->pManTim );
|
||||
Gia_ManForEachObjWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
{
|
||||
|
|
@ -1877,6 +1951,18 @@ void Nf_ManResetMatches( Nf_Man_t * p, int Round )
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
Arrival = Tim_ManGetCiArrival( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
Nf_ObjPrepareCi( p, i, Arrival );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
{
|
||||
Arrival = Nf_ObjMatchD( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj) )->D;
|
||||
Tim_ManSetCoArrival( p->pManTim, Gia_ObjCioId(pObj), Arrival );
|
||||
continue;
|
||||
}
|
||||
// select the best match for each phase
|
||||
for ( c = 0; c < 2; c++ )
|
||||
{
|
||||
|
|
@ -1949,19 +2035,40 @@ void Nf_ManComputeMappingEla( Nf_Man_t * p )
|
|||
Mio_Cell2_t * pCell;
|
||||
Nf_Mat_t Mb, * pMb = &Mb, * pM;
|
||||
word AreaBef, AreaAft, Gain = 0;
|
||||
int i, c, iVar, Id, fCompl, k, * pCut;
|
||||
int Required;
|
||||
Nf_ManSetOutputRequireds( p, 1 );
|
||||
int i, c, iVar, Id, fCompl, k, * pCut, Required;
|
||||
Nf_ManResetMatches( p, p->Iter - p->pPars->nRounds );
|
||||
Gia_ManForEachAndReverse( p->pGia, pObj, i )
|
||||
Nf_ManSetOutputRequireds( p, 1 );
|
||||
Gia_ManForEachObjReverseWithBoxes( p->pGia, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjIsBuf(pObj) )
|
||||
{
|
||||
if ( Nf_ObjMapRefNum(p, i, 1) )
|
||||
Nf_ObjUpdateRequired( p, i, 0, Nf_ObjRequired(p, i, 1) - p->InvDelayI );
|
||||
Nf_ObjUpdateRequired( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj), Nf_ObjRequired(p, i, 0) );
|
||||
int reqTime = Nf_ObjRequired(p, i, 0);
|
||||
int iObj = Gia_ObjFaninId0p(p->pGia, pObj);
|
||||
int fCompl = Gia_ObjFaninC0(pObj);
|
||||
Nf_ObjUpdateRequired( p, iObj, fCompl, reqTime );
|
||||
if ( iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
|
||||
Nf_ObjUpdateRequired( p, iObj, !fCompl, reqTime - p->InvDelayI );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
if ( Nf_ObjMapRefNum(p, i, 1) )
|
||||
Nf_ObjUpdateRequired( p, i, 0, Nf_ObjRequired(p, i, 1) - p->InvDelayI );
|
||||
Tim_ManSetCiRequired( p->pManTim, Gia_ObjCioId(pObj), Nf_ObjRequired(p, i, 0) );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
{
|
||||
int reqTime = Tim_ManGetCoRequired( p->pManTim, Gia_ObjCioId(pObj) );
|
||||
int iObj = Gia_ObjFaninId0p(p->pGia, pObj);
|
||||
int fCompl = Gia_ObjFaninC0(pObj);
|
||||
Nf_ObjUpdateRequired( p, iObj, fCompl, reqTime );
|
||||
if ( iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
|
||||
Nf_ObjUpdateRequired( p, iObj, !fCompl, reqTime - p->InvDelayI );
|
||||
continue;
|
||||
}
|
||||
for ( c = 0; c < 2; c++ )
|
||||
if ( Nf_ObjMapRefNum(p, i, c) )
|
||||
{
|
||||
|
|
@ -2012,7 +2119,7 @@ void Nf_ManComputeMappingEla( Nf_Man_t * p )
|
|||
}
|
||||
}
|
||||
}
|
||||
Gia_ManForEachCiId( p->pGia, Id, i )
|
||||
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
|
||||
if ( Nf_ObjMapRefNum(p, Id, 1) )
|
||||
{
|
||||
Required = Nf_ObjRequired( p, i, 1 );
|
||||
|
|
@ -2054,6 +2161,240 @@ void Nf_ManFixPoDrivers( Nf_Man_t * p )
|
|||
//printf( "Fixed %d PO drivers.\n", Count );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Dump matches.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Nf_ManDumpMatches( Nf_Man_t * p )
|
||||
{
|
||||
FILE * pFile = fopen( p->pPars->ZFile, "wb" );
|
||||
Gia_Obj_t * pObj; int n, iObj;
|
||||
// output matches
|
||||
Gia_ManForEachCi( p->pGia, pObj, n )
|
||||
fprintf( pFile, "%d input %.2f\n", Abc_Var2Lit(Gia_ObjId(p->pGia, pObj), 0), 0.0 );
|
||||
Gia_ManForEachAnd( p->pGia, pObj, iObj ) {
|
||||
assert( !Gia_ObjIsBuf(pObj) );
|
||||
for ( n = 0; n < 2; n++ ) {
|
||||
int c, * pCut, * pCutSet = Nf_ObjCutSet( p, iObj );
|
||||
Nf_SetForEachCut( pCutSet, pCut, c ) {
|
||||
if ( Abc_Lit2Var(Nf_CutFunc(pCut)) >= Vec_WecSize(p->vTt2Match) )
|
||||
continue;
|
||||
assert( !Nf_CutIsTriv(pCut, iObj) );
|
||||
assert( Nf_CutSize(pCut) <= p->pPars->nLutSize );
|
||||
assert( Abc_Lit2Var(Nf_CutFunc(pCut)) < Vec_WecSize(p->vTt2Match) );
|
||||
int iFuncLit = Nf_CutFunc(pCut);
|
||||
int fComplExt = Abc_LitIsCompl(iFuncLit);
|
||||
Vec_Int_t * v = Vec_WecEntry( p->vTt2Match, Abc_Lit2Var(iFuncLit) );
|
||||
int j, k, Info, Offset, iFanin, fComplF;
|
||||
Vec_IntForEachEntryDouble( v, Info, Offset, j ) {
|
||||
Nf_Cfg_t Cfg = Nf_Int2Cfg(Offset);
|
||||
int fCompl = Cfg.fCompl ^ fComplExt;
|
||||
if ( fCompl != n )
|
||||
continue;
|
||||
Mio_Cell2_t*pC = Nf_ManCell( p, Info );
|
||||
assert( Nf_CutSize(pCut) == (int)pC->nFanins );
|
||||
fprintf( pFile, "%d ", Abc_Var2Lit(iObj, n) );
|
||||
fprintf( pFile, "%s ", pC->pName );
|
||||
fprintf( pFile, "%.2f", pC->AreaF );
|
||||
Nf_CutForEachVarCompl( pCut, Cfg, iFanin, fComplF, k )
|
||||
fprintf( pFile, " %d", Abc_Var2Lit(iFanin, fComplF) );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Gia_ManForEachCo( p->pGia, pObj, n )
|
||||
fprintf( pFile, "%d output %.2f %d\n", Abc_Var2Lit(Gia_ObjId(p->pGia, pObj), 0), 0.0, Gia_ObjFaninLit0p(p->pGia, pObj) );
|
||||
// output levels
|
||||
extern int Gia_ManChoiceLevel( Gia_Man_t * p );
|
||||
int LevelMax = Gia_ManChoiceLevel( p->pGia );
|
||||
Gia_ManForEachCiId( p->pGia, iObj, n )
|
||||
fprintf( pFile, "L%d %d\n", Abc_Var2Lit(iObj, 0), 0 );
|
||||
Gia_ManForEachAnd( p->pGia, pObj, iObj )
|
||||
fprintf( pFile, "L%d %d\n", Abc_Var2Lit(iObj, 0), Gia_ObjLevelId(p->pGia, iObj) );
|
||||
Gia_ManForEachCoId( p->pGia, iObj, n )
|
||||
fprintf( pFile, "L%d %d\n", Abc_Var2Lit(iObj, 0), LevelMax+1 );
|
||||
// output mapping
|
||||
Gia_ManForEachCiId( p->pGia, iObj, n )
|
||||
if ( Nf_ObjMapRefNum(p, iObj, 1) )
|
||||
fprintf( pFile, "M%d %s %.2f %d\n", Abc_Var2Lit(iObj, 1), p->pCells[3].pName, p->pCells[3].AreaF, Abc_Var2Lit(iObj, 0) );
|
||||
Gia_ManForEachAnd( p->pGia, pObj, iObj )
|
||||
for ( n = 0; n < 2; n++ )
|
||||
if ( Nf_ObjMapRefNum(p, iObj, n) ) {
|
||||
Nf_Mat_t * pM = Nf_ObjMatchBest(p, iObj, n);
|
||||
if ( pM->fCompl ) {
|
||||
fprintf( pFile, "M%d %s %.2f %d\n", Abc_Var2Lit(iObj, n), p->pCells[3].pName, p->pCells[3].AreaF, Abc_Var2Lit(iObj, !n) );
|
||||
continue;
|
||||
}
|
||||
int k, iVar, fCompl, * pCut = Nf_CutFromHandle( Nf_ObjCutSet(p, iObj), pM->CutH );
|
||||
Mio_Cell2_t*pC = Nf_ManCell( p, pM->Gate );
|
||||
fprintf( pFile, "M%d ", Abc_Var2Lit(iObj, n) );
|
||||
fprintf( pFile, "%s ", pC->pName );
|
||||
fprintf( pFile, "%.2f", pC->AreaF );
|
||||
Nf_CutForEachVarCompl( pCut, pM->Cfg, iVar, fCompl, k )
|
||||
fprintf( pFile, " %d", Abc_Var2Lit(iVar, fCompl) );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
fclose( pFile );
|
||||
}
|
||||
void Nf_ManDumpMatchesPrint( Gia_Man_t * pGia, Vec_Int_t * vStore, int nCutSize, int nMaxMatches )
|
||||
{
|
||||
int iObj, n, f, m;
|
||||
int nObjs = Gia_ManObjNum( pGia );
|
||||
int * pData;
|
||||
if ( vStore == NULL || nCutSize == 0 || nMaxMatches == 0 )
|
||||
return;
|
||||
pData = Vec_IntArray( vStore );
|
||||
for ( iObj = 0; iObj < nObjs; iObj++ )
|
||||
{
|
||||
Gia_Obj_t * pObj = Gia_ManObj( pGia, iObj );
|
||||
int fPrint = 0;
|
||||
if ( Gia_ObjIsAnd(pObj) && !Gia_ObjIsBuf(pObj) )
|
||||
fPrint = 1;
|
||||
else if ( Gia_ObjIsCo(pObj) )
|
||||
fPrint = 1;
|
||||
if ( !fPrint )
|
||||
continue;
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
int * pNodeStore = pData + (2 * iObj + n) * nCutSize * nMaxMatches;
|
||||
printf( "Node %d (%s) polarity %d has %d matches:\n", iObj, Gia_ObjIsCo(pObj) ? "CO" : "AND", n, nMaxMatches );
|
||||
for ( f = 0; f < nCutSize; f++ )
|
||||
{
|
||||
printf( " Input %d:", f );
|
||||
for ( m = 0; m < nMaxMatches; m++ )
|
||||
printf( " %4d", pNodeStore[f * nMaxMatches + m] );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void Nf_ManDumpMatchesBin( Nf_Man_t * p, int nMaxMatches )
|
||||
{
|
||||
const char * pNameNA = "n/a";
|
||||
Gia_Obj_t * pObj;
|
||||
Vec_Int_t * vStore;
|
||||
int * pData;
|
||||
int iObj, n, nMatches = 0;
|
||||
int nCutSize = p->pPars->nLutSize;
|
||||
int nObjs = Gia_ManObjNum(p->pGia);
|
||||
char * pFileNameBin = NULL, * pFileNameGates = NULL;
|
||||
FILE * pFileBin = NULL, * pFileGates = NULL;
|
||||
if ( nMaxMatches <= 0 )
|
||||
return;
|
||||
if ( p->pPars->ZFile == NULL )
|
||||
return;
|
||||
assert( nCutSize > 0 && nCutSize <= NF_LEAF_MAX );
|
||||
vStore = Vec_IntStart( 2 * nObjs * nCutSize * nMaxMatches );
|
||||
pData = Vec_IntArray( vStore );
|
||||
pFileNameBin = Abc_UtilStrsav( Extra_FileNameGenericAppend( p->pPars->ZFile, ".bin" ) );
|
||||
pFileNameGates = Abc_UtilStrsav( Extra_FileNameGenericAppend( p->pPars->ZFile, ".gates" ) );
|
||||
pFileBin = fopen( pFileNameBin, "wb" );
|
||||
pFileGates = fopen( pFileNameGates, "wb" );
|
||||
if ( pFileBin == NULL || pFileGates == NULL ) {
|
||||
printf( "Cannot open match dump files \"%s\" and \"%s\".\n", pFileNameBin, pFileNameGates );
|
||||
if ( pFileBin ) fclose( pFileBin );
|
||||
if ( pFileGates ) fclose( pFileGates );
|
||||
ABC_FREE( pFileNameBin );
|
||||
ABC_FREE( pFileNameGates );
|
||||
Vec_IntFree( vStore );
|
||||
return;
|
||||
}
|
||||
for ( iObj = 0; iObj < nObjs; iObj++ ) {
|
||||
pObj = Gia_ManObj( p->pGia, iObj );
|
||||
assert( !Gia_ObjIsBuf(pObj) );
|
||||
for ( n = 0; n < 2; n++ ) {
|
||||
int Slot = 0;
|
||||
int k;
|
||||
int LitBuffer[NF_LEAF_MAX];
|
||||
int * pNodeStore = pData + (2 * iObj + n) * nCutSize * nMaxMatches;
|
||||
memset( pNodeStore, 0, sizeof(int) * nCutSize * nMaxMatches );
|
||||
if ( Gia_ObjIsCo(pObj) && n == 0 && Slot < nMaxMatches ) {
|
||||
pNodeStore[Slot] = Gia_ObjFaninLit0p( p->pGia, pObj );
|
||||
fprintf( pFileGates, "%s %.2f\n", pNameNA, 0.0 );
|
||||
Slot++;
|
||||
nMatches++;
|
||||
}
|
||||
if ( Gia_ObjIsAnd(pObj) ) {
|
||||
int c, * pCut, * pCutSet = Nf_ObjCutSet( p, iObj );
|
||||
Nf_SetForEachCut( pCutSet, pCut, c )
|
||||
{
|
||||
int iFuncLit, fComplExt;
|
||||
Vec_Int_t * vVec;
|
||||
int j, Info, Offset;
|
||||
if ( Slot == nMaxMatches )
|
||||
break;
|
||||
if ( Abc_Lit2Var(Nf_CutFunc(pCut)) >= Vec_WecSize(p->vTt2Match) )
|
||||
continue;
|
||||
if ( Nf_CutIsTriv(pCut, iObj) )
|
||||
continue;
|
||||
assert( Nf_CutSize(pCut) <= nCutSize );
|
||||
iFuncLit = Nf_CutFunc(pCut);
|
||||
fComplExt = Abc_LitIsCompl(iFuncLit);
|
||||
vVec = Vec_WecEntry( p->vTt2Match, Abc_Lit2Var(iFuncLit) );
|
||||
Vec_IntForEachEntryDouble( vVec, Info, Offset, j )
|
||||
{
|
||||
Nf_Cfg_t Cfg = Nf_Int2Cfg( Offset );
|
||||
int fCompl = Cfg.fCompl ^ fComplExt;
|
||||
Mio_Cell2_t * pCell = NULL;
|
||||
const char * pGateName;
|
||||
float Area = 0.0;
|
||||
int iFanin, fComplF, nLitCount = 0;
|
||||
if ( fCompl != n )
|
||||
continue;
|
||||
if ( Slot == nMaxMatches )
|
||||
break;
|
||||
if ( Info >= 0 )
|
||||
pCell = Nf_ManCell( p, Info );
|
||||
pGateName = (pCell && pCell->pName) ? pCell->pName : pNameNA;
|
||||
Area = pCell ? pCell->AreaF : 0.0f;
|
||||
Nf_CutForEachVarCompl( pCut, Cfg, iFanin, fComplF, k )
|
||||
LitBuffer[nLitCount++] = Abc_Var2Lit( iFanin, fComplF );
|
||||
for ( k = 0; k < nCutSize; k++ )
|
||||
pNodeStore[k * nMaxMatches + Slot] = 0;
|
||||
for ( k = 0; k < nLitCount; k++ )
|
||||
pNodeStore[k * nMaxMatches + Slot] = LitBuffer[k];
|
||||
fprintf( pFileGates, "%s %.2f\n", pGateName, Area );
|
||||
Slot++;
|
||||
nMatches++;
|
||||
}
|
||||
}
|
||||
}
|
||||
while ( Slot < nMaxMatches ) {
|
||||
fprintf( pFileGates, "%s %.2f\n", pNameNA, 0.0 );
|
||||
Slot++;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
int Num = 3;
|
||||
fwrite( &Num, 4, 1, pFileBin );
|
||||
Num = 2 * nObjs;
|
||||
fwrite( &Num, 4, 1, pFileBin );
|
||||
Num = nCutSize;
|
||||
fwrite( &Num, 4, 1, pFileBin );
|
||||
Num = nMaxMatches;
|
||||
fwrite( &Num, 4, 1, pFileBin );
|
||||
}
|
||||
fwrite( pData, 4, Vec_IntSize(vStore), pFileBin );
|
||||
if ( p->pPars->fVerbose )
|
||||
printf( "Dumped %d matches (limit %d) into binary file \"%s\" (%.2f MB).\n",
|
||||
nMatches, nMaxMatches, pFileNameBin, Vec_IntMemory(vStore)/(1<<20) );
|
||||
fclose( pFileBin );
|
||||
fclose( pFileGates );
|
||||
//Nf_ManDumpMatchesPrint( p->pGia, vStore, nCutSize, nMaxMatches );
|
||||
Vec_IntFree( vStore );
|
||||
ABC_FREE( pFileNameBin );
|
||||
ABC_FREE( pFileNameGates );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deriving mapping.]
|
||||
|
|
@ -2109,6 +2450,12 @@ Gia_Man_t * Nf_ManDeriveMapping( Nf_Man_t * p )
|
|||
}
|
||||
// assert( Vec_IntCap(vMapping) == 16 || Vec_IntSize(vMapping) == Vec_IntCap(vMapping) );
|
||||
p->pGia->vCellMapping = vMapping;
|
||||
if ( p->pPars->ZFile ) {
|
||||
if ( p->pPars->nMaxMatches )
|
||||
Nf_ManDumpMatchesBin( p, p->pPars->nMaxMatches );
|
||||
else
|
||||
Nf_ManDumpMatches( p );
|
||||
}
|
||||
return p->pGia;
|
||||
}
|
||||
void Nf_ManUpdateStats( Nf_Man_t * p )
|
||||
|
|
@ -2360,16 +2707,21 @@ void Nf_ManSetDefaultPars( Jf_Par_t * pPars )
|
|||
pPars->nCutNumMax = NF_CUT_MAX;
|
||||
pPars->MapDelayTarget = 0;
|
||||
}
|
||||
Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
||||
Gia_Man_t * Nf_ManPerformMappingInt( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
||||
{
|
||||
Gia_Man_t * pNew = NULL, * pCls;
|
||||
Nf_Man_t * p; int i, Id;
|
||||
if ( Gia_ManHasChoices(pGia) )
|
||||
pPars->fCoarsen = 0;
|
||||
if ( Gia_ManHasChoices(pGia) || pGia->pManTime )
|
||||
pPars->fCoarsen = 0;
|
||||
pCls = pPars->fCoarsen ? Gia_ManDupMuxes(pGia, pPars->nCoarseLimit) : pGia;
|
||||
p = Nf_StoCreate( pCls, pPars );
|
||||
if ( p == NULL )
|
||||
return NULL;
|
||||
// if ( p->pManTim ) Tim_ManPrint( p->pManTim );
|
||||
p->pGia->iFirstNonPiId = p->pManTim ? Tim_ManPiNum(p->pManTim) : Gia_ManCiNum(p->pGia);
|
||||
p->pGia->iFirstPoId = p->pManTim ? Gia_ManCoNum(p->pGia) - Tim_ManPoNum(p->pManTim) : 0;
|
||||
p->pGia->iFirstAndObj = 1 + p->pGia->iFirstNonPiId;
|
||||
p->pGia->iFirstPoObj = Gia_ManObjNum(p->pGia) - Gia_ManCoNum(p->pGia) + p->pGia->iFirstPoId;
|
||||
// if ( pPars->fVeryVerbose )
|
||||
// Nf_StoPrint( p, pPars->fVeryVerbose );
|
||||
if ( pPars->fVerbose && pPars->fCoarsen )
|
||||
|
|
@ -2382,12 +2734,12 @@ Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
Nf_ManPrintQuit( p );
|
||||
if ( Scl_ConIsRunning() )
|
||||
{
|
||||
Gia_ManForEachCiId( p->pGia, Id, i )
|
||||
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
|
||||
Nf_ObjPrepareCi( p, Id, Scl_ConGetInArr(i) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Gia_ManForEachCiId( p->pGia, Id, i )
|
||||
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
|
||||
// Nf_ObjPrepareCi( p, Id, Scl_Flt2Int(p->pGia->vInArrs ? Abc_MaxFloat(0.0, Vec_FltEntry(p->pGia->vInArrs, i)) : 0.0) );
|
||||
Nf_ObjPrepareCi( p, Id, Scl_Flt2Int(p->pGia->vInArrs ? Vec_FltEntry(p->pGia->vInArrs, i) : 0.0) );
|
||||
}
|
||||
|
|
@ -2418,10 +2770,162 @@ Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManCellMappingVerify_rec( Gia_Man_t * p, int iLit )
|
||||
{
|
||||
int iFanLit, k, Result = 1;
|
||||
if ( Abc_LitIsCompl(iLit) && Gia_ObjIsTravIdCurrentId(p, Abc_Lit2Var(iLit)) )
|
||||
return 1;
|
||||
if ( !Abc_LitIsCompl(iLit) && Gia_ObjIsTravIdPreviousId(p, Abc_Lit2Var(iLit)) )
|
||||
return 1;
|
||||
if ( Abc_LitIsCompl(iLit) )
|
||||
Gia_ObjSetTravIdCurrentId(p, Abc_Lit2Var(iLit));
|
||||
else
|
||||
Gia_ObjSetTravIdPreviousId(p, Abc_Lit2Var(iLit));
|
||||
if ( !Gia_ObjIsAndNotBuf(Gia_ManObj(p, Abc_Lit2Var(iLit))) )
|
||||
return 1;
|
||||
if ( !Gia_ObjIsCell(p, iLit) )
|
||||
{
|
||||
Abc_Print( -1, "Gia_ManCellMappingVerify: Internal literal %d does not have mapping.\n", iLit );
|
||||
return 0;
|
||||
}
|
||||
if ( Gia_ObjIsCellBuf(p, iLit) )
|
||||
return Gia_ManCellMappingVerify_rec( p, Gia_ObjFaninLit0p(p, Gia_ManObj(p, Abc_Lit2Var(iLit))) );
|
||||
if ( Gia_ObjIsCellInv(p, iLit) )
|
||||
return Gia_ManCellMappingVerify_rec( p, Abc_LitNot(iLit) );
|
||||
Gia_CellForEachFanin( p, iLit, iFanLit, k )
|
||||
if ( Result )
|
||||
Result &= Gia_ManCellMappingVerify_rec( p, iFanLit );
|
||||
return Result;
|
||||
}
|
||||
void Gia_ManCellMappingVerify( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int i, iLit, Result = 1;
|
||||
assert( Gia_ManHasCellMapping(p) );
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachBuf( p, pObj, i )
|
||||
{
|
||||
if ( !Gia_ObjIsAndNotBuf(Gia_ObjFanin0(pObj)) )
|
||||
continue;
|
||||
iLit = Gia_ObjFaninLit0p(p, pObj);
|
||||
if ( !Gia_ObjIsCell(p, iLit) )
|
||||
{
|
||||
Abc_Print( -1, "Gia_ManCellMappingVerify: Buffer driver %d does not have mapping.\n", Gia_ObjFaninId0p(p, pObj) );
|
||||
Result = 0;
|
||||
continue;
|
||||
}
|
||||
Result &= Gia_ManCellMappingVerify_rec( p, iLit );
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
if ( !Gia_ObjIsAndNotBuf(Gia_ObjFanin0(pObj)) )
|
||||
continue;
|
||||
iLit = Gia_ObjFaninLit0p(p, pObj);
|
||||
if ( !Gia_ObjIsCell(p, iLit) )
|
||||
{
|
||||
Abc_Print( -1, "Gia_ManCellMappingVerify: CO driver %d does not have mapping.\n", Gia_ObjFaninId0p(p, pObj) );
|
||||
Result = 0;
|
||||
continue;
|
||||
}
|
||||
Result &= Gia_ManCellMappingVerify_rec( p, iLit );
|
||||
}
|
||||
// if ( Result )
|
||||
// Abc_Print( 1, "Mapping verified correctly.\n" );
|
||||
}
|
||||
|
||||
void Gia_ManTransferCellMapping( Gia_Man_t * p, Gia_Man_t * pGia )
|
||||
{
|
||||
int iLit, iLitNew, k, iFanLit, iPlace;
|
||||
if ( !Gia_ManHasCellMapping(pGia) )
|
||||
return;
|
||||
Gia_ManCellMappingVerify( pGia );
|
||||
Vec_IntFreeP( &p->vCellMapping );
|
||||
p->vCellMapping = Vec_IntAlloc( 4 * Gia_ManObjNum(p) );
|
||||
Vec_IntFill( p->vCellMapping, 2 * Gia_ManObjNum(p), 0 );
|
||||
Gia_ManForEachCell( pGia, iLit )
|
||||
{
|
||||
Gia_Obj_t * pObj = Gia_ManObj(pGia, Abc_Lit2Var(iLit));
|
||||
if ( Gia_ObjValue(pObj) == ~0 ) // handle dangling LUT
|
||||
continue;
|
||||
assert( !Abc_LitIsCompl( Gia_ObjValue(pObj) ) );
|
||||
iLitNew = Abc_LitNotCond( Gia_ObjValue(pObj), Abc_LitIsCompl(iLit) );
|
||||
if ( Gia_ObjIsCellInv(pGia, iLit) ) {
|
||||
Vec_IntWriteEntry( p->vCellMapping, iLitNew, -1 );
|
||||
continue;
|
||||
}
|
||||
if ( Gia_ObjIsCellBuf(pGia, iLit) ) {
|
||||
Vec_IntWriteEntry( p->vCellMapping, iLitNew, -2 );
|
||||
continue;
|
||||
}
|
||||
Vec_IntWriteEntry( p->vCellMapping, iLitNew, Vec_IntSize(p->vCellMapping) );
|
||||
iPlace = Vec_IntSize( p->vCellMapping );
|
||||
Vec_IntPush( p->vCellMapping, Gia_ObjCellSize(pGia, iLit) );
|
||||
Gia_CellForEachFanin( pGia, iLit, iFanLit, k )
|
||||
{
|
||||
int iFanLitNew = Gia_ObjValue( Gia_ManObj(pGia, Abc_Lit2Var(iFanLit)) );
|
||||
if ( iFanLitNew == ~0 ) // handle dangling LUT fanin
|
||||
Vec_IntAddToEntry( p->vCellMapping, iPlace, -1 );
|
||||
else
|
||||
Vec_IntPush( p->vCellMapping, Abc_LitNotCond(iFanLitNew, Abc_LitIsCompl(iFanLit)) );
|
||||
}
|
||||
Vec_IntPush( p->vCellMapping, Gia_ObjCellId(pGia, iLit) );
|
||||
}
|
||||
Gia_ManCellMappingVerify( p );
|
||||
}
|
||||
Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * p, Jf_Par_t * pPars )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
if ( p->pManTime && Tim_ManBoxNum((Tim_Man_t*)p->pManTime) && Gia_ManIsNormalized(p) )
|
||||
{
|
||||
pNew = Gia_ManDupUnnormalize( p );
|
||||
if ( pNew == NULL )
|
||||
return NULL;
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
p = pNew;
|
||||
// mapping
|
||||
pNew = Nf_ManPerformMappingInt( p, pPars );
|
||||
if ( pNew != p )
|
||||
{
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
Gia_ManStop( p );
|
||||
}
|
||||
// normalize
|
||||
pNew = Gia_ManDupNormalize( p = pNew, 0 );
|
||||
Gia_ManTransferCellMapping( pNew, p );
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
Gia_ManStop( p );
|
||||
assert( Gia_ManIsNormalized(pNew) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pNew = Nf_ManPerformMappingInt( p, pPars );
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
//Gia_ManCellMappingVerify( pNew );
|
||||
// remove choices after mapping
|
||||
ABC_FREE( pNew->pReprs );
|
||||
ABC_FREE( pNew->pNexts );
|
||||
}
|
||||
//pNew->MappedDelay = (int)((If_Par_t *)pp)->FinalDelay;
|
||||
//pNew->MappedArea = (int)((If_Par_t *)pp)->FinalArea;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -184,13 +184,15 @@ static inline int Min_ManAppendCo( Min_Man_t * p, int iLit0 )
|
|||
***********************************************************************/
|
||||
void Min_ManFromGia_rec( Min_Man_t * pNew, Gia_Man_t * p, int iObj )
|
||||
{
|
||||
Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
|
||||
Gia_Obj_t * pObj = Gia_ManObj(p, iObj); int iLit0, iLit1;
|
||||
if ( ~pObj->Value )
|
||||
return;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj) );
|
||||
Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj) );
|
||||
pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
iLit0 = Gia_ObjFanin0Copy(pObj);
|
||||
iLit1 = Gia_ObjFanin1Copy(pObj);
|
||||
pObj->Value = Min_ManAppendObj( pNew, Abc_MinInt(iLit0, iLit1), Abc_MaxInt(iLit0, iLit1) );
|
||||
}
|
||||
Min_Man_t * Min_ManFromGia( Gia_Man_t * p, Vec_Int_t * vOuts )
|
||||
{
|
||||
|
|
@ -205,7 +207,7 @@ Min_Man_t * Min_ManFromGia( Gia_Man_t * p, Vec_Int_t * vOuts )
|
|||
Gia_ManForEachAnd( p, pObj, i )
|
||||
pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
pObj->Value = Min_ManAppendCo( pNew, Gia_ObjFaninLit0p(p, pObj) );
|
||||
pObj->Value = Min_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -346,7 +348,7 @@ void Min_LitMinimize( Min_Man_t * p, int iLit, Vec_Int_t * vLits )
|
|||
Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
|
||||
else if ( Val0 == 4 && Val1 != 4 )
|
||||
Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
|
||||
else if ( Val1 == 4 && Val1 != 4 )
|
||||
else if ( Val1 == 4 && Val0 != 4 )
|
||||
Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) );
|
||||
else if ( Abc_Random(0) & 1 )
|
||||
Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) );
|
||||
|
|
@ -403,8 +405,10 @@ static inline char Min_LitIsImplied2( Min_Man_t * p, int iLit )
|
|||
char Val1 = Min_LitValL(p, iLit1);
|
||||
assert( Min_LitIsNode(p, iLit) ); // internal node
|
||||
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
|
||||
Val0 = Min_LitIsImplied1(p, iLit0);
|
||||
Val1 = Min_LitValL(p, iLit1);
|
||||
}
|
||||
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
|
||||
Val1 = Min_LitIsImplied1(p, iLit1);
|
||||
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
|
||||
|
|
@ -427,8 +431,10 @@ static inline char Min_LitIsImplied3( Min_Man_t * p, int iLit )
|
|||
char Val1 = Min_LitValL(p, iLit1);
|
||||
assert( Min_LitIsNode(p, iLit) ); // internal node
|
||||
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
|
||||
Val0 = Min_LitIsImplied2(p, iLit0);
|
||||
Val1 = Min_LitValL(p, iLit1);
|
||||
}
|
||||
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
|
||||
Val1 = Min_LitIsImplied2(p, iLit1);
|
||||
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
|
||||
|
|
@ -451,8 +457,10 @@ static inline char Min_LitIsImplied4( Min_Man_t * p, int iLit )
|
|||
char Val1 = Min_LitValL(p, iLit1);
|
||||
assert( Min_LitIsNode(p, iLit) ); // internal node
|
||||
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
|
||||
Val0 = Min_LitIsImplied3(p, iLit0);
|
||||
Val1 = Min_LitValL(p, iLit1);
|
||||
}
|
||||
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
|
||||
Val1 = Min_LitIsImplied3(p, iLit1);
|
||||
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
|
||||
|
|
@ -475,8 +483,10 @@ static inline char Min_LitIsImplied5( Min_Man_t * p, int iLit )
|
|||
char Val1 = Min_LitValL(p, iLit1);
|
||||
assert( Min_LitIsNode(p, iLit) ); // internal node
|
||||
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
|
||||
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
|
||||
Val0 = Min_LitIsImplied4(p, iLit0);
|
||||
Val1 = Min_LitValL(p, iLit1);
|
||||
}
|
||||
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
|
||||
Val1 = Min_LitIsImplied4(p, iLit1);
|
||||
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
|
||||
|
|
@ -851,7 +861,7 @@ Gia_Man_t * Gia_ManDupCones2( Gia_Man_t * p, int * pOuts, int nOuts, Vec_Int_t *
|
|||
***********************************************************************/
|
||||
int Min_ManRemoveItem( Vec_Wec_t * vCexes, int iItem, int iFirst, int iLimit )
|
||||
{
|
||||
Vec_Int_t * vLevel, * vLevel0 = Vec_WecEntry(vCexes, iItem); int i;
|
||||
Vec_Int_t * vLevel = NULL, * vLevel0 = Vec_WecEntry(vCexes, iItem); int i;
|
||||
assert( iFirst <= iItem && iItem < iLimit );
|
||||
Vec_WecForEachLevelReverseStartStop( vCexes, vLevel, i, iLimit, iFirst )
|
||||
if ( Vec_IntSize(vLevel) > 0 )
|
||||
|
|
@ -890,6 +900,8 @@ int Min_ManCountSize( Vec_Wec_t * vCexes, int iFirst, int iLimit )
|
|||
}
|
||||
Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTries, int nMinCexes, Vec_Int_t * vStats[3], int fUseSim, int fUseSat, int fVerbose )
|
||||
{
|
||||
int fUseSynthesis = 1;
|
||||
abctime clkSim = Abc_Clock(), clkSat = Abc_Clock();
|
||||
Vec_Int_t * vOuts = vOuts0 ? vOuts0 : Vec_IntStartNatural( Gia_ManCoNum(p) );
|
||||
Min_Man_t * pNew = Min_ManFromGia( p, vOuts );
|
||||
Vec_Wec_t * vCexes = Vec_WecStart( Vec_IntSize(vOuts) * nMinCexes );
|
||||
|
|
@ -945,6 +957,7 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
|
|||
assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[0]) );
|
||||
assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[1]) );
|
||||
assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[2]) );
|
||||
clkSim = Abc_Clock() - clkSim;
|
||||
|
||||
if ( fUseSat )
|
||||
Gia_ManForEachCoVec( vOuts, p, pObj, i )
|
||||
|
|
@ -952,11 +965,19 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
|
|||
if ( Vec_IntEntry(vStats[2], i) >= nMinCexes || Vec_IntEntry(vStats[1], i) > 10*Vec_IntEntry(vStats[2], i) )
|
||||
continue;
|
||||
{
|
||||
assert( Gia_ObjIsCo(pObj) );
|
||||
if ( Gia_ObjFaninId0p(p, pObj) == 0 ) {
|
||||
if ( fVerbose )
|
||||
printf( "Output %d is driven by constant %d.\n", Gia_ObjCioId(pObj), Gia_ObjFaninC0(pObj) );
|
||||
continue;
|
||||
}
|
||||
abctime clk = Abc_Clock();
|
||||
int iObj = Min_ManCo(pNew, i);
|
||||
int Index = Gia_ObjCioId(pObj);
|
||||
Vec_Int_t * vMap = Vec_IntAlloc( 100 );
|
||||
Gia_Man_t * pCon = Gia_ManDupCones2( p, &Index, 1, vMap );
|
||||
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCon, 8, 0, 0, 0, 0 );
|
||||
Gia_Man_t * pCon1= fUseSynthesis ? Gia_ManAigSyn2( pCon, 0, 1, 0, 100, 0, 0, 0 ) : NULL;
|
||||
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( fUseSynthesis ? pCon1 : pCon, 8, 0, 0, 0, 0 );
|
||||
sat_solver* pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
|
||||
int Lit = Abc_Var2Lit( 1, 0 );
|
||||
int status = sat_solver_addclause( pSat, &Lit, &Lit+1 );
|
||||
|
|
@ -972,8 +993,11 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
|
|||
while ( nAllCalls++ < 100 )
|
||||
{
|
||||
int v, iVar = pCnf->nVars - Gia_ManPiNum(pCon), nVars = Gia_ManPiNum(pCon);
|
||||
sat_solver_randomize( pSat, iVar, nVars );
|
||||
if ( nAllCalls > 1 )
|
||||
sat_solver_randomize( pSat, iVar, nVars );
|
||||
status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
|
||||
if ( status != l_True )
|
||||
break;
|
||||
assert( status == l_True );
|
||||
Vec_IntClear( vLits );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
|
|
@ -1004,11 +1028,22 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
|
|||
sat_solver_delete( pSat );
|
||||
Cnf_DataFree( pCnf );
|
||||
Gia_ManStop( pCon );
|
||||
Gia_ManStopP( &pCon1 );
|
||||
Vec_IntFree( vMap );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "SAT solving for output %3d (cexes = %5d) : ", i, nCurrCexes );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
}
|
||||
}
|
||||
}
|
||||
clkSat = Abc_Clock() - clkSat - clkSim;
|
||||
if ( fVerbose )
|
||||
printf( "Used simulation for %d and SAT for %d outputs (out of %d).\n", nSimOuts, nSatOuts, nOuts );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "Simulation time ", clkSim );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "SAT solving time ", clkSat );
|
||||
//Vec_WecPrint( vCexes, 0 );
|
||||
if ( vOuts != vOuts0 )
|
||||
Vec_IntFreeP( &vOuts );
|
||||
|
|
@ -1076,7 +1111,7 @@ Vec_Ptr_t * Min_ReloadCexes( Vec_Wec_t * vCexes, int nMinCexes )
|
|||
Vec_Wrd_t * Min_ManBitPack( Gia_Man_t * p, int nWords0, Vec_Wec_t * vCexes, int fRandom, int nMinCexes, Vec_Int_t * vScores, int fVerbose )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
int fVeryVerbose = 0;
|
||||
//int fVeryVerbose = 0;
|
||||
Vec_Wrd_t * vSimsPi = NULL;
|
||||
Vec_Int_t * vLevel;
|
||||
int w, nBits, nTotal = 0, fFailed = ABC_INFINITY;
|
||||
|
|
@ -1259,39 +1294,51 @@ Vec_Wrd_t * Gia_ManCollectSims( Gia_Man_t * pSwp, int nWords, Vec_Int_t * vOuts,
|
|||
Vec_Int_t * vMap = Vec_IntAlloc( 100 );
|
||||
Gia_Man_t * pSwp2 = Gia_ManDupCones2( pSwp, Vec_IntArray(vOuts), Vec_IntSize(vOuts), vMap );
|
||||
Vec_Wec_t * vCexes = Min_ManComputeCexes( pSwp2, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose );
|
||||
Vec_Wrd_t * vSimsPi = Min_ManBitPack( pSwp2, nWords, vCexes, 1, nMinCexes, vStats[0], fVerbose );
|
||||
Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 );
|
||||
Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) );
|
||||
if ( fVerbose )
|
||||
Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) );
|
||||
if ( fVeryVerbose )
|
||||
if ( Vec_IntSum(vStats[2]) == 0 )
|
||||
{
|
||||
printf( "Unsolved = %4d ", Vec_IntSize(vOuts) );
|
||||
Gia_ManPrintStats( pSwp2, NULL );
|
||||
Vec_IntForEachEntry( vOuts, iObj, i )
|
||||
{
|
||||
printf( "%4d : ", i );
|
||||
printf( "Out = %5d ", Vec_IntEntry(vMap, i) );
|
||||
printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) );
|
||||
printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) );
|
||||
printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) );
|
||||
printf( "Count = %5d ", Vec_IntEntry(vCounts, i) );
|
||||
printf( "\n" );
|
||||
if ( i == 20 )
|
||||
break;
|
||||
}
|
||||
for ( i = 0; i < 3; i++ )
|
||||
Vec_IntFree( vStats[i] );
|
||||
Vec_IntFree( vMap );
|
||||
Gia_ManStop( pSwp2 );
|
||||
Vec_WecFree( vCexes );
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec_Wrd_t * vSimsPi = Min_ManBitPack( pSwp2, nWords, vCexes, 1, nMinCexes, vStats[0], fVerbose );
|
||||
Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 );
|
||||
Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) );
|
||||
if ( fVerbose )
|
||||
Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) );
|
||||
if ( fVeryVerbose )
|
||||
{
|
||||
printf( "Unsolved = %4d ", Vec_IntSize(vOuts) );
|
||||
Gia_ManPrintStats( pSwp2, NULL );
|
||||
Vec_IntForEachEntry( vOuts, iObj, i )
|
||||
{
|
||||
printf( "%4d : ", i );
|
||||
printf( "Out = %5d ", Vec_IntEntry(vMap, i) );
|
||||
printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) );
|
||||
printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) );
|
||||
printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) );
|
||||
printf( "Count = %5d ", Vec_IntEntry(vCounts, i) );
|
||||
printf( "\n" );
|
||||
if ( i == 20 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
for ( i = 0; i < 3; i++ )
|
||||
Vec_IntFree( vStats[i] );
|
||||
Vec_IntFree( vCounts );
|
||||
Vec_WrdFree( vSimsPo );
|
||||
Vec_WecFree( vCexes );
|
||||
Gia_ManStop( pSwp2 );
|
||||
//printf( "Compressing inputs: %5d -> %5d\n", Gia_ManCiNum(pSwp), Vec_IntSize(vMap) );
|
||||
vSimsPi = Min_ManRemapSims( Gia_ManCiNum(pSwp), vMap, vSimsPo = vSimsPi );
|
||||
Vec_WrdFree( vSimsPo );
|
||||
Vec_IntFree( vMap );
|
||||
return vSimsPi;
|
||||
}
|
||||
for ( i = 0; i < 3; i++ )
|
||||
Vec_IntFree( vStats[i] );
|
||||
Vec_IntFree( vCounts );
|
||||
Vec_WrdFree( vSimsPo );
|
||||
Vec_WecFree( vCexes );
|
||||
Gia_ManStop( pSwp2 );
|
||||
//printf( "Compressing inputs: %5d -> %5d\n", Gia_ManCiNum(pSwp), Vec_IntSize(vMap) );
|
||||
vSimsPi = Min_ManRemapSims( Gia_ManCiNum(pSwp), vMap, vSimsPo = vSimsPi );
|
||||
Vec_WrdFree( vSimsPo );
|
||||
Vec_IntFree( vMap );
|
||||
return vSimsPi;
|
||||
}
|
||||
Vec_Wrd_t * Min_ManCollect( Gia_Man_t * p, int nConf, int nConf2, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
|
|
@ -1320,6 +1367,136 @@ void Min_ManTest2( Gia_Man_t * p )
|
|||
Vec_WrdFreeP( &vSimsPi );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_GenerateCexesDumpBlif( char * pFileName, Gia_Man_t * p, Vec_Wec_t * vCexes )
|
||||
{
|
||||
extern Vec_Ptr_t * Gia_GetFakeNames( int nNames, int fCaps );
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open output file name \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
int fFakeIns = 0, fFakeOuts = 0;
|
||||
if ( p->vNamesIn == NULL )
|
||||
p->vNamesIn = Gia_GetFakeNames( Gia_ManCiNum(p), 0 ), fFakeIns = 1;
|
||||
if ( p->vNamesOut == NULL )
|
||||
p->vNamesOut = Gia_GetFakeNames( Gia_ManCoNum(p), 1 ), fFakeOuts = 1;
|
||||
|
||||
Gia_Obj_t * pObj, * pObj2;
|
||||
char * pLine = ABC_CALLOC( char, Gia_ManCiNum(p)+3 );
|
||||
int i, k, c, iLit, nOuts[2] = {0}, nCexes = Vec_WecSize(vCexes) / Gia_ManCoNum(p);
|
||||
fprintf( pFile, "# Satisfying assignments for the primary outputs generated by ABC on %s\n", Gia_TimeStamp() );
|
||||
fprintf( pFile, ".model %s\n", p->pName );
|
||||
fprintf( pFile, ".inputs" );
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
fprintf( pFile, " %s", Gia_ObjCiName(p, i) );
|
||||
fprintf( pFile, "\n.outputs" );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
fprintf( pFile, " %s", Gia_ObjCoName(p, i) );
|
||||
fprintf( pFile, "\n" );
|
||||
Gia_ManForEachCo( p, pObj, i ) {
|
||||
if ( Gia_ObjFaninLit0p(p, pObj) == 0 ) {
|
||||
fprintf( pFile, ".names %s\n", Gia_ObjCoName(p, i) );
|
||||
nOuts[0]++;
|
||||
}
|
||||
else if ( Gia_ObjFaninLit0p(p, pObj) == 1 ) {
|
||||
fprintf( pFile, ".names %s\n 1\n", Gia_ObjCiName(p, i) );
|
||||
nOuts[1]++;
|
||||
}
|
||||
else {
|
||||
fprintf( pFile, ".names" );
|
||||
Gia_ManForEachCi( p, pObj2, c )
|
||||
fprintf( pFile, " %s", Gia_ObjCiName(p, c) );
|
||||
fprintf( pFile, " %s\n", Gia_ObjCoName(p, i) );
|
||||
for ( c = 0; c < nCexes; c++ ) {
|
||||
Vec_Int_t * vPat = Vec_WecEntry( vCexes, i*nCexes+c );
|
||||
memset(pLine, '-', Gia_ManCiNum(p) );
|
||||
Vec_IntForEachEntry( vPat, iLit, k )
|
||||
pLine[Abc_Lit2Var(iLit)-1] = '1' - Abc_LitIsCompl(iLit);
|
||||
fprintf( pFile, "%s 1\n", pLine );
|
||||
}
|
||||
nOuts[1]++;
|
||||
}
|
||||
}
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
fclose( pFile );
|
||||
printf( "Information about %d sat, %d unsat, and %d undecided primary outputs was written into BLIF file \"%s\".\n",
|
||||
nOuts[1], nOuts[0], Gia_ManCoNum(p)-nOuts[1]-nOuts[0], pFileName );
|
||||
free( pLine );
|
||||
|
||||
if ( fFakeIns ) Vec_PtrFreeFree( p->vNamesIn ), p->vNamesIn = NULL;
|
||||
if ( fFakeOuts ) Vec_PtrFreeFree( p->vNamesOut ), p->vNamesOut = NULL;
|
||||
}
|
||||
void Gia_GenerateCexesDumpFile( char * pFileName, Gia_Man_t * p, Vec_Wec_t * vCexes, int fShort )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open output file name \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
Gia_Obj_t * pObj;
|
||||
char * pLine = ABC_CALLOC( char, Gia_ManCiNum(p)+3 );
|
||||
int i, k, c, iLit, nOuts[2] = {0}, nCexes = Vec_WecSize(vCexes) / Gia_ManCoNum(p);
|
||||
Gia_ManForEachCo( p, pObj, i ) {
|
||||
if ( Gia_ObjFaninLit0p(p, Gia_ManCo(p, i)) == 0 ) {
|
||||
fprintf( pFile, "%d : unsat\n", i );
|
||||
nOuts[0]++;
|
||||
}
|
||||
else if ( fShort ) {
|
||||
for ( c = 0; c < nCexes; c++ ) {
|
||||
Vec_Int_t * vPat = Vec_WecEntry( vCexes, i*nCexes+c );
|
||||
fprintf( pFile, "%d :", i );
|
||||
if ( Vec_IntSize(vPat) == 0 )
|
||||
fprintf( pFile, " not available" );
|
||||
else
|
||||
Vec_IntForEachEntry( vPat, iLit, k )
|
||||
fprintf( pFile, " %d", iLit );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
nOuts[1]++;
|
||||
}
|
||||
else {
|
||||
for ( c = 0; c < nCexes; c++ ) {
|
||||
Vec_Int_t * vPat = Vec_WecEntry( vCexes, i*nCexes+c );
|
||||
memset(pLine, '-', Gia_ManCiNum(p) );
|
||||
Vec_IntForEachEntry( vPat, iLit, k )
|
||||
pLine[Abc_Lit2Var(iLit)-1] = '1' - Abc_LitIsCompl(iLit);
|
||||
fprintf( pFile, "%d : %s\n", i, pLine );
|
||||
}
|
||||
nOuts[1]++;
|
||||
}
|
||||
}
|
||||
printf( "Information about %d sat, %d unsat, and %d undecided primary outputs was written into file \"%s\".\n",
|
||||
nOuts[1], nOuts[0], Gia_ManCoNum(p)-nOuts[1]-nOuts[0], pFileName );
|
||||
fclose( pFile );
|
||||
free( pLine );
|
||||
}
|
||||
void Gia_GenerateCexes( char * pFileName, Gia_Man_t * p, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fShort, int fBlif, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
unsigned Start = Abc_Random(1);
|
||||
Vec_Int_t * vStats[3] = {0}; int i;
|
||||
Vec_Wec_t * vCexes = Min_ManComputeCexes( p, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose );
|
||||
assert( Vec_WecSize(vCexes) == Gia_ManCoNum(p) * nMinCexes );
|
||||
if ( fBlif )
|
||||
Gia_GenerateCexesDumpBlif( pFileName, p, vCexes );
|
||||
else
|
||||
Gia_GenerateCexesDumpFile( pFileName, p, vCexes, fShort );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
Vec_IntFreeP( &vStats[i] );
|
||||
Vec_WecFree( vCexes );
|
||||
Start = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@
|
|||
#include "sat/bsat/satStore.h"
|
||||
#include "misc/extra/extra.h"
|
||||
#include "sat/glucose/AbcGlucose.h"
|
||||
#include "sat/cadical/cadicalSolver.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "base/io/ioResub.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -44,6 +46,7 @@ struct Qbf_Man_t_
|
|||
sat_solver * pSatVer; // verification instance
|
||||
sat_solver * pSatSyn; // synthesis instance
|
||||
bmcg_sat_solver*pSatSynG; // synthesis instance
|
||||
cadical_solver* pSatSynC; // synthesis instance
|
||||
Vec_Int_t * vValues; // variable values
|
||||
Vec_Int_t * vParMap; // parameter mapping
|
||||
Vec_Int_t * vLits; // literals for the SAT solver
|
||||
|
|
@ -482,6 +485,45 @@ void Gia_QbfDumpFile( Gia_Man_t * pGia, int nPars )
|
|||
Vec_IntFree( vVarMap );
|
||||
printf( "The 2QBF formula was written into file \"%s\".\n", pFileName );
|
||||
}
|
||||
void Gia_QbfDumpFileInv( Gia_Man_t * pGia, int nPars )
|
||||
{
|
||||
// original problem: \exists p \forall x \exists y. M(p,x,y)
|
||||
// negated problem: \forall p \exists x \exists y. !M(p,x,y)
|
||||
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
|
||||
Vec_Int_t * vVarMap, * vForAlls, * vExists1, * vExists2;
|
||||
Gia_Obj_t * pObj;
|
||||
char * pFileName;
|
||||
int i, Entry;
|
||||
// complement the last clause
|
||||
//int * pLit = pCnf->pClauses[pCnf->nClauses] - 1; *pLit ^= 1;
|
||||
// create var map
|
||||
vVarMap = Vec_IntStart( pCnf->nVars );
|
||||
Gia_ManForEachCi( pGia, pObj, i )
|
||||
Vec_IntWriteEntry( vVarMap, pCnf->pVarNums[Gia_ManCiIdToId(pGia, i)], i < nPars ? 1 : 2 );
|
||||
// create various maps
|
||||
vExists1 = Vec_IntAlloc( nPars );
|
||||
vForAlls = Vec_IntAlloc( Gia_ManCiNum(pGia) - nPars );
|
||||
vExists2 = Vec_IntAlloc( pCnf->nVars - Gia_ManCiNum(pGia) );
|
||||
Vec_IntForEachEntry( vVarMap, Entry, i )
|
||||
if ( Entry == 1 )
|
||||
Vec_IntPush( vExists1, i );
|
||||
else if ( Entry == 2 )
|
||||
Vec_IntPush( vForAlls, i );
|
||||
else
|
||||
Vec_IntPush( vExists2, i );
|
||||
// generate CNF
|
||||
pFileName = Extra_FileNameGenericAppend( pGia->pSpec, ".qdimacs" );
|
||||
Cnf_DataWriteIntoFileInv( pCnf, pFileName, 0, vExists1, vForAlls, vExists2 );
|
||||
Cnf_DataFree( pCnf );
|
||||
Vec_IntFree( vExists1 );
|
||||
Vec_IntFree( vForAlls );
|
||||
Vec_IntFree( vExists2 );
|
||||
Vec_IntFree( vVarMap );
|
||||
printf( "The 2QBF formula was written into file \"%s\".\n", pFileName );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -494,7 +536,7 @@ void Gia_QbfDumpFile( Gia_Man_t * pGia, int nPars )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fGlucose, int fVerbose )
|
||||
Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fGlucose, int fCadical, int fVerbose )
|
||||
{
|
||||
Qbf_Man_t * p;
|
||||
Cnf_Dat_t * pCnf;
|
||||
|
|
@ -511,11 +553,13 @@ Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fGlucose, int fVerbos
|
|||
p->pSatVer = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
|
||||
p->pSatSyn = sat_solver_new();
|
||||
p->pSatSynG = fGlucose ? bmcg_sat_solver_start() : NULL;
|
||||
p->pSatSynC = fCadical ? cadical_solver_new() : NULL;
|
||||
p->vValues = Vec_IntAlloc( Gia_ManPiNum(pGia) );
|
||||
p->vParMap = Vec_IntStartFull( nPars );
|
||||
p->vLits = Vec_IntAlloc( nPars );
|
||||
sat_solver_setnvars( p->pSatSyn, nPars );
|
||||
if ( p->pSatSynG ) bmcg_sat_solver_set_nvars( p->pSatSynG, nPars );
|
||||
if ( p->pSatSynC ) cadical_solver_setnvars( p->pSatSynC, nPars );
|
||||
Cnf_DataFree( pCnf );
|
||||
return p;
|
||||
}
|
||||
|
|
@ -524,6 +568,7 @@ void Gia_QbfFree( Qbf_Man_t * p )
|
|||
sat_solver_delete( p->pSatVer );
|
||||
sat_solver_delete( p->pSatSyn );
|
||||
if ( p->pSatSynG ) bmcg_sat_solver_stop( p->pSatSynG );
|
||||
if ( p->pSatSynC ) cadical_solver_delete( p->pSatSynC );
|
||||
Vec_IntFree( p->vLits );
|
||||
Vec_IntFree( p->vValues );
|
||||
Vec_IntFree( p->vParMap );
|
||||
|
|
@ -709,6 +754,21 @@ int Gia_QbfAddCofactorG( Qbf_Man_t * p, Gia_Man_t * pCof )
|
|||
Cnf_DataFree( pCnf );
|
||||
return 1;
|
||||
}
|
||||
int Gia_QbfAddCofactorC( Qbf_Man_t * p, Gia_Man_t * pCof )
|
||||
{
|
||||
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCof, 8, 0, 1, 0, 0 );
|
||||
int i, iFirstVar = pCnf->nVars - Gia_ManPiNum(pCof); //-1
|
||||
pCnf->pMan = NULL;
|
||||
Cnf_SpecialDataLift( pCnf, cadical_solver_nvars(p->pSatSynC), iFirstVar, iFirstVar + Gia_ManPiNum(p->pGia) );
|
||||
for ( i = 0; i < pCnf->nClauses; i++ )
|
||||
if ( !cadical_solver_addclause( p->pSatSynC, pCnf->pClauses[i], pCnf->pClauses[i+1] ) )
|
||||
{
|
||||
Cnf_DataFree( pCnf );
|
||||
return 0;
|
||||
}
|
||||
Cnf_DataFree( pCnf );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -726,16 +786,20 @@ void Gia_QbfOnePattern( Qbf_Man_t * p, Vec_Int_t * vValues )
|
|||
int i;
|
||||
Vec_IntClear( vValues );
|
||||
for ( i = 0; i < p->nPars; i++ )
|
||||
Vec_IntPush( vValues, p->pSatSynG ? bmcg_sat_solver_read_cex_varvalue(p->pSatSynG, i) : sat_solver_var_value(p->pSatSyn, i) );
|
||||
Vec_IntPush( vValues, p->pSatSynC ? cadical_solver_get_var_value(p->pSatSynC, i) :
|
||||
p->pSatSynG ? bmcg_sat_solver_read_cex_varvalue(p->pSatSynG, i) : sat_solver_var_value(p->pSatSyn, i) );
|
||||
}
|
||||
void Gia_QbfPrint( Qbf_Man_t * p, Vec_Int_t * vValues, int Iter )
|
||||
{
|
||||
printf( "%5d : ", Iter );
|
||||
assert( Vec_IntSize(vValues) == p->nVars );
|
||||
Vec_IntPrintBinary( vValues ); printf( " " );
|
||||
printf( "Var =%7d ", p->pSatSynG ? bmcg_sat_solver_varnum(p->pSatSynG) : sat_solver_nvars(p->pSatSyn) );
|
||||
printf( "Cla =%7d ", p->pSatSynG ? bmcg_sat_solver_clausenum(p->pSatSynG) : sat_solver_nclauses(p->pSatSyn) );
|
||||
printf( "Conf =%9d ", p->pSatSynG ? bmcg_sat_solver_conflictnum(p->pSatSynG) : sat_solver_nconflicts(p->pSatSyn) );
|
||||
printf( "Var =%7d ", p->pSatSynC ? cadical_solver_nvars(p->pSatSynC) :
|
||||
p->pSatSynG ? bmcg_sat_solver_varnum(p->pSatSynG) : sat_solver_nvars(p->pSatSyn) );
|
||||
printf( "Cla =%7d ", p->pSatSynC ? cadical_solver_nclauses(p->pSatSynC) :
|
||||
p->pSatSynG ? bmcg_sat_solver_clausenum(p->pSatSynG) : sat_solver_nclauses(p->pSatSyn) );
|
||||
printf( "Conf =%9d ", p->pSatSynC ? cadical_solver_nconflicts(p->pSatSynC) :
|
||||
p->pSatSynG ? bmcg_sat_solver_conflictnum(p->pSatSynG) : sat_solver_nconflicts(p->pSatSyn) );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
|
||||
}
|
||||
|
||||
|
|
@ -829,9 +893,9 @@ void Gia_QbfLearnConstraint( Qbf_Man_t * p, Vec_Int_t * vValues )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, int nTimeOut, int nEncVars, int fGlucose, int fVerbose )
|
||||
int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, int nTimeOut, int nEncVars, int fGlucose, int fCadical, int fSilent, int fVerbose )
|
||||
{
|
||||
Qbf_Man_t * p = Gia_QbfAlloc( pGia, nPars, fGlucose, fVerbose );
|
||||
Qbf_Man_t * p = Gia_QbfAlloc( pGia, nPars, fGlucose, fCadical, fVerbose );
|
||||
Gia_Man_t * pCof;
|
||||
int i, status, RetValue = 0;
|
||||
abctime clk;
|
||||
|
|
@ -846,12 +910,15 @@ int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, i
|
|||
// generate next constraint
|
||||
assert( Vec_IntSize(p->vValues) == p->nVars );
|
||||
pCof = Gia_QbfCofactor( pGia, nPars, p->vValues, p->vParMap );
|
||||
status = p->pSatSynG ? Gia_QbfAddCofactorG( p, pCof ) : Gia_QbfAddCofactor( p, pCof );
|
||||
status = p->pSatSynC ? Gia_QbfAddCofactorC( p, pCof ) :
|
||||
p->pSatSynG ? Gia_QbfAddCofactorG( p, pCof ) : Gia_QbfAddCofactor( p, pCof );
|
||||
Gia_ManStop( pCof );
|
||||
if ( status == 0 ) { RetValue = 1; break; }
|
||||
// synthesize next assignment
|
||||
clk = Abc_Clock();
|
||||
if ( p->pSatSynG )
|
||||
if ( p->pSatSynC )
|
||||
status = cadical_solver_solve( p->pSatSynC, NULL, NULL, 0, 0, 0, 0 );
|
||||
else if ( p->pSatSynG )
|
||||
status = bmcg_sat_solver_solve( p->pSatSynG, NULL, 0 );
|
||||
else
|
||||
status = sat_solver_solve( p->pSatSyn, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
|
||||
|
|
@ -872,9 +939,18 @@ int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, i
|
|||
if ( RetValue == 0 )
|
||||
{
|
||||
int nZeros = Vec_IntCountZero( p->vValues );
|
||||
printf( "Parameters: " );
|
||||
printf( "Parameters (%d): 0x", nPars );
|
||||
assert( Vec_IntSize(p->vValues) == nPars );
|
||||
Vec_IntPrintBinary( p->vValues );
|
||||
//Vec_IntPrintBinary( p->vValues );
|
||||
while ( Vec_IntSize(p->vValues) % 4 )
|
||||
Vec_IntPush(p->vValues, 0);
|
||||
for ( int i = Vec_IntSize(p->vValues)/4 - 1; i >= 0; i-- ) {
|
||||
int Digit = Vec_IntEntry(p->vValues, 4*i+0);
|
||||
Digit |= Vec_IntEntry(p->vValues, 4*i+1) << 1;
|
||||
Digit |= Vec_IntEntry(p->vValues, 4*i+2) << 2;
|
||||
Digit |= Vec_IntEntry(p->vValues, 4*i+3) << 3;
|
||||
printf( "%x", Digit );
|
||||
}
|
||||
printf( " Statistics: 0=%d 1=%d\n", nZeros, Vec_IntSize(p->vValues) - nZeros );
|
||||
if ( nEncVars )
|
||||
{
|
||||
|
|
@ -889,9 +965,9 @@ int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, i
|
|||
printf( "The problem aborted after %d conflicts. ", nConfLimit );
|
||||
else if ( RetValue == -1 && nIterLimit )
|
||||
printf( "The problem aborted after %d iterations. ", nIterLimit );
|
||||
else if ( RetValue == 1 )
|
||||
else if ( RetValue == 1 && !fSilent )
|
||||
printf( "The problem is UNSAT after %d iterations. ", i );
|
||||
else
|
||||
else if ( !fSilent )
|
||||
printf( "The problem is SAT after %d iterations. ", i );
|
||||
if ( fVerbose )
|
||||
{
|
||||
|
|
@ -900,12 +976,307 @@ int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, i
|
|||
Abc_PrintTime( 1, "Other", Abc_Clock() - p->clkStart - p->clkSat );
|
||||
Abc_PrintTime( 1, "TOTAL", Abc_Clock() - p->clkStart );
|
||||
}
|
||||
else
|
||||
else if ( !fSilent )
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
|
||||
Gia_QbfFree( p );
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive the SAT solver.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
sat_solver * Gia_ManGenSolver( Gia_Man_t * p, Vec_Int_t * vInsOuts, int nIns )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, nObjs = Gia_ManObjNum(p);
|
||||
sat_solver * pSat = sat_solver_new();
|
||||
sat_solver_setnvars( pSat, 2 * nObjs );
|
||||
Gia_ManIncrementTravId(p);
|
||||
Gia_ManForEachObjVecStart( vInsOuts, p, pObj, i, nIns )
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
sat_solver_add_and( pSat, i, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninId1(pObj, i), Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
sat_solver_add_and( pSat, nObjs+i, nObjs+Gia_ObjFaninId0(pObj, i), nObjs+Gia_ObjFaninId1(pObj, i), Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
sat_solver_add_buffer( pSat, nObjs+Gia_ObjId(p, pObj), Gia_ObjId(p, pObj), 0 );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
if ( Gia_ObjFaninId0p(p, pObj) > 0 ) {
|
||||
sat_solver_add_buffer( pSat, Gia_ObjId(p, pObj), Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) );
|
||||
sat_solver_add_buffer( pSat, nObjs+Gia_ObjId(p, pObj), nObjs+Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) );
|
||||
sat_solver_add_buffer( pSat, nObjs+Gia_ObjId(p, pObj), Gia_ObjId(p, pObj), 0 );
|
||||
}
|
||||
return pSat;
|
||||
}
|
||||
Vec_Int_t * Gia_ManGenCombs( Gia_Man_t * p, Vec_Int_t * vInsOuts, int nIns, int fVerbose )
|
||||
{
|
||||
int nTimeOut = 600, nConfLimit = 1000000;
|
||||
int i, iSatVar, Iter, Mask, nSolutions = 0, RetValue = 0;
|
||||
abctime clkStart = Abc_Clock();
|
||||
sat_solver * pSat = Gia_ManGenSolver( p, vInsOuts, nIns );
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
|
||||
for ( Iter = 0; Iter < 1000000; Iter++ )
|
||||
{
|
||||
int status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
|
||||
if ( status == l_False ) { RetValue = 1; break; }
|
||||
if ( status == l_Undef ) { RetValue = 0; break; }
|
||||
nSolutions++;
|
||||
// extract SAT assignment
|
||||
Mask = 0;
|
||||
Vec_IntClear( vLits );
|
||||
Vec_IntForEachEntry( vInsOuts, iSatVar, i ) {
|
||||
Vec_IntPush( vLits, Abc_Var2Lit(iSatVar, sat_solver_var_value(pSat, iSatVar)) );
|
||||
if ( sat_solver_var_value(pSat, iSatVar) )
|
||||
Mask |= 1 << (Vec_IntSize(vInsOuts)-1-i);
|
||||
}
|
||||
Vec_IntPush( vRes, Mask );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "%5d : ", Iter );
|
||||
Vec_IntForEachEntry( vInsOuts, iSatVar, i ) {
|
||||
if ( i == nIns ) printf( " " );
|
||||
printf( "%d", (Mask >> (Vec_IntSize(vInsOuts)-1-i)) & 1 );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
// add clause
|
||||
if ( !sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ) )
|
||||
{ RetValue = 1; break; }
|
||||
if ( nTimeOut && (Abc_Clock() - clkStart)/CLOCKS_PER_SEC >= nTimeOut ) { RetValue = 0; break; }
|
||||
}
|
||||
Vec_IntSort( vRes, 0 );
|
||||
Vec_IntFree( vLits );
|
||||
sat_solver_delete( pSat );
|
||||
if ( RetValue == 0 )
|
||||
Vec_IntFreeP( &vRes );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
|
||||
return vRes;
|
||||
}
|
||||
void Gia_ManGenWriteRel( Vec_Int_t * vRes, int nIns, int nOuts, char * pFileName )
|
||||
{
|
||||
int i, k, Mask, nVars = nIns + nOuts;
|
||||
Abc_RData_t * p2, * p = Abc_RDataStart( nIns, nOuts, Vec_IntSize(vRes) );
|
||||
Vec_IntForEachEntry( vRes, Mask, i ) {
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
if ( (Mask >> (nVars-1-k)) & 1 ) { // the bit is 1
|
||||
if ( k < nIns )
|
||||
Abc_RDataSetIn( p, k, i );
|
||||
else
|
||||
Abc_RDataSetOut( p, 2*(k-nIns)+1, i );
|
||||
}
|
||||
else { // the bit is zero
|
||||
if ( k >= nIns )
|
||||
Abc_RDataSetOut( p, 2*(k-nIns), i );
|
||||
}
|
||||
}
|
||||
Abc_WritePla( p, pFileName, 0 );
|
||||
p2 = Abc_RData2Rel( p );
|
||||
Abc_WritePla( p2, Extra_FileNameGenericAppend(pFileName, "_rel.pla"), 1 );
|
||||
Abc_RDataStop( p2 );
|
||||
Abc_RDataStop( p );
|
||||
}
|
||||
void Gia_ManGenRel2( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns, char * pFileName, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vRes = Gia_ManGenCombs( pGia, vInsOuts, nIns, fVerbose );
|
||||
if ( vRes == NULL ) {
|
||||
printf( "Enumerating solutions did not succeed.\n" );
|
||||
return;
|
||||
}
|
||||
Gia_ManGenWriteRel( vRes, nIns, Vec_IntSize(vInsOuts)-nIns, pFileName );
|
||||
Vec_IntFree( vRes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive the SAT solver.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManCollectNodeTfos( Gia_Man_t * p, int * pNodes, int nNodes )
|
||||
{
|
||||
Vec_Int_t * vTfo = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Gia_ManIncrementTravId( p );
|
||||
for ( i = 0; i < nNodes; i++ )
|
||||
Gia_ObjSetTravIdCurrentId( p, pNodes[i] );
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, i) )
|
||||
continue;
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) || Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) )
|
||||
Gia_ObjSetTravIdCurrentId( p, i ), Vec_IntPush( vTfo, i );
|
||||
}
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0p(p, pObj)) )
|
||||
Vec_IntPush( vTfo, Gia_ObjId(p, pObj) );
|
||||
return vTfo;
|
||||
}
|
||||
Vec_Int_t * Gia_ManCollectNodeTfis( Gia_Man_t * p, Vec_Int_t * vNodes )
|
||||
{
|
||||
Vec_Int_t * vTfi = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj; int i, Id;
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachObjVec( vNodes, p, pObj, i )
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
Gia_ObjSetTravIdCurrentId( p, Gia_ObjFaninId0p(p, pObj) );
|
||||
Gia_ManForEachAndReverse( p, pObj, i ) {
|
||||
if ( !Gia_ObjIsTravIdCurrentId(p, i) )
|
||||
continue;
|
||||
Gia_ObjSetTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i));
|
||||
Gia_ObjSetTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i));
|
||||
}
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Id) )
|
||||
Vec_IntPush( vTfi, Id );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, i) )
|
||||
Vec_IntPush( vTfi, i );
|
||||
return vTfi;
|
||||
}
|
||||
Gia_Man_t * Gia_ManGenRelMiter( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns )
|
||||
{
|
||||
Vec_Int_t * vTfo = Gia_ManCollectNodeTfos( pGia, Vec_IntEntryP(vInsOuts, nIns), Vec_IntSize(vInsOuts)-nIns );
|
||||
Vec_Int_t * vTfi = Gia_ManCollectNodeTfis( pGia, vTfo );
|
||||
Vec_Int_t * vInLits = Vec_IntAlloc( nIns );
|
||||
Vec_Int_t * vOutLits = Vec_IntAlloc( Vec_IntSize(vInsOuts) - nIns );
|
||||
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, iLit = 0;
|
||||
Gia_ManFillValue( pGia );
|
||||
pNew = Gia_ManStart( 1000 );
|
||||
pNew->pName = Abc_UtilStrsav( pGia->pName );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Gia_ManForEachObjVec( vTfi, pGia, pObj, i )
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
for ( i = 0; i < Vec_IntSize(vInsOuts)-nIns; i++ )
|
||||
Vec_IntPush( vInLits, Gia_ManAppendCi(pNew) );
|
||||
Gia_ManForEachObjVec( vTfi, pGia, pObj, i )
|
||||
if ( Gia_ObjIsAnd(pObj) )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachObjVec( vTfo, pGia, pObj, i )
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
pObj->Value = Gia_ObjFanin0Copy(pObj);
|
||||
Gia_ManForEachObjVec( vInsOuts, pGia, pObj, i )
|
||||
if ( i < nIns )
|
||||
Vec_IntPush( vOutLits, pObj->Value );
|
||||
else
|
||||
pObj->Value = Vec_IntEntry( vInLits, i-nIns );
|
||||
Gia_ManForEachObjVec( vTfo, pGia, pObj, i )
|
||||
if ( Gia_ObjIsAnd(pObj) )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachObjVec( vTfo, pGia, pObj, i )
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, Gia_ObjFanin0Copy(pObj), pObj->Value) );
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
Vec_IntForEachEntry( vOutLits, iLit, i )
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
Vec_IntFree( vTfo );
|
||||
Vec_IntFree( vTfi );
|
||||
Vec_IntFree( vInLits );
|
||||
Vec_IntFree( vOutLits );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia) );
|
||||
return pNew;
|
||||
}
|
||||
void Gia_ManPrintRelMinterm( int Mint, int nIns, int nVars )
|
||||
{
|
||||
for ( int i = 0; i < nVars; i++ )
|
||||
printf( "%s%d", i == nIns ? " ":"", (Mint >> (nVars-1-i)) & 1 );
|
||||
printf( "\n" );
|
||||
}
|
||||
Vec_Int_t * Gia_ManGenIoCombs( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns, int fVerbose )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
int nTimeOut = 600, nConfLimit = 1000000;
|
||||
int i, iNode, iSatVar, Iter, Mask, nSolutions = 0, RetValue = 0;
|
||||
Gia_Man_t * pMiter = Gia_ManGenRelMiter( pGia, vInsOuts, nIns );
|
||||
Cnf_Dat_t * pCnf = (Cnf_Dat_t*)Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0, 0 );
|
||||
sat_solver * pSat = (sat_solver*)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
|
||||
int iLit = Abc_Var2Lit( 1, 0 ); // enumerating the care set (the miter output is 1)
|
||||
int status = sat_solver_addclause( pSat, &iLit, &iLit + 1 ); assert( status );
|
||||
Vec_Int_t * vSatVars = Vec_IntAlloc( Vec_IntSize(vInsOuts) );
|
||||
Vec_IntForEachEntry( vInsOuts, iNode, i )
|
||||
Vec_IntPush( vSatVars, i < nIns ? 2+i : pCnf->nVars-Vec_IntSize(vInsOuts)+i );
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
|
||||
for ( Iter = 0; Iter < 1000000; Iter++ )
|
||||
{
|
||||
int status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
|
||||
if ( status == l_False ) { RetValue = 1; break; }
|
||||
if ( status == l_Undef ) { RetValue = 0; break; }
|
||||
nSolutions++;
|
||||
// extract SAT assignment
|
||||
Mask = 0;
|
||||
Vec_IntClear( vLits );
|
||||
Vec_IntForEachEntry( vSatVars, iSatVar, i ) {
|
||||
Vec_IntPush( vLits, Abc_Var2Lit(iSatVar, sat_solver_var_value(pSat, iSatVar)) );
|
||||
if ( sat_solver_var_value(pSat, iSatVar) )
|
||||
Mask |= 1 << (Vec_IntSize(vInsOuts)-1-i);
|
||||
}
|
||||
Vec_IntPush( vRes, Mask );
|
||||
if ( 0 ) {
|
||||
printf( "%5d : ", Iter );
|
||||
Gia_ManPrintRelMinterm( Mask, nIns, Vec_IntSize(vSatVars) );
|
||||
}
|
||||
// add clause
|
||||
if ( !sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ) )
|
||||
{ RetValue = 1; break; }
|
||||
if ( nTimeOut && (Abc_Clock() - clkStart)/CLOCKS_PER_SEC >= nTimeOut ) { RetValue = 0; break; }
|
||||
}
|
||||
// complement the set of input/output minterms
|
||||
Vec_Int_t * vBits = Vec_IntStart( 1 << Vec_IntSize(vInsOuts) );
|
||||
Vec_IntForEachEntry( vRes, Mask, i )
|
||||
Vec_IntWriteEntry( vBits, Mask, 1 );
|
||||
Vec_IntClear( vRes );
|
||||
Vec_IntForEachEntry( vBits, Mask, i )
|
||||
if ( !Mask )
|
||||
Vec_IntPush( vRes, i );
|
||||
Vec_IntFree( vBits );
|
||||
// cleanup
|
||||
Vec_IntFree( vLits );
|
||||
sat_solver_delete( pSat );
|
||||
Gia_ManStop( pMiter );
|
||||
Cnf_DataFree( pCnf );
|
||||
if ( RetValue == 0 )
|
||||
Vec_IntFreeP( &vRes );
|
||||
return vRes;
|
||||
}
|
||||
void Gia_ManGenRel( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns, char * pFileName, int fVerbose )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
Vec_Int_t * vRes = Gia_ManGenIoCombs( pGia, vInsOuts, nIns, fVerbose );
|
||||
if ( vRes == NULL ) {
|
||||
printf( "Enumerating solutions did not succeed.\n" );
|
||||
return;
|
||||
}
|
||||
Gia_ManGenWriteRel( vRes, nIns, Vec_IntSize(vInsOuts)-nIns, pFileName );
|
||||
if ( fVerbose ) {
|
||||
printf( "The resulting relation with %d input/output minterms is written into file \"%s\". ", Vec_IntSize(vRes), pFileName );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
|
||||
if ( 0 ) {
|
||||
int i, Mint;
|
||||
Vec_IntForEachEntry( vRes, Mint, i )
|
||||
Gia_ManPrintRelMinterm( Mint, nIns, Vec_IntSize(vInsOuts) );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vRes );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "misc/vec/vecQue.h"
|
||||
#include "misc/vec/vecHsh.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "base/io/ioResub.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -67,7 +68,7 @@ int Gia_ObjCheckMffc_rec( Gia_Man_t * p,Gia_Obj_t * pObj, int Limit, Vec_Int_t *
|
|||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static inline int Gia_ObjCheckMffc( Gia_Man_t * p, Gia_Obj_t * pRoot, int Limit, Vec_Int_t * vNodes, Vec_Int_t * vLeaves, Vec_Int_t * vInners )
|
||||
int Gia_ObjCheckMffc( Gia_Man_t * p, Gia_Obj_t * pRoot, int Limit, Vec_Int_t * vNodes, Vec_Int_t * vLeaves, Vec_Int_t * vInners )
|
||||
{
|
||||
int RetValue, iObj, i;
|
||||
Vec_IntClear( vNodes );
|
||||
|
|
@ -2048,10 +2049,111 @@ Vec_Int_t * Gia_ManDeriveSubset( Gia_Man_t * p, Vec_Wrd_t * vFuncs, Vec_Int_t *
|
|||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManResubFindUsed( Vec_Int_t * vRes, int nDivs, int nNodes, Vec_Int_t * vSupp )
|
||||
{
|
||||
int i, k, iLit, Counter = 1;
|
||||
Vec_Int_t * vUsed = Vec_IntStartFull( nDivs );
|
||||
Vec_Int_t * vRes2 = Vec_IntDup( vRes );
|
||||
Vec_IntWriteEntry( vUsed, 0, 0 );
|
||||
assert( Vec_IntSize(vRes) % 2 == 1 );
|
||||
Vec_IntSort( vRes2, 0 );
|
||||
Vec_IntForEachEntry( vRes2, iLit, k )
|
||||
{
|
||||
int iVar = Abc_Lit2Var(iLit);
|
||||
if ( iVar > 0 && iVar < nDivs && Vec_IntEntry(vUsed, iVar) == -1 ) {
|
||||
Vec_IntWriteEntry( vUsed, iVar, Counter++ );
|
||||
Vec_IntPush( vSupp, iVar-2 );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vRes2 );
|
||||
for ( i = nDivs; i < nDivs + nNodes; i++ )
|
||||
Vec_IntPush( vUsed, Counter++ );
|
||||
return vUsed;
|
||||
}
|
||||
Vec_Int_t * Gia_ManResubRemapSolution( Vec_Int_t * vRes, Vec_Int_t * vUsed )
|
||||
{
|
||||
int i, iLit;
|
||||
Vec_Int_t * vResNew = Vec_IntAlloc( Vec_IntSize(vRes) );
|
||||
Vec_IntForEachEntry( vRes, iLit, i )
|
||||
Vec_IntPush( vResNew, Abc_Lit2LitV(Vec_IntArray(vUsed), iLit) );
|
||||
return vResNew;
|
||||
}
|
||||
void Gia_ManResubRecordSolution( char * pFileName, Vec_Int_t * vRes, int nDivs )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "ab" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
|
||||
return;
|
||||
}
|
||||
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vUsed = Gia_ManResubFindUsed( vRes, nDivs, Vec_IntSize(vRes)/2, vSupp );
|
||||
Vec_Int_t * vResN = Gia_ManResubRemapSolution( vRes, vUsed );
|
||||
|
||||
int i, Temp;
|
||||
fprintf( pFile, "\n.s" );
|
||||
Vec_IntForEachEntry( vSupp, Temp, i )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n.a" );
|
||||
Vec_IntForEachEntry( vResN, Temp, i )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
|
||||
Vec_IntFree( vUsed );
|
||||
Vec_IntFree( vSupp );
|
||||
Vec_IntFree( vResN );
|
||||
}
|
||||
Gia_Man_t * Gia_ManResubUnateOne( char * pFileName, int nLimit, int nDivMax, int fWriteSol, int fVerbose )
|
||||
{
|
||||
Gia_Man_t * pNew = NULL;
|
||||
Abc_RData_t * p = Abc_ReadPla( pFileName );
|
||||
if ( p == NULL ) return NULL;
|
||||
assert( p->nOuts == 1 );
|
||||
Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2+p->nIns );
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(p->vSimsOut, 0*p->nSimWords) );
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(p->vSimsOut, 1*p->nSimWords) );
|
||||
int i, k, ArraySize, * pArray;
|
||||
for ( i = 0; i < p->nIns; i++ )
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(p->vSimsIn, i*p->nSimWords) );
|
||||
Abc_ResubPrepareManager( p->nSimWords );
|
||||
if ( fVerbose )
|
||||
printf( "The problem has %d divisors and %d outputs.\n", p->nIns, p->nOuts );
|
||||
ArraySize = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), p->nSimWords, nLimit, nDivMax, 0, 0, 1, fVerbose, &pArray );
|
||||
for ( k = 0; k < ArraySize; k++ )
|
||||
Vec_IntPush( vRes, pArray[k] );
|
||||
if ( ArraySize ) {
|
||||
//Vec_IntPrint( vRes );
|
||||
Vec_Wec_t * vGates = Vec_WecStart(1);
|
||||
Vec_IntAppend( Vec_WecEntry(vGates, 0), vRes );
|
||||
pNew = Gia_ManConstructFromGates( vGates, Vec_PtrSize(vDivs) );
|
||||
Vec_WecFree( vGates );
|
||||
if ( fVerbose )
|
||||
printf( "The solution has %d inputs and %d nodes.\n", Gia_ManCiNum(pNew), Gia_ManAndNum(pNew) );
|
||||
}
|
||||
if ( fWriteSol && ArraySize )
|
||||
Gia_ManResubRecordSolution( pFileName, vRes, Vec_PtrSize(vDivs) );
|
||||
Abc_ResubPrepareManager( 0 );
|
||||
Vec_IntFree( vRes );
|
||||
Vec_PtrFree( vDivs );
|
||||
Abc_RDataStop( p );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -733,7 +733,7 @@ void Gia_RsbCiWindowTest( Gia_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Gia_ObjFaninId( Gia_Obj_t * pObj, int iObj, int n ) { return n ? Gia_ObjFaninId1(pObj, iObj) : Gia_ObjFaninId0(pObj, iObj); }
|
||||
//static inline int Gia_ObjFaninId( Gia_Obj_t * pObj, int iObj, int n ) { return n ? Gia_ObjFaninId1(pObj, iObj) : Gia_ObjFaninId0(pObj, iObj); }
|
||||
|
||||
static inline int Gia_ObjTravIsTopTwo( Gia_Man_t * p, int iNodeA ) { return (p->pTravIds[iNodeA] >= p->nTravIds - 1); }
|
||||
static inline int Gia_ObjTravIsSame( Gia_Man_t * p, int iNodeA, int iNodeB ) { return (p->pTravIds[iNodeA] == p->pTravIds[iNodeB]); }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,564 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaResub6.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Resubstitution.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaResub6.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "base/io/ioResub.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAX_NODE 100
|
||||
|
||||
typedef struct Res6_Man_t_ Res6_Man_t;
|
||||
struct Res6_Man_t_
|
||||
{
|
||||
int nIns; // inputs
|
||||
int nDivs; // divisors
|
||||
int nDivsA; // divisors alloc
|
||||
int nOuts; // outputs
|
||||
int nPats; // patterns
|
||||
int nWords; // words
|
||||
Vec_Wrd_t vIns; // input sim data
|
||||
Vec_Wrd_t vOuts; // input sim data
|
||||
word ** ppLits; // literal sim info
|
||||
word ** ppSets; // set sim info
|
||||
Vec_Int_t vSol; // current solution
|
||||
Vec_Int_t vSolBest; // best solution
|
||||
Vec_Int_t vTempBest;// current best solution
|
||||
Vec_Int_t vSupp; // support
|
||||
};
|
||||
|
||||
extern void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Res6_Man_t * Res6_ManStart( int nIns, int nNodes, int nOuts, int nPats )
|
||||
{
|
||||
Res6_Man_t * p; int i;
|
||||
p = ABC_CALLOC( Res6_Man_t, 1 );
|
||||
p->nIns = nIns;
|
||||
p->nDivs = 1 + nIns + nNodes;
|
||||
p->nDivsA = p->nDivs + MAX_NODE;
|
||||
p->nOuts = nOuts;
|
||||
p->nPats = nPats;
|
||||
p->nWords =(nPats + 63)/64;
|
||||
Vec_WrdFill( &p->vIns, 2*p->nDivsA*p->nWords, 0 );
|
||||
Vec_WrdFill( &p->vOuts, (1 << nOuts)*p->nWords, 0 );
|
||||
p->ppLits = ABC_CALLOC( word *, 2*p->nDivsA );
|
||||
p->ppSets = ABC_CALLOC( word *, 1 << nOuts );
|
||||
for ( i = 0; i < 2*p->nDivsA; i++ )
|
||||
p->ppLits[i] = Vec_WrdEntryP( &p->vIns, i*p->nWords );
|
||||
for ( i = 0; i < (1 << nOuts); i++ )
|
||||
p->ppSets[i] = Vec_WrdEntryP( &p->vOuts, i*p->nWords );
|
||||
Abc_TtFill( p->ppLits[1], p->nWords );
|
||||
Vec_IntGrow( &p->vSol, 2*MAX_NODE+nOuts );
|
||||
Vec_IntGrow( &p->vSolBest, 2*MAX_NODE+nOuts );
|
||||
Vec_IntGrow( &p->vTempBest, 2*MAX_NODE+nOuts );
|
||||
return p;
|
||||
}
|
||||
static inline void Res6_ManStop( Res6_Man_t * p )
|
||||
{
|
||||
Vec_WrdErase( &p->vIns );
|
||||
Vec_WrdErase( &p->vOuts );
|
||||
Vec_IntErase( &p->vSol );
|
||||
Vec_IntErase( &p->vSolBest );
|
||||
Vec_IntErase( &p->vTempBest );
|
||||
Vec_IntErase( &p->vSupp );
|
||||
ABC_FREE( p->ppLits );
|
||||
ABC_FREE( p->ppSets );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Res6_Man_t * Res6_ManReadPla( char * pFileName )
|
||||
{
|
||||
int i, n;
|
||||
Abc_RData_t * pData = Abc_ReadPla( pFileName ); assert( pData->nOuts == 1 );
|
||||
Res6_Man_t * p = pData ? Res6_ManStart( 0, pData->nIns, pData->nOuts, pData->nPats ) : NULL;
|
||||
if ( p == NULL ) return NULL;
|
||||
assert( pData->nSimWords == p->nWords );
|
||||
for ( i = 1; i < p->nDivs; i++ )
|
||||
for ( n = 0; n < 2; n++ )
|
||||
Abc_TtCopy( p->ppLits[2*i+n], Vec_WrdEntryP(pData->vSimsIn, (i-1)*pData->nSimWords), pData->nSimWords, n );
|
||||
for ( i = 0; i < (1 << p->nOuts); i++ )
|
||||
Abc_TtCopy( p->ppSets[i], Vec_WrdEntryP(pData->vSimsOut, i*pData->nSimWords), pData->nSimWords, 0 );
|
||||
if ( pData->vDivs )
|
||||
Vec_IntForEachEntry( pData->vDivs, n, i )
|
||||
Vec_IntPush( &p->vSupp, 1+n );
|
||||
if ( pData->vSol ) {
|
||||
Vec_IntForEachEntry( pData->vSol, n, i )
|
||||
Vec_IntPush( &p->vSol, n );
|
||||
Vec_IntPush( &p->vSol, Vec_IntEntryLast(&p->vSol) );
|
||||
}
|
||||
Abc_RDataStop( pData );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Res6_Man_t * Res6_ManRead( char * pFileName )
|
||||
{
|
||||
Res6_Man_t * p = NULL;
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open input file \"%s\".\n", pFileName );
|
||||
else
|
||||
{
|
||||
int i, k, nIns, nNodes, nOuts, nPats;
|
||||
char Temp[100], Buffer[100];
|
||||
char * pLine = fgets( Buffer, 100, pFile );
|
||||
if ( pLine == NULL )
|
||||
{
|
||||
printf( "Cannot read the header line of input file \"%s\".\n", pFileName );
|
||||
return NULL;
|
||||
}
|
||||
if ( 5 != sscanf(pLine, "%s %d %d %d %d", Temp, &nIns, &nNodes, &nOuts, &nPats) )
|
||||
{
|
||||
printf( "Cannot read the parameters from the header of input file \"%s\".\n", pFileName );
|
||||
return NULL;
|
||||
}
|
||||
p = Res6_ManStart( nIns, nNodes, nOuts, nPats );
|
||||
pLine = ABC_ALLOC( char, nPats + 100 );
|
||||
for ( i = 1; i < p->nDivs; i++ )
|
||||
{
|
||||
char * pNext = fgets( pLine, nPats + 100, pFile );
|
||||
if ( pNext == NULL )
|
||||
{
|
||||
printf( "Cannot read line %d of input file \"%s\".\n", i, pFileName );
|
||||
Res6_ManStop( p );
|
||||
ABC_FREE( pLine );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
for ( k = 0; k < p->nPats; k++ )
|
||||
if ( pNext[k] == '0' )
|
||||
Abc_TtSetBit( p->ppLits[2*i+1], k );
|
||||
else if ( pNext[k] == '1' )
|
||||
Abc_TtSetBit( p->ppLits[2*i], k );
|
||||
}
|
||||
for ( i = 0; i < (1 << p->nOuts); i++ )
|
||||
{
|
||||
char * pNext = fgets( pLine, nPats + 100, pFile );
|
||||
if ( pNext == NULL )
|
||||
{
|
||||
printf( "Cannot read line %d of input file \"%s\".\n", i, pFileName );
|
||||
Res6_ManStop( p );
|
||||
ABC_FREE( pLine );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
for ( k = 0; k < p->nPats; k++ )
|
||||
if ( pNext[k] == '1' )
|
||||
Abc_TtSetBit( p->ppSets[i], k );
|
||||
}
|
||||
ABC_FREE( pLine );
|
||||
fclose( pFile );
|
||||
}
|
||||
return p;
|
||||
}
|
||||
void Res6_ManWrite( char * pFileName, Res6_Man_t * p )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open output file \"%s\".\n", pFileName );
|
||||
else
|
||||
{
|
||||
int i, k;
|
||||
fprintf( pFile, "resyn %d %d %d %d\n", p->nIns, p->nDivs - p->nIns - 1, p->nOuts, p->nPats );
|
||||
for ( i = 1; i < p->nDivs; i++, fputc('\n', pFile) )
|
||||
for ( k = 0; k < p->nPats; k++ )
|
||||
if ( Abc_TtGetBit(p->ppLits[2*i+1], k) )
|
||||
fputc( '0', pFile );
|
||||
else if ( Abc_TtGetBit(p->ppLits[2*i], k) )
|
||||
fputc( '1', pFile );
|
||||
else
|
||||
fputc( '-', pFile );
|
||||
for ( i = 0; i < (1 << p->nOuts); i++, fputc('\n', pFile) )
|
||||
for ( k = 0; k < p->nPats; k++ )
|
||||
fputc( '0' + Abc_TtGetBit(p->ppSets[i], k), pFile );
|
||||
fclose( pFile );
|
||||
}
|
||||
}
|
||||
void Res6_ManPrintProblem( Res6_Man_t * p, int fVerbose )
|
||||
{
|
||||
int i, nInputs = (p->nIns && p->nIns < 6) ? p->nIns : 6;
|
||||
printf( "Problem: In = %d Div = %d Out = %d Pat = %d\n", p->nIns, p->nDivs - p->nIns - 1, p->nOuts, p->nPats );
|
||||
if ( !fVerbose )
|
||||
return;
|
||||
printf( "%02d : %s\n", 0, "const0" );
|
||||
printf( "%02d : %s\n", 1, "const1" );
|
||||
for ( i = 1; i < p->nDivs; i++ )
|
||||
{
|
||||
if ( nInputs < 6 )
|
||||
{
|
||||
*p->ppLits[2*i+0] = Abc_Tt6Stretch( *p->ppLits[2*i+0], nInputs );
|
||||
*p->ppLits[2*i+1] = Abc_Tt6Stretch( *p->ppLits[2*i+1], nInputs );
|
||||
}
|
||||
printf("%02d : ", 2*i+0), Dau_DsdPrintFromTruth2(p->ppLits[2*i+0], nInputs), printf( "\n" );
|
||||
printf("%02d : ", 2*i+1), Dau_DsdPrintFromTruth2(p->ppLits[2*i+1], nInputs), printf( "\n" );
|
||||
}
|
||||
for ( i = 0; i < (1 << p->nOuts); i++ )
|
||||
{
|
||||
if ( nInputs < 6 )
|
||||
*p->ppSets[i] = Abc_Tt6Stretch( *p->ppSets[i], nInputs );
|
||||
printf("%02d : ", i), Dau_DsdPrintFromTruth2(p->ppSets[i], nInputs), printf( "\n" );
|
||||
}
|
||||
}
|
||||
static inline Vec_Int_t * Res6_ManReadSol( char * pFileName )
|
||||
{
|
||||
Vec_Int_t * vRes = NULL; int Num;
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open input file \"%s\".\n", pFileName );
|
||||
else
|
||||
{
|
||||
while ( fgetc(pFile) != '\n' );
|
||||
vRes = Vec_IntAlloc( 10 );
|
||||
while ( fscanf(pFile, "%d", &Num) == 1 )
|
||||
Vec_IntPush( vRes, Num );
|
||||
fclose ( pFile );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
static inline void Res6_ManWriteSol( char * pFileName, Vec_Int_t * p )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open output file \"%s\".\n", pFileName );
|
||||
else
|
||||
{
|
||||
int i, iLit;
|
||||
Vec_IntForEachEntry( p, iLit, i )
|
||||
fprintf( pFile, "%d ", iLit );
|
||||
fclose ( pFile );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Res6_LitSign( int iLit )
|
||||
{
|
||||
return Abc_LitIsCompl(iLit) ? '~' : ' ';
|
||||
}
|
||||
static inline int Res6_LitChar( int iLit, int nDivs )
|
||||
{
|
||||
return Abc_Lit2Var(iLit) < nDivs ? (nDivs < 28 ? 'a'+Abc_Lit2Var(iLit)-1 : 'd') : 'x';
|
||||
}
|
||||
static inline void Res6_LitPrint( int iLit, int nDivs )
|
||||
{
|
||||
if ( iLit < 2 )
|
||||
printf( "%d", iLit );
|
||||
else
|
||||
{
|
||||
printf( "%c%c", Res6_LitSign(iLit), Res6_LitChar(iLit, nDivs) );
|
||||
if ( Abc_Lit2Var(iLit) >= nDivs || nDivs >= 28 )
|
||||
printf( "%d", Abc_Lit2Var(iLit) );
|
||||
}
|
||||
}
|
||||
Vec_Int_t * Res6_FindSupport( Vec_Int_t * vSol, int nDivs )
|
||||
{
|
||||
int i, iLit;
|
||||
Vec_Int_t * vSupp = Vec_IntAlloc( 10 );
|
||||
Vec_IntForEachEntry( vSol, iLit, i )
|
||||
if ( iLit >= 2 && iLit < 2*nDivs )
|
||||
Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) );
|
||||
return vSupp;
|
||||
}
|
||||
void Res6_PrintSuppSims( Vec_Int_t * vSol, word ** ppLits, int nWords, int nDivs )
|
||||
{
|
||||
Vec_Int_t * vSupp = Res6_FindSupport( vSol, nDivs );
|
||||
int i, k, iObj;
|
||||
Vec_IntForEachEntry( vSupp, iObj, i )
|
||||
{
|
||||
for ( k = 0; k < 64*nWords; k++ )
|
||||
if ( Abc_TtGetBit(ppLits[2*iObj+1], k) )
|
||||
printf( "0" );
|
||||
else if ( Abc_TtGetBit(ppLits[2*iObj], k) )
|
||||
printf( "1" );
|
||||
else
|
||||
printf( "-" );
|
||||
printf( "\n" );
|
||||
}
|
||||
for ( k = 0; k < 64*nWords; k++ )
|
||||
{
|
||||
Vec_IntForEachEntry( vSupp, iObj, i )
|
||||
if ( Abc_TtGetBit(ppLits[2*iObj+1], k) )
|
||||
printf( "0" );
|
||||
else if ( Abc_TtGetBit(ppLits[2*iObj+0], k) )
|
||||
printf( "1" );
|
||||
else
|
||||
printf( "-" );
|
||||
printf( "\n" );
|
||||
if ( k == 9 )
|
||||
break;
|
||||
}
|
||||
Vec_IntFree( vSupp );
|
||||
}
|
||||
int Res6_FindSupportSize( Vec_Int_t * vSol, int nDivs )
|
||||
{
|
||||
Vec_Int_t * vSupp = Res6_FindSupport( vSol, nDivs );
|
||||
int Res = Vec_IntSize(vSupp);
|
||||
Vec_IntFree( vSupp );
|
||||
return Res;
|
||||
}
|
||||
void Res6_PrintSolution( Vec_Int_t * vSol, int nDivs )
|
||||
{
|
||||
int iNode, nNodes = Vec_IntSize(vSol)/2-1;
|
||||
assert( Vec_IntSize(vSol) % 2 == 0 );
|
||||
printf( "Solution: In = %d Div = %d Node = %d Out = %d\n", Res6_FindSupportSize(vSol, nDivs), nDivs-1, nNodes, 1 );
|
||||
for ( iNode = 0; iNode <= nNodes; iNode++ )
|
||||
{
|
||||
int * pLits = Vec_IntEntryP( vSol, 2*iNode );
|
||||
printf( "x%-2d = ", nDivs + iNode );
|
||||
Res6_LitPrint( pLits[0], nDivs );
|
||||
if ( pLits[0] != pLits[1] )
|
||||
{
|
||||
printf( " %c ", pLits[0] < pLits[1] ? '&' : '^' );
|
||||
Res6_LitPrint( pLits[1], nDivs );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
int Res6_FindGetCost( Res6_Man_t * p, int iDiv )
|
||||
{
|
||||
int w, Cost = 0;
|
||||
//printf( "DivLit = %d\n", iDiv );
|
||||
//Abc_TtPrintBinary1( stdout, p->ppLits[iDiv], p->nIns ); printf( "\n" );
|
||||
//printf( "Set0\n" );
|
||||
//Abc_TtPrintBinary1( stdout, p->ppSets[0], p->nIns ); printf( "\n" );
|
||||
//printf( "Set1\n" );
|
||||
//Abc_TtPrintBinary1( stdout, p->ppSets[1], p->nIns ); printf( "\n" );
|
||||
for ( w = 0; w < p->nWords; w++ )
|
||||
Cost += Abc_TtCountOnes( (p->ppLits[iDiv][w] & p->ppSets[0][w]) | (p->ppLits[iDiv^1][w] & p->ppSets[1][w]) );
|
||||
return Cost;
|
||||
}
|
||||
int Res6_FindBestDiv( Res6_Man_t * p, int * pCost )
|
||||
{
|
||||
int d, dBest = -1, CostBest = ABC_INFINITY;
|
||||
for ( d = 0; d < 2*p->nDivs; d++ )
|
||||
{
|
||||
int Cost = Res6_FindGetCost( p, d );
|
||||
printf( "Div = %d Cost = %d\n", d, Cost );
|
||||
if ( CostBest >= Cost )
|
||||
CostBest = Cost, dBest = d;
|
||||
}
|
||||
if ( pCost )
|
||||
*pCost = CostBest;
|
||||
return dBest;
|
||||
}
|
||||
int Res6_FindBestEval( Res6_Man_t * p, Vec_Int_t * vSol, int Start )
|
||||
{
|
||||
int i, iLit0, iLit1;
|
||||
assert( Vec_IntSize(vSol) % 2 == 0 );
|
||||
Vec_IntForEachEntryDoubleStart( vSol, iLit0, iLit1, i, 2*Start )
|
||||
{
|
||||
if ( iLit0 > iLit1 )
|
||||
{
|
||||
Abc_TtXor( p->ppLits[2*p->nDivs+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 );
|
||||
Abc_TtXor( p->ppLits[2*p->nDivs+i+1], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_TtAnd( p->ppLits[2*p->nDivs+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 );
|
||||
Abc_TtOr ( p->ppLits[2*p->nDivs+i+1], p->ppLits[iLit0^1], p->ppLits[iLit1^1], p->nWords );
|
||||
}
|
||||
|
||||
//printf( "Node %d\n", i/2 );
|
||||
//Abc_TtPrintBinary1( stdout, p->ppLits[2*p->nDivs+i+0], 6 ); printf( "\n" );
|
||||
//Abc_TtPrintBinary1( stdout, p->ppLits[2*p->nDivs+i+1], 6 ); printf( "\n" );
|
||||
}
|
||||
return Res6_FindGetCost( p, Vec_IntEntryLast(vSol) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Res6_ManResubVerify( Res6_Man_t * p, Vec_Int_t * vSol )
|
||||
{
|
||||
int Cost = Res6_FindBestEval( p, vSol, 0 );
|
||||
if ( Cost == 0 )
|
||||
printf( "Verification successful.\n" );
|
||||
else
|
||||
printf( "Verification FAILED with %d errors on %d patterns.\n", Cost, p->nPats );
|
||||
}
|
||||
void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose )
|
||||
{
|
||||
char FileNameSol[1000];
|
||||
if ( pFileNameSol )
|
||||
strcpy( FileNameSol, pFileNameSol );
|
||||
else
|
||||
{
|
||||
strcpy( FileNameSol, pFileNameRes );
|
||||
strcpy( FileNameSol + strlen(FileNameSol) - strlen(".resub"), ".sol" );
|
||||
}
|
||||
{
|
||||
Res6_Man_t * p = Res6_ManRead( pFileNameRes );
|
||||
Vec_Int_t * vSol = Res6_ManReadSol( FileNameSol );
|
||||
//Vec_IntPrint( vSol );
|
||||
if ( p == NULL || vSol == NULL )
|
||||
return;
|
||||
if ( fVerbose )
|
||||
Res6_ManPrintProblem( p, 0 );
|
||||
if ( fVerbose )
|
||||
Res6_PrintSolution( vSol, p->nDivs );
|
||||
//if ( fVerbose )
|
||||
// Res6_PrintSuppSims( vSol, p->ppLits, p->nWords, p->nDivs );
|
||||
Res6_ManResubVerify( p, vSol );
|
||||
Vec_IntFree( vSol );
|
||||
Res6_ManStop( p );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Res6_FindBestEvalPla( Res6_Man_t * p, Vec_Int_t * vSol )
|
||||
{
|
||||
int i, n, iObj, iLit0, iLit1, iOffset = 2*(1+Vec_IntSize(&p->vSupp));
|
||||
assert( Vec_IntSize(vSol) % 2 == 0 );
|
||||
Vec_IntForEachEntry( &p->vSupp, iObj, i )
|
||||
for ( n = 0; n < 2; n++ )
|
||||
Abc_TtCopy( p->ppLits[2*(1+i)+n], p->ppLits[2*iObj+n], p->nWords, 0 );
|
||||
Vec_IntForEachEntryDouble( vSol, iLit0, iLit1, i )
|
||||
{
|
||||
if ( iLit0 > iLit1 )
|
||||
{
|
||||
Abc_TtXor( p->ppLits[iOffset+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 );
|
||||
Abc_TtXor( p->ppLits[iOffset+i+1], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_TtAnd( p->ppLits[iOffset+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 );
|
||||
Abc_TtOr ( p->ppLits[iOffset+i+1], p->ppLits[iLit0^1], p->ppLits[iLit1^1], p->nWords );
|
||||
}
|
||||
}
|
||||
return Res6_FindGetCost( p, Vec_IntEntryLast(vSol) );
|
||||
}
|
||||
void Res6_ManResubVerifyPla( Res6_Man_t * p, Vec_Int_t * vSol )
|
||||
{
|
||||
int Cost = Res6_FindBestEvalPla( p, vSol );
|
||||
if ( Cost == 0 )
|
||||
printf( "Verification successful.\n" );
|
||||
else
|
||||
printf( "Verification FAILED with %d errors on %d patterns.\n", Cost, p->nPats );
|
||||
}
|
||||
void Res6_PrintSolutionPla( Vec_Int_t * vSol, int nSuppSize, int nDivs )
|
||||
{
|
||||
int iNode, nNodes = Vec_IntSize(vSol)/2-1;
|
||||
assert( Vec_IntSize(vSol) % 2 == 0 );
|
||||
printf( "Solution: In = %d Div = %d Node = %d Out = %d\n", nSuppSize, nDivs-1, nNodes, 1 );
|
||||
for ( iNode = 0; iNode <= nNodes; iNode++ )
|
||||
{
|
||||
int * pLits = Vec_IntEntryP( vSol, 2*iNode );
|
||||
printf( "x%-2d = ", 1+nSuppSize+iNode );
|
||||
Res6_LitPrint( pLits[0], 1+nSuppSize );
|
||||
if ( pLits[0] != pLits[1] )
|
||||
{
|
||||
printf( " %c ", pLits[0] < pLits[1] ? '&' : '^' );
|
||||
Res6_LitPrint( pLits[1], 1+nSuppSize );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
void Res6_ManResubCheckPla( char * pFileName, int fVerbose )
|
||||
{
|
||||
Res6_Man_t * p = Res6_ManReadPla( pFileName );
|
||||
if ( p == NULL ) return;
|
||||
//Vec_IntPrint( &p->vSupp );
|
||||
//Vec_IntPrint( &p->vSol );
|
||||
if ( fVerbose )
|
||||
Res6_ManPrintProblem( p, 0 );
|
||||
if ( fVerbose )
|
||||
Res6_PrintSolutionPla( &p->vSol, Vec_IntSize(&p->vSupp), p->nDivs );
|
||||
//if ( fVerbose )
|
||||
// Res6_PrintSuppSims( vSol, p->ppLits, p->nWords, p->nDivs );
|
||||
Res6_ManResubVerifyPla( p, &p->vSol );
|
||||
Res6_ManStop( p );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#include "aig/gia/gia.h"
|
||||
|
||||
#include "opt/rrr/rrr.h"
|
||||
#include "opt/rrr/rrrAbc.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
Gia_Man_t *Gia_ManRrr(Gia_Man_t *pGia, int iSeed, int nWords, int nTimeout, int nSchedulerVerbose, int nPartitionerVerbose, int nOptimizerVerbose, int nAnalyzerVerbose, int nSimulatorVerbose, int nSatSolverVerbose, int fUseBddCspf, int fUseBddMspf, int nConflictLimit, int nSortType, int nOptimizerFlow, int nSchedulerFlow, int nPartitionType, int nDistance, int nJobs, int nThreads, int nPartitionSize, int nPartitionSizeMin, int fDeterministic, int nParallelPartitions, int fOptOnInsert, int fGreedy) {
|
||||
rrr::AndNetwork ntk;
|
||||
ntk.Read(pGia, rrr::GiaReader<rrr::AndNetwork>);
|
||||
rrr::Parameter Par;
|
||||
Par.iSeed = iSeed;
|
||||
Par.nWords = nWords;
|
||||
Par.nTimeout = nTimeout;
|
||||
Par.nSchedulerVerbose = nSchedulerVerbose;
|
||||
Par.nPartitionerVerbose = nPartitionerVerbose;
|
||||
Par.nOptimizerVerbose = nOptimizerVerbose;
|
||||
Par.nAnalyzerVerbose = nAnalyzerVerbose;
|
||||
Par.nSimulatorVerbose = nSimulatorVerbose;
|
||||
Par.nSatSolverVerbose = nSatSolverVerbose;
|
||||
Par.fUseBddCspf = fUseBddCspf;
|
||||
Par.fUseBddMspf = fUseBddMspf;
|
||||
Par.nConflictLimit = nConflictLimit;
|
||||
Par.nSortType = nSortType;
|
||||
Par.nOptimizerFlow = nOptimizerFlow;
|
||||
Par.nSchedulerFlow = nSchedulerFlow;
|
||||
Par.nPartitionType = nPartitionType;
|
||||
Par.nDistance = nDistance;
|
||||
Par.nJobs = nJobs;
|
||||
Par.nThreads = nThreads;
|
||||
Par.nPartitionSize = nPartitionSize;
|
||||
Par.nPartitionSizeMin = nPartitionSizeMin;
|
||||
Par.fDeterministic = fDeterministic;
|
||||
Par.nParallelPartitions = nParallelPartitions;
|
||||
Par.fOptOnInsert = fOptOnInsert;
|
||||
Par.fGreedy = fGreedy;
|
||||
rrr::Perform(&ntk, &Par);
|
||||
Gia_Man_t *pNew = rrr::CreateGia(&ntk, false);
|
||||
return pNew;
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -20,11 +20,18 @@
|
|||
|
||||
#include "gia.h"
|
||||
#include "misc/tim/tim.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "sat/bsat/satStore.h"
|
||||
#include "misc/util/utilNam.h"
|
||||
#include "map/scl/sclCon.h"
|
||||
#include "misc/vec/vecHsh.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define unlink _unlink
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
|
|
@ -632,7 +639,9 @@ static inline int Sbl_CutIsFeasible( word CutI1, word CutI2, word CutN1, word Cu
|
|||
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
|
||||
if ( LutSize <= 4 )
|
||||
return Count <= 4;
|
||||
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
|
||||
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
|
||||
if ( LutSize <= 5 )
|
||||
return Count <= 5;
|
||||
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
|
||||
return Count <= 6;
|
||||
}
|
||||
|
|
@ -1026,7 +1035,7 @@ int Sbl_ManTestSat( Sbl_Man_t * p, int iPivot )
|
|||
|
||||
StartSol = Vec_IntSize(p->vSolInit) + 1;
|
||||
// StartSol = 30;
|
||||
while ( fKeepTrying && StartSol-fKeepTrying > 0 )
|
||||
while ( fKeepTrying && StartSol-fKeepTrying > 0 && StartSol-fKeepTrying < Vec_IntSize(p->vCardVars) )
|
||||
{
|
||||
int Count = 0, LitCount = 0;
|
||||
int nConfBef, nConfAft;
|
||||
|
|
@ -1216,6 +1225,864 @@ void Gia_ManLutSat( Gia_Man_t * pGia, int LutSize, int nNumber, int nImproves, i
|
|||
Vec_IntFreeP( &pGia->vPacking );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_RunKadical( char * pFileNameIn, char * pFileNameOut, int Seed, int nBTLimit, int TimeOut, int fVerbose, int * pStatus )
|
||||
{
|
||||
extern Vec_Int_t * Exa4_ManParse( char *pFileName );
|
||||
int fVerboseSolver = 0;
|
||||
abctime clkTotal = Abc_Clock();
|
||||
Vec_Int_t * vRes = NULL;
|
||||
#ifdef _WIN32
|
||||
char * pKadical = "kadical.exe";
|
||||
#else
|
||||
char * pKadical = "./kadical";
|
||||
FILE * pFile = fopen( pKadical, "rb" );
|
||||
if ( pFile == NULL )
|
||||
pKadical += 2;
|
||||
else
|
||||
fclose( pFile );
|
||||
#endif
|
||||
char Command[1000], * pCommand = (char *)&Command;
|
||||
if ( nBTLimit ) {
|
||||
if ( TimeOut )
|
||||
sprintf( pCommand, "%s --seed=%d -c %d -t %d %s %s > %s", pKadical, Seed, nBTLimit, TimeOut, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
|
||||
else
|
||||
sprintf( pCommand, "%s --seed=%d -c %d %s %s > %s", pKadical, Seed, nBTLimit, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
|
||||
}
|
||||
else {
|
||||
if ( TimeOut )
|
||||
sprintf( pCommand, "%s --seed=%d -t %d %s %s > %s", pKadical, Seed, TimeOut, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
|
||||
else
|
||||
sprintf( pCommand, "%s --seed=%d %s %s > %s", pKadical, Seed, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
|
||||
}
|
||||
#ifdef __wasm
|
||||
if ( 1 )
|
||||
#else
|
||||
if ( system( pCommand ) == -1 )
|
||||
#endif
|
||||
{
|
||||
fprintf( stdout, "Command \"%s\" did not succeed.\n", pCommand );
|
||||
return 0;
|
||||
}
|
||||
vRes = Exa4_ManParse( pFileNameOut );
|
||||
if ( fVerbose )
|
||||
{
|
||||
if ( vRes )
|
||||
printf( "The problem has a solution. " ), *pStatus = 0;
|
||||
else if ( vRes == NULL && TimeOut == 0 )
|
||||
printf( "The problem has no solution. " ), *pStatus = 1;
|
||||
else if ( vRes == NULL )
|
||||
printf( "The problem has no solution or reached a resource limit after %d sec. ", TimeOut ), *pStatus = -1;
|
||||
Abc_PrintTime( 1, "SAT solver time", Abc_Clock() - clkTotal );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_SatVarReqPos( int i ) { return i*7+0; } // p
|
||||
int Gia_SatVarReqNeg( int i ) { return i*7+1; } // n
|
||||
int Gia_SatVarAckPos( int i ) { return i*7+2; } // P
|
||||
int Gia_SatVarAckNeg( int i ) { return i*7+3; } // N
|
||||
int Gia_SatVarInv ( int i ) { return i*7+4; } // i
|
||||
int Gia_SatVarFan0 ( int i ) { return i*7+5; } // 0
|
||||
int Gia_SatVarFan1 ( int i ) { return i*7+6; } // 1
|
||||
|
||||
int Gia_SatValReqPos( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+0); } // p
|
||||
int Gia_SatValReqNeg( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+1); } // n
|
||||
int Gia_SatValAckPos( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+2); } // P
|
||||
int Gia_SatValAckNeg( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+3); } // N
|
||||
int Gia_SatValInv ( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+4); } // i
|
||||
int Gia_SatValFan0 ( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+5); } // 0
|
||||
int Gia_SatValFan1 ( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+6); } // 1
|
||||
|
||||
void Gia_SatDumpClause( Vec_Str_t * vStr, int * pLits, int nLits )
|
||||
{
|
||||
for ( int i = 0; i < nLits; i++ )
|
||||
Vec_StrPrintF( vStr, "%d ", Abc_LitIsCompl(pLits[i]) ? -Abc_Lit2Var(pLits[i])-1 : Abc_Lit2Var(pLits[i])+1 );
|
||||
Vec_StrPrintF( vStr, "0\n" );
|
||||
}
|
||||
void Gia_SatDumpLiteral( Vec_Str_t * vStr, int Lit )
|
||||
{
|
||||
Gia_SatDumpClause( vStr, &Lit, 1 );
|
||||
}
|
||||
void Gia_SatDumpKlause( Vec_Str_t * vStr, int nIns, int nAnds, int nBound )
|
||||
{
|
||||
int i, nVars = nIns + 7*nAnds;
|
||||
Vec_StrPrintF( vStr, "k %d ", nVars - nBound );
|
||||
// counting primary inputs: n
|
||||
for ( i = 0; i < nIns; i++ )
|
||||
Vec_StrPrintF( vStr, "-%d ", Gia_SatVarReqNeg(1+i)+1 );
|
||||
// counting internal nodes: p, n, P, N, i, 0, 1
|
||||
for ( i = 0; i < 7*nAnds; i++ )
|
||||
Vec_StrPrintF( vStr, "-%d ", (1+nIns)*7+i+1 );
|
||||
Vec_StrPrintF( vStr, "0\n" );
|
||||
}
|
||||
|
||||
Vec_Str_t * Gia_ManSimpleCnf( Gia_Man_t * p, int nBound )
|
||||
{
|
||||
Vec_Str_t * vStr = Vec_StrAlloc( 10000 );
|
||||
Gia_SatDumpKlause( vStr, Gia_ManCiNum(p), Gia_ManAndNum(p), nBound );
|
||||
int i, n, m, Id, pLits[4]; Gia_Obj_t * pObj;
|
||||
for ( n = 0; n < 7; n++ )
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit(n, 1) );
|
||||
// acknowledge positive PI literals
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
for ( n = 0; n < 7; n++ ) if ( n != 1 )
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit(Gia_SatVarReqPos(Id)+n, n>0) );
|
||||
// require driving PO literals
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_SatVarReqPos(Gia_ObjFaninId0p(p, pObj)) + Gia_ObjFaninC0(pObj), 0 ) );
|
||||
// internal nodes
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
int fCompl[2] = { Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj) };
|
||||
int iFans[2] = { Gia_ObjFaninId0(pObj, i), Gia_ObjFaninId1(pObj, i) };
|
||||
Gia_Obj_t * pFans[2] = { Gia_ObjFanin0(pObj), Gia_ObjFanin1(pObj) };
|
||||
// require inverter: p & !n & N -> i, n & !p & P -> i
|
||||
for ( n = 0; n < 2; n++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarReqPos(i)+n, 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarReqNeg(i)-n, 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarAckNeg(i)-n, 1 );
|
||||
pLits[3] = Abc_Var2Lit( Gia_SatVarInv (i), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 4 );
|
||||
}
|
||||
// exclusive acknowledge: !P + !N
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
// required acknowledge: p -> P + N, n -> P + N
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarAckPos(i), 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 0 );
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarReqPos(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarReqNeg(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
// forbid acknowledge: !p & !n -> !P, !p & !n -> !N
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarReqPos(i), 0 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarReqNeg(i), 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarAckPos(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
// when fanins can be used: !N & !P -> !0, !N & !P -> !1
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i), 0 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarFan0(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarFan1(i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
// when fanins are not used: 0 -> !N, 0 -> !P, 1 -> !N, 1 -> !P
|
||||
for ( m = 0; m < 2; m++ )
|
||||
for ( n = 0; n < 2; n++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarFan0(i)+n, 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarReqPos(iFans[n])+m, 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
}
|
||||
// can only extend both when both complemented: !(C0 & C1) -> !0 + !1
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarFan0(i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarFan1(i), 1 );
|
||||
if ( !fCompl[0] || !fCompl[1] )
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
// if fanin is a primary input, cannot extend it (pi -> !0 or pi -> !1)
|
||||
for ( n = 0; n < 2; n++ )
|
||||
if ( Gia_ObjIsCi(pFans[n]) )
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_SatVarFan0(i)+n, 1 ) );
|
||||
// propagating assignments when fanin is not used
|
||||
// P & !0 -> C0 ? P0 : N0
|
||||
// N & !0 -> C0 ? N0 : P0
|
||||
// P & !1 -> C1 ? P1 : N1
|
||||
// N & !1 -> C1 ? N1 : P1
|
||||
for ( m = 0; m < 2; m++ )
|
||||
for ( n = 0; n < 2; n++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i)+m, 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarFan0(i)+n, 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarReqPos(iFans[n]) + !(m ^ fCompl[n]), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
}
|
||||
// propagating assignments when fanins are used
|
||||
// P & 0 -> (C0 ^ C00) ? P00 : N00
|
||||
// P & 0 -> (C0 ^ C01) ? P01 : N01
|
||||
// N & 0 -> (C0 ^ C00) ? N00 : P00
|
||||
// N & 0 -> (C0 ^ C01) ? N01 : P01
|
||||
// P & 1 -> (C1 ^ C10) ? P10 : N10
|
||||
// P & 1 -> (C1 ^ C11) ? P11 : N11
|
||||
// N & 1 -> (C1 ^ C10) ? N10 : P10
|
||||
// N & 1 -> (C1 ^ C11) ? N11 : P11
|
||||
for ( m = 0; m < 2; m++ )
|
||||
for ( n = 0; n < 2; n++ )
|
||||
if ( Gia_ObjIsAnd(pFans[n]) ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i)+m, 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_SatVarFan0(i)+n, 1 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarReqPos(Gia_ObjFaninId0p(p, pFans[n])) + !(m ^ fCompl[n] ^ Gia_ObjFaninC0(pFans[n])), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_SatVarReqPos(Gia_ObjFaninId1p(p, pFans[n])) + !(m ^ fCompl[n] ^ Gia_ObjFaninC1(pFans[n])), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
}
|
||||
}
|
||||
Vec_StrPush( vStr, '\0' );
|
||||
return vStr;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
GIA_GATE_ZERO, // 0:
|
||||
GIA_GATE_ONE, // 1:
|
||||
GIA_GATE_BUF, // 2:
|
||||
GIA_GATE_INV, // 3:
|
||||
GIA_GATE_NAN2, // 4:
|
||||
GIA_GATE_NOR2, // 5:
|
||||
GIA_GATE_AOI21, // 6:
|
||||
GIA_GATE_NAN3, // 7:
|
||||
GIA_GATE_NOR3, // 8:
|
||||
GIA_GATE_OAI21, // 9:
|
||||
GIA_GATE_AOI22, // 10:
|
||||
GIA_GATE_OAI22, // 11:
|
||||
RTM_VAL_VOID // 12: unused value
|
||||
} Gia_ManGate_t;
|
||||
|
||||
Vec_Int_t * Gia_ManDeriveSimpleMapping( Gia_Man_t * p, Vec_Int_t * vRes )
|
||||
{
|
||||
Vec_Int_t * vMapping = Vec_IntStart( 2*Gia_ManObjNum(p) );
|
||||
int i, Id; Gia_Obj_t * pObj;
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
if ( Gia_SatValReqNeg(vRes, Id) )
|
||||
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(Id, 1), -1 );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
if ( Gia_SatValAckPos(vRes, i) + Gia_SatValAckNeg(vRes, i) == 0 )
|
||||
continue;
|
||||
assert( Gia_SatValAckPos(vRes, i) != Gia_SatValAckNeg(vRes, i) );
|
||||
if ( (Gia_SatValReqPos(vRes, i) && Gia_SatValReqNeg(vRes, i)) || Gia_SatValInv(vRes, i) )
|
||||
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(i, Gia_SatValAckPos(vRes, i)), -1 );
|
||||
int fComp = Gia_SatValAckNeg(vRes, i);
|
||||
int fFan0 = Gia_SatValFan0(vRes, i);
|
||||
int fFan1 = Gia_SatValFan1(vRes, i);
|
||||
Gia_Obj_t * pFans[2] = { Gia_ObjFanin0(pObj), Gia_ObjFanin1(pObj) };
|
||||
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(i, fComp), Vec_IntSize(vMapping) );
|
||||
if ( fFan0 && fFan1 ) {
|
||||
assert( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) );
|
||||
Vec_IntPush( vMapping, 4 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_OAI22 : GIA_GATE_AOI22 );
|
||||
} else if ( fFan0 ) {
|
||||
Vec_IntPush( vMapping, 3 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pObj), !(fComp ^ Gia_ObjFaninC1(pObj))) );
|
||||
if ( Gia_ObjFaninC0(pObj) )
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_OAI21 : GIA_GATE_AOI21 );
|
||||
else
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_NAN3 : GIA_GATE_NOR3 );
|
||||
} else if ( fFan1 ) {
|
||||
Vec_IntPush( vMapping, 3 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pObj), !(fComp ^ Gia_ObjFaninC0(pObj))) );
|
||||
if ( Gia_ObjFaninC1(pObj) )
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_OAI21 : GIA_GATE_AOI21 );
|
||||
else
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_NAN3 : GIA_GATE_NOR3 );
|
||||
} else {
|
||||
Vec_IntPush( vMapping, 2 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pObj), !(fComp ^ Gia_ObjFaninC0(pObj))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pObj), !(fComp ^ Gia_ObjFaninC1(pObj))) );
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE_NAN2 : GIA_GATE_NOR2 );
|
||||
}
|
||||
}
|
||||
return vMapping;
|
||||
}
|
||||
void Gia_ManSimplePrintMapping( Vec_Int_t * vRes, int nIns )
|
||||
{
|
||||
int i, k, nObjs = Vec_IntSize(vRes)/7, nSteps = Abc_Base10Log(nObjs);
|
||||
int nCard = Vec_IntSum(vRes) - nIns; char NumStr[10];
|
||||
printf( "Solution with cardinality %d:\n", nCard );
|
||||
for ( k = 0; k < nSteps; k++ ) {
|
||||
printf( " " );
|
||||
for ( i = 0; i < nObjs; i++ ) {
|
||||
sprintf( NumStr, "%02d", i );
|
||||
printf( "%c", NumStr[k] );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
for ( k = 0; k < 7; k++ ) {
|
||||
printf( "%c ", "pnPNi01"[k] );
|
||||
for ( i = 0; i < nObjs; i++ )
|
||||
if ( Vec_IntEntry( vRes, i*7+k ) == 0 )
|
||||
printf( " " );
|
||||
else
|
||||
printf( "1" );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
int Gia_ManDumpCnf( char * pFileName, Vec_Str_t * vStr, int nVars )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL ) { printf( "Cannot open input file \"%s\".\n", pFileName ); return 0; }
|
||||
fprintf( pFile, "p knf %d %d\n%s\n", nVars, Vec_StrCountEntry(vStr, '\n'), Vec_StrArray(vStr) );
|
||||
fclose( pFile );
|
||||
return 1;
|
||||
}
|
||||
int Gia_ManDumpCnf2( Vec_Str_t * vStr, int nVars, int argc, char ** argv, abctime Time, int Status )
|
||||
{
|
||||
Vec_Str_t * vFileName = Vec_StrAlloc( 100 ); int c;
|
||||
Vec_StrPrintF( vFileName, "%s", argv[0] + (argv[0][0] == '&') );
|
||||
for ( c = 1; c < argc; c++ )
|
||||
Vec_StrPrintF( vFileName, "_%s", argv[c] + (argv[c][0] == '-') );
|
||||
Vec_StrPrintF( vFileName, ".cnf" );
|
||||
Vec_StrPush( vFileName, '\0' );
|
||||
FILE * pFile = fopen( Vec_StrArray(vFileName), "wb" );
|
||||
if ( pFile == NULL ) { printf( "Cannot open output file \"%s\".\n", Vec_StrArray(vFileName) ); Vec_StrFree(vFileName); return 0; }
|
||||
Vec_StrFree(vFileName);
|
||||
fprintf( pFile, "c This file was generated by ABC command: \"" );
|
||||
fprintf( pFile, "%s", argv[0] );
|
||||
for ( c = 1; c < argc; c++ )
|
||||
fprintf( pFile, " %s", argv[c] );
|
||||
fprintf( pFile, "\" on %s\n", Gia_TimeStamp() );
|
||||
fprintf( pFile, "c Cardinality CDCL (https://github.com/jreeves3/Cardinality-CDCL) found it to be " );
|
||||
if ( Status == 1 )
|
||||
fprintf( pFile, "UNSAT" );
|
||||
if ( Status == 0 )
|
||||
fprintf( pFile, "SAT" );
|
||||
if ( Status == -1 )
|
||||
fprintf( pFile, "UNDECIDED" );
|
||||
fprintf( pFile, " in %.2f sec\n", 1.0*((double)(Time))/((double)CLOCKS_PER_SEC) );
|
||||
fprintf( pFile, "p knf %d %d\n%s\n", nVars, Vec_StrCountEntry(vStr, '\n'), Vec_StrArray(vStr) );
|
||||
fclose( pFile );
|
||||
return 1;
|
||||
}
|
||||
int Gia_ManSimpleMapping( Gia_Man_t * p, int nBound, int Seed, int nBTLimit, int nTimeout, int fVerbose, int fKeepFile, int argc, char ** argv )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
srand(time(NULL));
|
||||
int Status, Rand = ((((unsigned)rand()) << 12) ^ ((unsigned)rand())) & 0xFFFFFF;
|
||||
char pFileNameI[32]; sprintf( pFileNameI, "_%06x_.cnf", Rand );
|
||||
char pFileNameO[32]; sprintf( pFileNameO, "_%06x_.out", Rand );
|
||||
if ( nBound == 0 )
|
||||
nBound = 5 * Gia_ManAndNum(p);
|
||||
Vec_Str_t * vStr = Gia_ManSimpleCnf( p, nBound/2 );
|
||||
int nVars = 7*(Gia_ManObjNum(p)-Gia_ManCoNum(p));
|
||||
if ( !Gia_ManDumpCnf(pFileNameI, vStr, nVars) ) {
|
||||
Vec_StrFree( vStr );
|
||||
return 0;
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "SAT variables = %d. SAT clauses = %d. Cardinality bound = %d. Conflict limit = %d. Timeout = %d.\n",
|
||||
nVars, Vec_StrCountEntry(vStr, '\n'), nBound, nBTLimit, nTimeout );
|
||||
Vec_Int_t * vRes = Gia_RunKadical( pFileNameI, pFileNameO, Seed, nBTLimit, nTimeout, fVerbose, &Status );
|
||||
unlink( pFileNameI );
|
||||
//unlink( pFileNameO );
|
||||
if ( fKeepFile ) Gia_ManDumpCnf2( vStr, nVars, argc, argv, Abc_Clock() - clkStart, Status );
|
||||
Vec_StrFree( vStr );
|
||||
if ( vRes == NULL )
|
||||
return 0;
|
||||
Vec_IntFreeP( &p->vCellMapping );
|
||||
assert( p->vCellMapping == NULL );
|
||||
Vec_IntDrop( vRes, 0 );
|
||||
if ( fVerbose ) Gia_ManSimplePrintMapping( vRes, Gia_ManCiNum(p) );
|
||||
p->vCellMapping = Gia_ManDeriveSimpleMapping( p, vRes );
|
||||
Vec_IntFree( vRes );
|
||||
if ( fVerbose ) Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#define KSAT_OBJS 24
|
||||
#define KSAT_MINTS 64
|
||||
#define KSAT_SPACE (4+3*KSAT_OBJS+3*KSAT_MINTS)
|
||||
|
||||
int Gia_KSatVarInv( int * pMap, int i ) { return pMap[i*KSAT_SPACE+0]; }
|
||||
int Gia_KSatVarAnd( int * pMap, int i ) { return pMap[i*KSAT_SPACE+1]; }
|
||||
int Gia_KSatVarEqu( int * pMap, int i ) { return pMap[i*KSAT_SPACE+2]; }
|
||||
int Gia_KSatVarRef( int * pMap, int i ) { return pMap[i*KSAT_SPACE+3]; }
|
||||
int Gia_KSatVarFan( int * pMap, int i, int f, int k ) { return pMap[i*KSAT_SPACE+4+f*KSAT_OBJS+k]; }
|
||||
int Gia_KSatVarMin( int * pMap, int i, int m, int k ) { return pMap[i*KSAT_SPACE+4+3*KSAT_OBJS+3*m+k]; }
|
||||
|
||||
void Gia_KSatSetInv( int * pMap, int i, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+0] ); pMap[i*KSAT_SPACE+0] = iVar; }
|
||||
void Gia_KSatSetAnd( int * pMap, int i, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+1] ); pMap[i*KSAT_SPACE+1] = iVar; }
|
||||
void Gia_KSatSetEqu( int * pMap, int i, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+2] ); pMap[i*KSAT_SPACE+2] = iVar; }
|
||||
void Gia_KSatSetRef( int * pMap, int i, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+3] ); pMap[i*KSAT_SPACE+3] = iVar; }
|
||||
void Gia_KSatSetFan( int * pMap, int i, int f, int k, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+4+f*KSAT_OBJS+k] ); pMap[i*KSAT_SPACE+4+f*KSAT_OBJS+k] = iVar; }
|
||||
void Gia_KSatSetMin( int * pMap, int i, int m, int k, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+4+3*KSAT_OBJS+3*m+k] ); pMap[i*KSAT_SPACE+4+3*KSAT_OBJS+3*m+k] = iVar; }
|
||||
|
||||
int Gia_KSatValInv( int * pMap, int i, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+0] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+0] ); }
|
||||
int Gia_KSatValAnd( int * pMap, int i, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+1] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+1] ); }
|
||||
int Gia_KSatValEqu( int * pMap, int i, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+2] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+2] ); }
|
||||
int Gia_KSatValRef( int * pMap, int i, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+3] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+3] ); }
|
||||
int Gia_KSatValFan( int * pMap, int i, int f, int k, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+4+f*KSAT_OBJS+k] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+4+f*KSAT_OBJS+k] ); }
|
||||
int Gia_KSatValMin( int * pMap, int i, int m, int k, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+4+3*KSAT_OBJS+3*m+k] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+4+3*KSAT_OBJS+3*m+k] ); }
|
||||
|
||||
int * Gia_KSatMapInit( int nIns, int nNodes, word Truth, int * pnVars )
|
||||
{
|
||||
assert( nIns + nNodes <= KSAT_OBJS );
|
||||
assert( (1 << nIns) <= KSAT_MINTS );
|
||||
int n, m, f, k, nVars = 2, * pMap = ABC_FALLOC( int, KSAT_OBJS*KSAT_SPACE );
|
||||
for ( n = nIns; n < nIns+nNodes; n++ ) {
|
||||
Gia_KSatSetInv(pMap, n, nVars++);
|
||||
Gia_KSatSetAnd(pMap, n, nVars++);
|
||||
Gia_KSatSetEqu(pMap, n, nVars++);
|
||||
Gia_KSatSetRef(pMap, n, nVars++);
|
||||
}
|
||||
for ( n = nIns; n < nIns+nNodes; n++ ) {
|
||||
for ( f = 0; f < 2; f++ )
|
||||
for ( k = 0; k < n; k++ )
|
||||
Gia_KSatSetFan(pMap, n, f, k, nVars++);
|
||||
for ( k = n+1; k < nIns+nNodes; k++ )
|
||||
Gia_KSatSetFan(pMap, n, 2, k, nVars++);
|
||||
}
|
||||
for ( m = 0; m < (1<<nIns); m++ ) {
|
||||
for ( n = 0; n < nIns; n++ )
|
||||
Gia_KSatSetMin(pMap, n, m, 0, (m >> n) & 1 );
|
||||
Gia_KSatSetMin(pMap, nIns+nNodes-1, m, 0, (Truth >> m) & 1 );
|
||||
for ( n = nIns; n < nIns+nNodes; n++ )
|
||||
for ( k = 0; k < 3; k++ )
|
||||
if ( k || n < nIns+nNodes-1 )
|
||||
Gia_KSatSetMin(pMap, n, m, k, nVars++);
|
||||
|
||||
}
|
||||
if ( pnVars ) *pnVars = nVars;
|
||||
return pMap;
|
||||
}
|
||||
|
||||
int Gia_KSatFindFan( int * pMap, int i, int f, Vec_Int_t * vRes )
|
||||
{
|
||||
assert( f < 2 );
|
||||
for ( int k = 0; k < i; k++ )
|
||||
if ( Gia_KSatValFan( pMap, i, f, k, vRes ) )
|
||||
return k;
|
||||
assert( 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
Vec_Int_t * Gia_ManKSatGenLevels( char * pGuide, int nIns, int nNodes )
|
||||
{
|
||||
Vec_Int_t * vRes;
|
||||
int i, k, Count = 0;
|
||||
for ( i = 0; pGuide[i]; i++ )
|
||||
Count += pGuide[i] - '0';
|
||||
if ( Count != nNodes ) {
|
||||
printf( "Guidance %s has %d nodes while the problem has %d nodes.\n", pGuide, Count, nNodes );
|
||||
return NULL;
|
||||
}
|
||||
int FirstPrev = 0;
|
||||
int FirstThis = nIns;
|
||||
int FirstNext = FirstThis;
|
||||
vRes = Vec_IntStartFull( 2*nIns );
|
||||
for ( i = 0; pGuide[i]; i++ ) {
|
||||
FirstNext += pGuide[i] - '0';
|
||||
for ( k = FirstThis; k < FirstNext; k++ )
|
||||
Vec_IntPushTwo( vRes, FirstPrev, FirstThis );
|
||||
FirstPrev = FirstThis;
|
||||
FirstThis = FirstNext;
|
||||
}
|
||||
assert( Vec_IntSize(vRes) == 2*(nIns + nNodes) );
|
||||
Count = 0;
|
||||
//int Start, Stop;
|
||||
//Vec_IntForEachEntryDouble(vRes, Start, Stop, i)
|
||||
// printf( "%2d : Start %2d Stop %2d\n", Count++, Start, Stop );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
Vec_Str_t * Gia_ManKSatCnf( int * pMap, int nIns, int nNodes, int nBound, int fMultiLevel, char * pGuide )
|
||||
{
|
||||
Vec_Str_t * vStr = Vec_StrAlloc( 10000 );
|
||||
Vec_Int_t * vRes = pGuide ? Gia_ManKSatGenLevels( pGuide, nIns, nNodes ) : NULL;
|
||||
int i, j, m, n, f, c, a, Start, Stop, nLits = 0, pLits[256] = {0};
|
||||
Gia_SatDumpLiteral( vStr, 1 );
|
||||
Gia_SatDumpLiteral( vStr, 2 );
|
||||
if ( vRes ) {
|
||||
n = nIns;
|
||||
Vec_IntForEachEntryDoubleStart( vRes, Start, Stop, i, 2*nIns ) {
|
||||
for ( j = 0; j < Start; j++ )
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 1, j), 1 ) );
|
||||
for ( f = 0; f < 2; f++ )
|
||||
for ( j = Stop; j < n; j++ )
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, j), 1 ) );
|
||||
n++;
|
||||
}
|
||||
assert( n == nIns + nNodes );
|
||||
}
|
||||
// fanins are connected once
|
||||
for ( n = nIns; n < nIns+nNodes; n++ )
|
||||
for ( f = 0; f < 2; f++ ) {
|
||||
|
||||
nLits = 0;
|
||||
for ( i = 0; i < n; i++ )
|
||||
pLits[nLits++] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, nLits );
|
||||
/*
|
||||
for ( i = 0; i < n; i++ )
|
||||
for ( j = 0; j < i; j++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, j), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
}
|
||||
*/
|
||||
Vec_StrPrintF( vStr, "k %d ", n-1 );
|
||||
for ( i = 0; i < n; i++ )
|
||||
pLits[i] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, n );
|
||||
}
|
||||
for ( n = nIns; n < nIns+nNodes; n++ ) {
|
||||
// fanins are equal
|
||||
for ( i = 0; i < n; i++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 0, i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 1, i), 1 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_KSatVarEqu(pMap, n), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
}
|
||||
for ( i = 0; i < n; i++ )
|
||||
for ( j = i+1; j < n; j++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 0, i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 1, j), 1 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_KSatVarEqu(pMap, n), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
}
|
||||
// if fanins are equal, inv is used
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarEqu(pMap, n), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
// fanin ordering
|
||||
for ( i = 0; i < n; i++ )
|
||||
for ( j = 0; j < i; j++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 0, i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 1, j), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
}
|
||||
}
|
||||
for ( n = nIns; n < nIns+nNodes-1; n++ ) {
|
||||
// there is a fanout to the node above
|
||||
for ( i = n+1; i < nIns+nNodes; i++ ) {
|
||||
for ( f = 0; f < 2; f++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, i, f, n), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 2, i), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
}
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, i, 0, n), 0 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, i, 1, n), 0 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 2, i), 1 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
}
|
||||
// there is at least one fanout, except the last one
|
||||
nLits = 0;
|
||||
for ( i = n+1; i < nIns+nNodes; i++ )
|
||||
pLits[nLits++] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 2, i), 0 );
|
||||
assert( nLits > 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, nLits );
|
||||
}
|
||||
// there is more than one fanout, except the last one
|
||||
for ( n = nIns; n < nIns+nNodes-1; n++ ) {
|
||||
for ( i = n+1; i < nIns+nNodes; i++ )
|
||||
for ( j = i+1; j < nIns+nNodes; j++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 2, i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 2, j), 1 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_KSatVarRef(pMap, n), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
}
|
||||
// if more than one fanout, inv is used
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarRef(pMap, n), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 2 );
|
||||
// if inv is not used, its fanins' invs are used
|
||||
if ( !fMultiLevel ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), 0 );
|
||||
for ( i = nIns; i < n; i++ )
|
||||
for ( f = 0; f < 2; f++ ) {
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 1 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_KSatVarInv(pMap, i), 0 );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
// the last one always uses inverter
|
||||
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_KSatVarInv(pMap, nIns+nNodes-1), 0 ) );
|
||||
/*
|
||||
// for each minterm, for each pair of possible fanins, the node's output is determined using and/or and inv (4*N*N*M)
|
||||
for ( m = 0; m < (1 << nIns); m++ )
|
||||
for ( n = nIns; n < nIns+nNodes; n++ )
|
||||
for ( c = 0; c < 2; c++ )
|
||||
for ( a = 0; a < 2; a++ ) {
|
||||
// implications: Fan(f) & Mint(m) & !And & !Inv -> Val1
|
||||
for ( f = 0; f < 2; f++ )
|
||||
for ( i = 0; i < n; i++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarMin(pMap, i, m, 0), !a );
|
||||
pLits[2] = Abc_Var2Lit( Gia_KSatVarAnd(pMap, n), a );
|
||||
pLits[3] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), c );
|
||||
pLits[4] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 0), a^c );
|
||||
Gia_SatDumpClause( vStr, pLits, 5 );
|
||||
}
|
||||
// large clauses: Fan(0) & Fan(1) & !Mint(m) & !Mint(m) & !And & !Inv -> Val0
|
||||
for ( i = 0; i < n; i++ )
|
||||
for ( j = i; j < n; j++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 0, i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 1, j), 1 );
|
||||
pLits[2] = Abc_Var2Lit( Gia_KSatVarMin(pMap, i, m, 0), a );
|
||||
pLits[3] = Abc_Var2Lit( Gia_KSatVarMin(pMap, j, m, 0), a );
|
||||
pLits[4] = Abc_Var2Lit( Gia_KSatVarAnd(pMap, n), a );
|
||||
pLits[5] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), c );
|
||||
pLits[6] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 0), a==c );
|
||||
Gia_SatDumpClause( vStr, pLits, 7 );
|
||||
}
|
||||
}
|
||||
*/
|
||||
// for each minterm, define a fanin variable and use it to get the node's output based on and/or and inv (4*N*N*M)
|
||||
for ( m = 0; m < (1 << nIns); m++ )
|
||||
for ( n = nIns; n < nIns+nNodes; n++ ) {
|
||||
for ( i = 0; i < n; i++ )
|
||||
for ( f = 0; f < 2; f++ )
|
||||
for ( c = 0; c < 2; c++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 1 );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarMin(pMap, i, m, 0), c );
|
||||
pLits[2] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 1+f), !c );
|
||||
Gia_SatDumpClause( vStr, pLits, 3 );
|
||||
}
|
||||
for ( c = 0; c < 2; c++ )
|
||||
for ( a = 0; a < 2; a++ ) {
|
||||
// implications: Mint(m,f) & !And & !Inv -> Val1
|
||||
for ( f = 0; f < 2; f++ ) {
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 1+f), !a );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarAnd(pMap, n), a );
|
||||
pLits[2] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), c );
|
||||
pLits[3] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 0), a^c );
|
||||
Gia_SatDumpClause( vStr, pLits, 4 );
|
||||
}
|
||||
// large clauses: !Mint(m,0) & !Mint(m,1) & !And & !Inv -> Val0
|
||||
pLits[0] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 1), a );
|
||||
pLits[1] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 2), a );
|
||||
pLits[2] = Abc_Var2Lit( Gia_KSatVarAnd(pMap, n), a );
|
||||
pLits[3] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), c );
|
||||
pLits[4] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 0), a==c );
|
||||
Gia_SatDumpClause( vStr, pLits, 5 );
|
||||
}
|
||||
}
|
||||
// the number of nodes with duplicated fanins and without inv is maximized
|
||||
if ( nBound && 2*nNodes > nBound ) {
|
||||
Vec_StrPrintF( vStr, "k %d ", 2*nNodes-nBound );
|
||||
nLits = 0;
|
||||
for ( n = nIns; n < nIns+nNodes; n++ ) {
|
||||
pLits[nLits++] = Abc_Var2Lit(Gia_KSatVarEqu(pMap, n), 0);
|
||||
pLits[nLits++] = Abc_Var2Lit(Gia_KSatVarInv(pMap, n), 1);
|
||||
}
|
||||
Gia_SatDumpClause( vStr, pLits, nLits );
|
||||
}
|
||||
Vec_StrPush( vStr, '\0' );
|
||||
Vec_IntFreeP( &vRes );
|
||||
return vStr;
|
||||
}
|
||||
|
||||
|
||||
typedef enum {
|
||||
GIA_GATE2_ZERO, // 0:
|
||||
GIA_GATE2_ONE, // 1:
|
||||
GIA_GATE2_BUF, // 2:
|
||||
GIA_GATE2_INV, // 3:
|
||||
GIA_GATE2_NAN2, // 4:
|
||||
GIA_GATE2_NOR2, // 5:
|
||||
GIA_GATE2_AOI21, // 6:
|
||||
GIA_GATE2_NAN3, // 7:
|
||||
GIA_GATE2_NOR3, // 8:
|
||||
GIA_GATE2_OAI21, // 9:
|
||||
GIA_GATE2_NOR4, // 10:
|
||||
GIA_GATE2_AOI211, // 11:
|
||||
GIA_GATE2_AOI22, // 12:
|
||||
GIA_GATE2_NAN4, // 13:
|
||||
GIA_GATE2_OAI211, // 14:
|
||||
GIA_GATE2_OAI22, // 15:
|
||||
GIA_GATE2_VOID // 16: unused value
|
||||
} Gia_ManGate2_t;
|
||||
|
||||
Vec_Int_t * Gia_ManDeriveKSatMappingArray( Gia_Man_t * p, Vec_Int_t * vRes )
|
||||
{
|
||||
Vec_Int_t * vMapping = Vec_IntStart( 2*Gia_ManObjNum(p) );
|
||||
int i, Id; Gia_Obj_t * pObj;
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
if ( Vec_IntEntry(vRes, Id) )
|
||||
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(Id, 1), -1 );
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
assert( Vec_IntEntry(vRes, i) > 0 );
|
||||
if ( (Vec_IntEntry(vRes, i) & 2) == 0 ) {
|
||||
assert( (Vec_IntEntry(vRes, i) & 1) == 0 );
|
||||
continue;
|
||||
}
|
||||
Gia_Obj_t * pFans[2] = { Gia_ObjFanin0(pObj), Gia_ObjFanin1(pObj) };
|
||||
int fComp = ((Vec_IntEntry(vRes, i) >> 2) & 1) != 0;
|
||||
int fFan0 = ((Vec_IntEntry(vRes, Gia_ObjFaninId0(pObj, i)) >> 1) & 1) == 0 && Gia_ObjIsAnd(pFans[0]);
|
||||
int fFan1 = ((Vec_IntEntry(vRes, Gia_ObjFaninId1(pObj, i)) >> 1) & 1) == 0 && Gia_ObjIsAnd(pFans[1]);
|
||||
if ( Vec_IntEntry(vRes, i) & 1 )
|
||||
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(i, !fComp), -1 );
|
||||
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(i, fComp), Vec_IntSize(vMapping) );
|
||||
if ( fFan0 && fFan1 ) {
|
||||
Vec_IntPush( vMapping, 4 );
|
||||
if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) {
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
|
||||
}
|
||||
else {
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
|
||||
}
|
||||
if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE2_OAI22 : GIA_GATE2_AOI22 );
|
||||
else if ( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE2_NAN4 : GIA_GATE2_NOR4 );
|
||||
else
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE2_OAI211 : GIA_GATE2_AOI211 );
|
||||
} else if ( fFan0 ) {
|
||||
Vec_IntPush( vMapping, 3 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pObj), !(fComp ^ Gia_ObjFaninC1(pObj))) );
|
||||
if ( Gia_ObjFaninC0(pObj) )
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE2_OAI21 : GIA_GATE2_AOI21 );
|
||||
else
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE2_NAN3 : GIA_GATE2_NOR3 );
|
||||
} else if ( fFan1 ) {
|
||||
Vec_IntPush( vMapping, 3 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pObj), !(fComp ^ Gia_ObjFaninC0(pObj))) );
|
||||
if ( Gia_ObjFaninC1(pObj) )
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE2_OAI21 : GIA_GATE2_AOI21 );
|
||||
else
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE2_NAN3 : GIA_GATE2_NOR3 );
|
||||
} else {
|
||||
Vec_IntPush( vMapping, 2 );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pObj), !(fComp ^ Gia_ObjFaninC0(pObj))) );
|
||||
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pObj), !(fComp ^ Gia_ObjFaninC1(pObj))) );
|
||||
Vec_IntPush( vMapping, fComp ? GIA_GATE2_NAN2 : GIA_GATE2_NOR2 );
|
||||
}
|
||||
}
|
||||
return vMapping;
|
||||
}
|
||||
|
||||
Gia_Man_t * Gia_ManDeriveKSatMapping( Vec_Int_t * vRes, int * pMap, int nIns, int nNodes, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vGuide = Vec_IntStart( 1000 );
|
||||
Gia_Man_t * pNew = Gia_ManStart( nIns + nNodes + 2 );
|
||||
pNew->pName = Abc_UtilStrsav( "test" );
|
||||
int i, nSave = 0, pCopy[256] = {0};
|
||||
for ( i = 1; i <= nIns; i++ )
|
||||
pCopy[i] = Gia_ManAppendCi( pNew );
|
||||
for ( i = nIns; i < nIns+nNodes; i++ ) {
|
||||
int iFan0 = Gia_KSatFindFan( pMap, i, 0, vRes );
|
||||
int iFan1 = Gia_KSatFindFan( pMap, i, 1, vRes );
|
||||
if ( iFan0 == iFan1 )
|
||||
pCopy[i+1] = pCopy[iFan0+1];
|
||||
else if ( Gia_KSatValAnd(pMap, i, vRes) )
|
||||
pCopy[i+1] = Gia_ManAppendAnd( pNew, pCopy[iFan0+1], pCopy[iFan1+1] );
|
||||
else
|
||||
pCopy[i+1] = Gia_ManAppendOr( pNew, pCopy[iFan0+1], pCopy[iFan1+1] );
|
||||
pCopy[i+1] = Abc_LitNotCond( pCopy[i+1], Gia_KSatValInv(pMap, i, vRes) );
|
||||
if ( iFan0 == iFan1 )
|
||||
*Vec_IntEntryP(vGuide, Abc_Lit2Var(pCopy[i+1])) ^= 1;
|
||||
else if ( Gia_KSatValAnd(pMap, i, vRes) )
|
||||
*Vec_IntEntryP(vGuide, Abc_Lit2Var(pCopy[i+1])) ^= 4 | (2*Gia_KSatValInv(pMap, i, vRes));
|
||||
else
|
||||
*Vec_IntEntryP(vGuide, Abc_Lit2Var(pCopy[i+1])) ^= 8 | (2*Gia_KSatValInv(pMap, i, vRes));
|
||||
if ( fVerbose ) {
|
||||
if ( i == nIns+nNodes-1 )
|
||||
printf( " F = " );
|
||||
else
|
||||
printf( "%2d = ", i );
|
||||
if ( iFan0 == iFan1 )
|
||||
printf( "INV( %d )\n", iFan0 );
|
||||
else if ( Gia_KSatValAnd(pMap, i, vRes) )
|
||||
printf( "%sAND( %d, %d )\n", Gia_KSatValInv(pMap, i, vRes) ? "N":"", iFan0, iFan1 );
|
||||
else
|
||||
printf( "%sOR( %d, %d )\n", Gia_KSatValInv(pMap, i, vRes) ? "N":"", iFan0, iFan1 );
|
||||
nSave += (iFan0 == iFan1) || !Gia_KSatValInv(pMap, i, vRes);
|
||||
if ( i == nIns+nNodes-1 )
|
||||
printf( "Solution cost = %d\n", 2*(2*nNodes - nSave) );
|
||||
}
|
||||
}
|
||||
Gia_ManAppendCo( pNew, pCopy[nIns+nNodes] );
|
||||
//pNew->vCellMapping = Gia_ManDeriveKSatMappingArray( pNew, vGuide );
|
||||
Vec_IntFree( vGuide );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
word Gia_ManGetTruth( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, Id;
|
||||
word pFuncs[256] = {0}, Const[2] = {0, ~(word)0};
|
||||
assert( Gia_ManObjNum(p) <= 256 );
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
pFuncs[Id] = s_Truths6[i];
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
pFuncs[i] = (Const[Gia_ObjFaninC0(pObj)] ^ pFuncs[Gia_ObjFaninId0(pObj, i)]) & (Const[Gia_ObjFaninC1(pObj)] ^ pFuncs[Gia_ObjFaninId1(pObj, i)]);
|
||||
pObj = Gia_ManCo(p, 0);
|
||||
return Const[Gia_ObjFaninC0(pObj)] ^ pFuncs[Gia_ObjFaninId0p(p, pObj)];
|
||||
}
|
||||
|
||||
Gia_Man_t * Gia_ManKSatMapping( word Truth, int nIns, int nNodes, int nBound, int Seed, int fMultiLevel, int nBTLimit, int nTimeout, int fVerbose, int fKeepFile, int argc, char ** argv, char * pGuide )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
Gia_Man_t * pNew = NULL;
|
||||
srand(time(NULL));
|
||||
int Status, Rand = ((((unsigned)rand()) << 12) ^ ((unsigned)rand())) & 0xFFFFFF;
|
||||
char pFileNameI[32]; sprintf( pFileNameI, "_%06x_.cnf", Rand );
|
||||
char pFileNameO[32]; sprintf( pFileNameO, "_%06x_.out", Rand );
|
||||
int nVars = 0, * pMap = Gia_KSatMapInit( nIns, nNodes, Truth, &nVars );
|
||||
Vec_Str_t * vStr = Gia_ManKSatCnf( pMap, nIns, nNodes, nBound/2, fMultiLevel, pGuide );
|
||||
if ( !Gia_ManDumpCnf(pFileNameI, vStr, nVars) ) {
|
||||
Vec_StrFree( vStr );
|
||||
return NULL;
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "Vars = %d. Nodes = %d. Cardinality bound = %d. SAT vars = %d. SAT clauses = %d. Conflict limit = %d. Timeout = %d.\n",
|
||||
nIns, nNodes, nBound, nVars, Vec_StrCountEntry(vStr, '\n'), nBTLimit, nTimeout );
|
||||
Vec_Int_t * vRes = Gia_RunKadical( pFileNameI, pFileNameO, Seed, nBTLimit, nTimeout, 1, &Status );
|
||||
unlink( pFileNameI );
|
||||
//unlink( pFileNameO );
|
||||
if ( fKeepFile ) Gia_ManDumpCnf2( vStr, nVars, argc, argv, Abc_Clock() - clkStart, Status );
|
||||
Vec_StrFree( vStr );
|
||||
if ( vRes == NULL )
|
||||
return 0;
|
||||
Vec_IntDrop( vRes, 0 );
|
||||
pNew = Gia_ManDeriveKSatMapping( vRes, pMap, nIns, nNodes, fVerbose );
|
||||
printf( "Verification %s. ", Truth == Gia_ManGetTruth(pNew) ? "passed" : "failed" );
|
||||
Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
|
||||
Vec_IntFree( vRes );
|
||||
ABC_FREE( pMap );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -269,6 +269,118 @@ static inline int sat_solver_add_and2( sat_solver * pSat, int iVar, int iVar0, i
|
|||
return 3;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds a general cardinality constraint in terms of vVars.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline int Card_AddClause( Vec_Int_t * p, int* begin, int* end )
|
||||
{
|
||||
Vec_IntPush( p, (int)(end-begin) );
|
||||
while ( begin < end )
|
||||
Vec_IntPush( p, (int)*begin++ );
|
||||
return 1;
|
||||
}
|
||||
static inline int Card_AddHalfSorter( Vec_Int_t * p, int iVarA, int iVarB, int iVar0, int iVar1 )
|
||||
{
|
||||
lit Lits[3];
|
||||
int Cid;
|
||||
|
||||
Lits[0] = toLitCond( iVarA, 0 );
|
||||
Lits[1] = toLitCond( iVar0, 1 );
|
||||
Cid = Card_AddClause( p, Lits, Lits + 2 );
|
||||
assert( Cid );
|
||||
|
||||
Lits[0] = toLitCond( iVarA, 0 );
|
||||
Lits[1] = toLitCond( iVar1, 1 );
|
||||
Cid = Card_AddClause( p, Lits, Lits + 2 );
|
||||
assert( Cid );
|
||||
|
||||
Lits[0] = toLitCond( iVarB, 0 );
|
||||
Lits[1] = toLitCond( iVar0, 1 );
|
||||
Lits[2] = toLitCond( iVar1, 1 );
|
||||
Cid = Card_AddClause( p, Lits, Lits + 3 );
|
||||
assert( Cid );
|
||||
return 3;
|
||||
}
|
||||
static inline void Card_AddSorter( Vec_Int_t * p, int * pVars, int i, int k, int * pnVars )
|
||||
{
|
||||
int iVar1 = (*pnVars)++;
|
||||
int iVar2 = (*pnVars)++;
|
||||
Card_AddHalfSorter( p, iVar1, iVar2, pVars[i], pVars[k] );
|
||||
pVars[i] = iVar1;
|
||||
pVars[k] = iVar2;
|
||||
}
|
||||
static inline void Card_AddCardinConstrMerge( Vec_Int_t * p, int * pVars, int lo, int hi, int r, int * pnVars )
|
||||
{
|
||||
int i, step = r * 2;
|
||||
if ( step < hi - lo )
|
||||
{
|
||||
Card_AddCardinConstrMerge( p, pVars, lo, hi-r, step, pnVars );
|
||||
Card_AddCardinConstrMerge( p, pVars, lo+r, hi, step, pnVars );
|
||||
for ( i = lo+r; i < hi-r; i += step )
|
||||
Card_AddSorter( p, pVars, i, i+r, pnVars );
|
||||
for ( i = lo+r; i < hi-r-1; i += r )
|
||||
{
|
||||
lit Lits[2] = { Abc_Var2Lit(pVars[i], 0), Abc_Var2Lit(pVars[i+r], 1) };
|
||||
int Cid = Card_AddClause( p, Lits, Lits + 2 );
|
||||
assert( Cid );
|
||||
}
|
||||
}
|
||||
}
|
||||
static inline void Card_AddCardinConstrRange( Vec_Int_t * p, int * pVars, int lo, int hi, int * pnVars )
|
||||
{
|
||||
if ( hi - lo >= 1 )
|
||||
{
|
||||
int i, mid = lo + (hi - lo) / 2;
|
||||
for ( i = lo; i <= mid; i++ )
|
||||
Card_AddSorter( p, pVars, i, i + (hi - lo + 1) / 2, pnVars );
|
||||
Card_AddCardinConstrRange( p, pVars, lo, mid, pnVars );
|
||||
Card_AddCardinConstrRange( p, pVars, mid+1, hi, pnVars );
|
||||
Card_AddCardinConstrMerge( p, pVars, lo, hi, 1, pnVars );
|
||||
}
|
||||
}
|
||||
int Card_AddCardinConstrPairWise( Vec_Int_t * p, Vec_Int_t * vVars )
|
||||
{
|
||||
int nVars = Vec_IntSize(vVars);
|
||||
Card_AddCardinConstrRange( p, Vec_IntArray(vVars), 0, nVars - 1, &nVars );
|
||||
return nVars;
|
||||
}
|
||||
int Card_AddCardinSolver( int LogN, Vec_Int_t ** pvVars, Vec_Int_t ** pvRes )
|
||||
{
|
||||
int nVars = 1 << LogN;
|
||||
int nVarsAlloc = nVars + 2 * (nVars * LogN * (LogN-1) / 4 + nVars - 1);
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
|
||||
Vec_Int_t * vVars = Vec_IntStartNatural( nVars );
|
||||
int nVarsReal = Card_AddCardinConstrPairWise( vRes, vVars );
|
||||
assert( nVarsReal == nVarsAlloc );
|
||||
Vec_IntPush( vRes, -1 );
|
||||
*pvVars = vVars;
|
||||
*pvRes = vRes;
|
||||
return nVarsReal;
|
||||
}
|
||||
sat_solver * Sbm_AddCardinSolver2( int LogN, Vec_Int_t ** pvVars, Vec_Int_t ** pvRes )
|
||||
{
|
||||
Vec_Int_t * vVars = NULL;
|
||||
Vec_Int_t * vRes = NULL;
|
||||
int nVarsReal = Card_AddCardinSolver( LogN, &vVars, &vRes ), i, size;
|
||||
sat_solver * pSat = sat_solver_new();
|
||||
sat_solver_setnvars( pSat, nVarsReal );
|
||||
for ( i = 0, size = Vec_IntEntry(vRes, i++); i < Vec_IntSize(vRes); i += size, size = Vec_IntEntry(vRes, i++) )
|
||||
sat_solver_addclause( pSat, Vec_IntEntryP(vRes, i), Vec_IntEntryP(vRes, i+size) );
|
||||
if ( pvVars ) *pvVars = vVars;
|
||||
if ( pvRes ) *pvRes = vRes;
|
||||
return pSat;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds a general cardinality constraint in terms of vVars.]
|
||||
|
|
|
|||
|
|
@ -1,30 +1,34 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cbaCba.c]
|
||||
FileName [giaSyn.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Hierarchical word-level netlist.]
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Reading binary representation.]
|
||||
Synopsis [High-effort synthesis.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - July 21, 2015.]
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: cbaCba.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: giaSyn.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cba.h"
|
||||
#include "gia.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "sat/glucose/AbcGlucose.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -41,12 +45,10 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cba_Man_t * Cba_ManReadCba( char * pFileName )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
void Cba_ManWriteCba( char * pFileName, Cba_Man_t * p )
|
||||
Gia_Man_t * Gia_ManSyn( Gia_Man_t * p, int nNodes, int nOuts, int nTimeLimit, int fUseXor, int fFancy, int fVerbose )
|
||||
{
|
||||
Gia_Man_t * pNew = NULL;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1125,11 +1125,11 @@ void Gia_ShowProcess( Gia_Man_t * p, char * pFileName, Vec_Int_t * vBold, Vec_In
|
|||
}
|
||||
void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds, int fPath )
|
||||
{
|
||||
extern void Abc_ShowFile( char * FileNameDot );
|
||||
extern void Abc_ShowFile( char * FileNameDot, int fKeepDot );
|
||||
char FileNameDot[200];
|
||||
FILE * pFile;
|
||||
Vec_Int_t * vXors = NULL, * vAdds = fAdders ? Ree_ManComputeCuts( pMan, &vXors, 0 ) : NULL;
|
||||
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") );
|
||||
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName ? pMan->pName : (char *)"unknown", ".dot") );
|
||||
// check that the file can be opened
|
||||
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
|
||||
{
|
||||
|
|
@ -1145,7 +1145,7 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds,
|
|||
else
|
||||
Gia_WriteDotAigSimple( pMan, FileNameDot, vBold );
|
||||
// visualize the file
|
||||
Abc_ShowFile( FileNameDot );
|
||||
Abc_ShowFile( FileNameDot, 0 );
|
||||
|
||||
Vec_IntFreeP( &vAdds );
|
||||
Vec_IntFreeP( &vXors );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,676 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaSif.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Sequential mapping.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaSif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManSifDupNode_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
|
||||
{
|
||||
if ( Gia_ObjUpdateTravIdCurrent(p, pObj) )
|
||||
return;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
Gia_ManSifDupNode_rec( pNew, p, Gia_ObjFanin0(pObj) );
|
||||
Gia_ManSifDupNode_rec( pNew, p, Gia_ObjFanin1(pObj) );
|
||||
pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
}
|
||||
void Gia_ManSifDupNode( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, Vec_Int_t * vCopy )
|
||||
{
|
||||
int k, iFan;
|
||||
Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_LutForEachFanin( p, iObj, iFan, k )
|
||||
{
|
||||
assert( Vec_IntEntry(vCopy, iFan) >= 0 );
|
||||
Gia_ManObj(p, iFan)->Value = Vec_IntEntry(vCopy, iFan);
|
||||
Gia_ObjUpdateTravIdCurrentId(p, iFan);
|
||||
}
|
||||
Gia_ManSifDupNode_rec( pNew, p, pObj );
|
||||
Vec_IntWriteEntry( vCopy, iObj, pObj->Value );
|
||||
}
|
||||
Vec_Int_t * Gia_ManSifInitNeg( Gia_Man_t * p, Vec_Int_t * vMoves, Vec_Int_t * vRegs )
|
||||
{
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vRegs) );
|
||||
Gia_Obj_t * pObj; int i, iObj;
|
||||
Gia_Man_t * pNew = Gia_ManStart( 1000 ), * pTemp;
|
||||
Vec_Int_t * vCopy = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
Vec_IntWriteEntry( vCopy, 0, 0 );
|
||||
Gia_ManForEachRo( p, pObj, i )
|
||||
Vec_IntWriteEntry( vCopy, Gia_ObjId(p, pObj), Gia_ManAppendCi(pNew) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Vec_IntForEachEntry( vMoves, iObj, i )
|
||||
Gia_ManSifDupNode( pNew, p, iObj, vCopy );
|
||||
Vec_IntForEachEntry( vRegs, iObj, i )
|
||||
{
|
||||
int iLit = Vec_IntEntry( vCopy, iObj );
|
||||
assert( iLit >= 0 );
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
}
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
Gia_ManSetPhase( pNew );
|
||||
Gia_ManForEachPo( pNew, pObj, i )
|
||||
Vec_IntPush( vRes, pObj->fPhase );
|
||||
Gia_ManStop( pNew );
|
||||
Vec_IntFree( vCopy );
|
||||
assert( Vec_IntSize(vRes) == Vec_IntSize(vRegs) );
|
||||
return vRes;
|
||||
}
|
||||
Vec_Int_t * Gia_ManSifInitPos( Gia_Man_t * p, Vec_Int_t * vMoves, Vec_Int_t * vRegs )
|
||||
{
|
||||
extern int * Abc_NtkSolveGiaMiter( Gia_Man_t * p );
|
||||
int i, iObj, iLitAnd = 1, * pResult = NULL;
|
||||
Gia_Obj_t * pObj; Vec_Int_t * vRes = NULL;
|
||||
Gia_Man_t * pNew = Gia_ManStart( 1000 ), * pTemp;
|
||||
Vec_Int_t * vCopy = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
Vec_IntWriteEntry( vCopy, 0, 0 );
|
||||
Vec_IntForEachEntry( vRegs, iObj, i )
|
||||
Vec_IntWriteEntry( vCopy, iObj, Gia_ManAppendCi(pNew) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Vec_IntForEachEntry( vMoves, iObj, i )
|
||||
Gia_ManSifDupNode( pNew, p, iObj, vCopy );
|
||||
Gia_ManForEachRi( p, pObj, i )
|
||||
{
|
||||
int iFan = Gia_ObjFaninId0p(p, pObj);
|
||||
int iLit = Vec_IntEntry(vCopy, iFan);
|
||||
if ( iLit == -1 )
|
||||
continue;
|
||||
iLit = Abc_LitNotCond( iLit, Gia_ObjFaninC0(pObj) );
|
||||
iLitAnd = Gia_ManAppendAnd2( pNew, iLitAnd, Abc_LitNot(iLit) );
|
||||
}
|
||||
Gia_ManAppendCo( pNew, iLitAnd );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
pResult = Abc_NtkSolveGiaMiter( pNew );
|
||||
if ( pResult )
|
||||
{
|
||||
vRes = Vec_IntAllocArray( pResult, Vec_IntSize(vRegs) );
|
||||
Gia_ManSetPhasePattern( pNew, vRes );
|
||||
assert( Gia_ManPo(pNew, 0)->fPhase == 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
vRes = Vec_IntStart( Vec_IntSize(vRegs) );
|
||||
printf( "***!!!*** The SAT problem has no solution. Using all-0 initial state. ***!!!***\n" );
|
||||
}
|
||||
Gia_ManStop( pNew );
|
||||
Vec_IntFree( vCopy );
|
||||
assert( Vec_IntSize(vRes) == Vec_IntSize(vRegs) );
|
||||
return vRes;
|
||||
}
|
||||
Gia_Man_t * Gia_ManSifDerive( Gia_Man_t * p, Vec_Int_t * vCounts, int fVerbose )
|
||||
{
|
||||
Gia_Man_t * pNew = NULL; Gia_Obj_t * pObj;
|
||||
Vec_Int_t * vCopy = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vCopy2 = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
Vec_Int_t * vLuts[3], * vRos[3], * vRegs[2], * vInits[2], * vTemp;
|
||||
int i, k, Id, iFan;
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
vLuts[i] = Vec_IntAlloc(100);
|
||||
vRos[i] = Vec_IntAlloc(100);
|
||||
if ( i == 2 ) break;
|
||||
vRegs[i] = Vec_IntAlloc(100);
|
||||
}
|
||||
Gia_ManForEachLut( p, i )
|
||||
if ( Vec_IntEntry(vCounts, i) == 1 )
|
||||
Vec_IntPush( vLuts[0], i );
|
||||
else if ( Vec_IntEntry(vCounts, i) == -1 )
|
||||
Vec_IntPush( vLuts[1], i );
|
||||
else if ( Vec_IntEntry(vCounts, i) == 0 )
|
||||
Vec_IntPush( vLuts[2], i );
|
||||
else assert( 0 );
|
||||
assert( Vec_IntSize(vLuts[0]) || Vec_IntSize(vLuts[1]) );
|
||||
if ( Vec_IntSize(vLuts[0]) )
|
||||
{
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntForEachEntry( vLuts[0], Id, i )
|
||||
Gia_ObjSetTravIdCurrentId(p, Id);
|
||||
Gia_ManForEachRo( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(Gia_ObjRoToRi(p, pObj))) )
|
||||
Vec_IntPush( vRos[0], Gia_ObjId(p, pObj) );
|
||||
assert( !Vec_IntSize(vLuts[0]) == !Vec_IntSize(vRos[0]) );
|
||||
}
|
||||
if ( Vec_IntSize(vLuts[1]) )
|
||||
{
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntForEachEntry( vLuts[1], Id, i )
|
||||
Gia_LutForEachFanin( p, Id, iFan, k )
|
||||
Gia_ObjSetTravIdCurrentId(p, iFan);
|
||||
Gia_ManForEachRo( p, pObj, i )
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
Vec_IntPush( vRos[1], Gia_ObjId(p, pObj) );
|
||||
assert( !Vec_IntSize(vLuts[1]) == !Vec_IntSize(vRos[1]) );
|
||||
}
|
||||
Gia_ManIncrementTravId( p );
|
||||
for ( k = 0; k < 2; k++ )
|
||||
Vec_IntForEachEntry( vRos[k], Id, i )
|
||||
Gia_ObjSetTravIdCurrentId(p, Id);
|
||||
Gia_ManForEachRo( p, pObj, i )
|
||||
if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
Vec_IntPush( vRos[2], Gia_ObjId(p, pObj) );
|
||||
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntForEachEntry( vLuts[0], Id, i )
|
||||
Gia_ObjSetTravIdCurrentId(p, Id);
|
||||
Vec_IntForEachEntry( vLuts[0], Id, i )
|
||||
Gia_LutForEachFanin( p, Id, iFan, k )
|
||||
if ( !Gia_ObjUpdateTravIdCurrentId(p, iFan) )
|
||||
Vec_IntPush( vRegs[0], iFan );
|
||||
Vec_IntSort( vRegs[0], 0 );
|
||||
assert( Vec_IntCountDuplicates(vRegs[1]) == 0 );
|
||||
assert( !Vec_IntSize(vLuts[0]) == !Vec_IntSize(vRegs[0]) );
|
||||
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntForEachEntry( vLuts[0], Id, i )
|
||||
Gia_LutForEachFanin( p, Id, iFan, k )
|
||||
Gia_ObjSetTravIdCurrentId(p, iFan);
|
||||
Vec_IntForEachEntry( vLuts[2], Id, i )
|
||||
Gia_LutForEachFanin( p, Id, iFan, k )
|
||||
Gia_ObjSetTravIdCurrentId(p, iFan);
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Gia_ObjSetTravIdCurrentId(p, Gia_ObjFaninId0p(p, pObj));
|
||||
Vec_IntForEachEntry( vRos[1], Id, i )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Id) )
|
||||
Vec_IntPush( vRegs[1], Id );
|
||||
Vec_IntForEachEntry( vLuts[1], Id, i )
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, Id) )
|
||||
Vec_IntPush( vRegs[1], Id );
|
||||
Vec_IntSort( vRegs[1], 0 );
|
||||
assert( Vec_IntCountDuplicates(vRegs[1]) == 0 );
|
||||
assert( !Vec_IntSize(vLuts[1]) == !Vec_IntSize(vRegs[1]) );
|
||||
|
||||
vInits[0] = Vec_IntSize(vLuts[0]) ? Gia_ManSifInitPos( p, vLuts[0], vRegs[0] ) : Vec_IntAlloc(0);
|
||||
vInits[1] = Vec_IntSize(vLuts[1]) ? Gia_ManSifInitNeg( p, vLuts[1], vRegs[1] ) : Vec_IntAlloc(0);
|
||||
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Flops : %5d %5d %5d\n", Vec_IntSize(vRos[0]), Vec_IntSize(vRos[1]), Vec_IntSize(vRos[2]) );
|
||||
printf( "LUTs : %5d %5d %5d\n", Vec_IntSize(vLuts[0]), Vec_IntSize(vLuts[1]), Vec_IntSize(vLuts[2]) );
|
||||
printf( "Spots : %5d %5d %5d\n", Vec_IntSize(vRegs[0]), Vec_IntSize(vRegs[1]), 0 );
|
||||
}
|
||||
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) + Vec_IntSize(vRegs[0]) + Vec_IntSize(vRegs[1]) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
|
||||
Vec_IntWriteEntry( vCopy, 0, 0 );
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
Vec_IntWriteEntry( vCopy, Gia_ObjId(p, pObj), Gia_ManAppendCi(pNew) );
|
||||
Vec_IntForEachEntry( vRos[2], Id, i )
|
||||
Vec_IntWriteEntry( vCopy, Id, Gia_ManAppendCi(pNew) );
|
||||
Vec_IntForEachEntry( vRegs[1], Id, i )
|
||||
Vec_IntWriteEntry( vCopy, Id, Abc_LitNotCond(Gia_ManAppendCi(pNew), Vec_IntEntry(vInits[1], i)) );
|
||||
|
||||
vTemp = Vec_IntAlloc(100);
|
||||
Vec_IntForEachEntry( vRegs[0], Id, i )
|
||||
Vec_IntPush( vTemp, Vec_IntEntry(vCopy, Id) );
|
||||
Vec_IntForEachEntry( vRegs[0], Id, i )
|
||||
Vec_IntWriteEntry( vCopy, Id, Abc_LitNotCond(Gia_ManAppendCi(pNew), Vec_IntEntry(vInits[0], i)) );
|
||||
Vec_IntForEachEntry( vLuts[0], Id, i )
|
||||
Gia_ManSifDupNode( pNew, p, Id, vCopy );
|
||||
Vec_IntForEachEntry( vRegs[0], Id, i )
|
||||
Vec_IntWriteEntry( vCopy, Id, Vec_IntEntry(vTemp, i) );
|
||||
Vec_IntFree( vTemp );
|
||||
|
||||
Gia_ManForEachRoToRiVec( vRos[0], p, pObj, i )
|
||||
Vec_IntWriteEntry( vCopy, Vec_IntEntry(vRos[0], i), Abc_LitNotCond(Vec_IntEntry(vCopy, Gia_ObjFaninId0p(p, pObj)), Gia_ObjFaninC0(pObj)) );
|
||||
Vec_IntForEachEntry( vLuts[2], Id, i )
|
||||
Gia_ManSifDupNode( pNew, p, Id, vCopy );
|
||||
|
||||
Gia_ManForEachRoToRiVec( vRos[1], p, pObj, i )
|
||||
Vec_IntWriteEntry( vCopy2, Vec_IntEntry(vRos[1], i), Abc_LitNotCond(Vec_IntEntry(vCopy, Gia_ObjFaninId0p(p, pObj)), Gia_ObjFaninC0(pObj)) );
|
||||
Vec_IntForEachEntry( vLuts[1], Id, i )
|
||||
Gia_ManSifDupNode( pNew, p, Id, vCopy2 );
|
||||
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
Gia_ManAppendCo( pNew, Abc_LitNotCond(Vec_IntEntry(vCopy, Gia_ObjFaninId0p(p, pObj)), Gia_ObjFaninC0(pObj)) );
|
||||
Gia_ManForEachRoToRiVec( vRos[2], p, pObj, i )
|
||||
Gia_ManAppendCo( pNew, Abc_LitNotCond(Vec_IntEntry(vCopy, Gia_ObjFaninId0p(p, pObj)), Gia_ObjFaninC0(pObj)) );
|
||||
Vec_IntForEachEntry( vRegs[1], Id, i )
|
||||
Gia_ManAppendCo( pNew, Abc_LitNotCond(Vec_IntEntry(vCopy2, Id), Vec_IntEntry(vInits[1], i)) );
|
||||
Vec_IntForEachEntry( vRegs[0], Id, i )
|
||||
Gia_ManAppendCo( pNew, Abc_LitNotCond(Vec_IntEntry(vCopy, Id), Vec_IntEntry(vInits[0], i)) );
|
||||
|
||||
Gia_ManSetRegNum( pNew, Vec_IntSize(vRos[2]) + Vec_IntSize(vRegs[0]) + Vec_IntSize(vRegs[1]) );
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
Vec_IntFreeP( &vLuts[i] );
|
||||
Vec_IntFreeP( &vRos[i] );
|
||||
if ( i == 2 ) break;
|
||||
Vec_IntFreeP( &vRegs[i] );
|
||||
Vec_IntFreeP( &vInits[i] );
|
||||
}
|
||||
Vec_IntFree( vCopy );
|
||||
Vec_IntFree( vCopy2 );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManSifArea_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCuts, int nSize )
|
||||
{
|
||||
int i, * pCut, Area = 1;
|
||||
if ( Gia_ObjUpdateTravIdCurrent(p, pObj) )
|
||||
return 0;
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
return 0;
|
||||
pCut = Vec_IntEntryP( vCuts, Gia_ObjId(p, pObj)*nSize );
|
||||
for ( i = 1; i <= pCut[0]; i++ )
|
||||
Area += Gia_ManSifArea_rec( p, Gia_ManObj(p, pCut[i] >> 8), vCuts, nSize );
|
||||
return Area;
|
||||
}
|
||||
int Gia_ManSifArea( Gia_Man_t * p, Vec_Int_t * vCuts, int nSize )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, nArea = 0;
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
nArea += Gia_ManSifArea_rec( p, Gia_ObjFanin0(pObj), vCuts, nSize );
|
||||
return nArea;
|
||||
}
|
||||
int Gia_ManSifDelay_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize )
|
||||
{
|
||||
int i, * pCut, Delay, nFails = 0;
|
||||
if ( Gia_ObjUpdateTravIdCurrent(p, pObj) )
|
||||
return 0;
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
return 0;
|
||||
pCut = Vec_IntEntryP( vCuts, Gia_ObjId(p, pObj)*nSize );
|
||||
Delay = -ABC_INFINITY-10000;
|
||||
for ( i = 1; i <= pCut[0]; i++ )
|
||||
{
|
||||
nFails += Gia_ManSifDelay_rec( p, Gia_ManObj(p, pCut[i] >> 8), vCuts, vTimes, nSize );
|
||||
Delay = Abc_MaxInt( Delay, Vec_IntEntry(vTimes, pCut[i] >> 8) );
|
||||
}
|
||||
Delay += 1;
|
||||
return nFails + (int)(Delay > Vec_IntEntry(vTimes, Gia_ObjId(p, pObj)));
|
||||
}
|
||||
int Gia_ManSifDelay( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, nFails = 0;
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
nFails += Gia_ManSifDelay_rec( p, Gia_ObjFanin0(pObj), vCuts, vTimes, nSize );
|
||||
return nFails;
|
||||
}
|
||||
static inline int Gia_ManSifTimeToCount( int Value, int Period )
|
||||
{
|
||||
return (Period*0xFFFF + Value)/Period + ((Period*0xFFFF + Value)%Period != 0) - 0x10000;
|
||||
}
|
||||
Vec_Int_t * Gia_ManSifTimesToCounts( Gia_Man_t * p, Vec_Int_t * vTimes, int Period )
|
||||
{
|
||||
int i, Times;
|
||||
Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
Vec_IntFillExtra( vTimes, Gia_ManObjNum(p), 0 );
|
||||
Vec_IntForEachEntry( vTimes, Times, i )
|
||||
if ( Gia_ObjIsLut(p, i) )
|
||||
Vec_IntWriteEntry( vCounts, i, Gia_ManSifTimeToCount(Times, Period) );
|
||||
return vCounts;
|
||||
}
|
||||
Gia_Man_t * Gia_ManSifTransform( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int fVerbose )
|
||||
{
|
||||
Gia_Man_t * pNew = NULL; Vec_Int_t * vCounts = NULL;
|
||||
if ( fVerbose )
|
||||
printf( "Current area = %d. Period = %d. ", Gia_ManSifArea(p, vCuts, nLutSize+1), Period );
|
||||
if ( fVerbose )
|
||||
printf( "Delay checking failed for %d cuts.\n", Gia_ManSifDelay( p, vCuts, vTimes, nLutSize+1 ) );
|
||||
vCounts = Gia_ManSifTimesToCounts( p, vTimes, Period );
|
||||
pNew = Gia_ManSifDerive( p, vCounts, fVerbose );
|
||||
Vec_IntFreeP( &vCounts );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline void Gia_ManSifCutMerge( int * pCut, int * pCut1, int * pCut2, int nSize )
|
||||
{
|
||||
int * pBeg = pCut+1;
|
||||
int * pBeg1 = pCut1+1;
|
||||
int * pBeg2 = pCut2+1;
|
||||
int * pEnd1 = pBeg1 + pCut1[0];
|
||||
int * pEnd2 = pBeg2 + pCut2[0];
|
||||
while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
|
||||
{
|
||||
if ( pBeg == pCut+nSize )
|
||||
{
|
||||
pCut[0] = -1;
|
||||
return;
|
||||
}
|
||||
if ( *pBeg1 == *pBeg2 )
|
||||
*pBeg++ = *pBeg1++, pBeg2++;
|
||||
else if ( *pBeg1 < *pBeg2 )
|
||||
*pBeg++ = *pBeg1++;
|
||||
else
|
||||
*pBeg++ = *pBeg2++;
|
||||
}
|
||||
while ( pBeg1 < pEnd1 )
|
||||
{
|
||||
if ( pBeg == pCut+nSize )
|
||||
{
|
||||
pCut[0] = -1;
|
||||
return;
|
||||
}
|
||||
*pBeg++ = *pBeg1++;
|
||||
}
|
||||
while ( pBeg2 < pEnd2 )
|
||||
{
|
||||
if ( pBeg == pCut+nSize )
|
||||
{
|
||||
pCut[0] = -1;
|
||||
return;
|
||||
}
|
||||
*pBeg++ = *pBeg2++;
|
||||
}
|
||||
pCut[0] = pBeg-(pCut+1);
|
||||
assert( pCut[0] < nSize );
|
||||
}
|
||||
static inline int Gia_ManSifCutChoice( Gia_Man_t * p, int Level, int iObj, int iSibl, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize )
|
||||
{
|
||||
int * pCut = Vec_IntEntryP( vCuts, iObj*nSize );
|
||||
int * pCut2 = Vec_IntEntryP( vCuts, iSibl*nSize );
|
||||
int Level2 = Vec_IntEntry( vTimes, iSibl ); int i;
|
||||
assert( iObj > iSibl );
|
||||
if ( Level < Level2 || (Level == Level2 && pCut[0] <= pCut2[0]) )
|
||||
return Level;
|
||||
for ( i = 0; i <= pCut2[0]; i++ )
|
||||
pCut[i] = pCut2[i];
|
||||
return Level2;
|
||||
}
|
||||
static inline int Gia_ManSifCutOne( Gia_Man_t * p, int iObj, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize )
|
||||
{
|
||||
Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
|
||||
int iFan0 = Gia_ObjFaninId0(pObj, iObj);
|
||||
int iFan1 = Gia_ObjFaninId1(pObj, iObj);
|
||||
int Cut0[2] = { 1, iFan0 << 8 };
|
||||
int Cut1[2] = { 1, iFan1 << 8 };
|
||||
int * pCut = Vec_IntEntryP( vCuts, iObj*nSize );
|
||||
int * pCut0 = Vec_IntEntryP( vCuts, iFan0*nSize );
|
||||
int * pCut1 = Vec_IntEntryP( vCuts, iFan1*nSize );
|
||||
int Level_ = Vec_IntEntry( vTimes, iObj );
|
||||
int Level0 = Vec_IntEntry( vTimes, iFan0 );
|
||||
int Level1 = Vec_IntEntry( vTimes, iFan1 );
|
||||
int Level = -ABC_INFINITY, i;
|
||||
assert( pCut0[0] > 0 && pCut1[0] > 0 );
|
||||
if ( Level0 == Level1 )
|
||||
Gia_ManSifCutMerge( pCut, pCut0, pCut1, nSize );
|
||||
else if ( Level0 > Level1 )
|
||||
Gia_ManSifCutMerge( pCut, pCut0, Cut1, nSize );
|
||||
else //if ( Level0 < Level1 )
|
||||
Gia_ManSifCutMerge( pCut, pCut1, Cut0, nSize );
|
||||
if ( pCut[0] == -1 )
|
||||
{
|
||||
pCut[0] = 2;
|
||||
pCut[1] = iFan0 << 8;
|
||||
pCut[2] = iFan1 << 8;
|
||||
}
|
||||
for ( i = 1; i <= pCut[0]; i++ )
|
||||
Level = Abc_MaxInt( Level, Vec_IntEntry(vTimes, pCut[i] >> 8) );
|
||||
Level++;
|
||||
if ( Gia_ObjSibl(p, iObj) )
|
||||
Level = Gia_ManSifCutChoice( p, Level, iObj, Gia_ObjSibl(p, iObj), vCuts, vTimes, nSize );
|
||||
assert( pCut[0] > 0 && pCut[0] < nSize );
|
||||
Vec_IntUpdateEntry( vTimes, iObj, Level );
|
||||
return Level > Level_;
|
||||
}
|
||||
int Gia_ManSifCheckIter( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period )
|
||||
{
|
||||
int i, fChange = 0, nSize = nLutSize+1;
|
||||
Gia_Obj_t * pObj, * pObjRi, * pObjRo;
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
fChange |= Gia_ManSifCutOne( p, i, vCuts, vTimes, nSize );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), Vec_IntEntry(vTimes, Gia_ObjFaninId0p(p, pObj)) );
|
||||
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
|
||||
{
|
||||
int TimeNew = Vec_IntEntry(vTimes, Gia_ObjId(p, pObjRi)) - Period;
|
||||
TimeNew = Abc_MaxInt( TimeNew, Vec_IntEntry(vTimes, Gia_ObjId(p, pObjRo)) );
|
||||
Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObjRo), TimeNew );
|
||||
}
|
||||
return fChange;
|
||||
}
|
||||
int Gia_ManSifCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int * pIters )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, Id, Stop, nSize = nLutSize+1;
|
||||
assert( Gia_ManRegNum(p) > 0 );
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
Vec_IntWriteEntry( vCuts, Id*nSize, 1 );
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
Vec_IntWriteEntry( vCuts, Id*nSize+1, Id << 8 );
|
||||
Vec_IntFill( vTimes, Gia_ManObjNum(p), -Period );
|
||||
if ( p->vStopsF )
|
||||
Vec_StrForEachEntry( p->vStopsF, Stop, i )
|
||||
if ( Stop ) Vec_IntWriteEntry( vTimes, i, 0 );
|
||||
Vec_IntWriteEntry( vTimes, 0, 0 );
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), 0 );
|
||||
for ( *pIters = 0; *pIters < 100; (*pIters)++ )
|
||||
{
|
||||
if ( !Gia_ManSifCheckIter(p, vCuts, vTimes, nLutSize, Period) )
|
||||
return 1;
|
||||
Gia_ManForEachPo( p, pObj, i )
|
||||
if ( Vec_IntEntry(vTimes, Gia_ObjId(p, pObj)) > Period )
|
||||
return 0;
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
if ( Vec_IntEntry(vTimes, Gia_ObjId(p, pObj)) > 2*Period )
|
||||
return 0;
|
||||
if ( p->vStopsB )
|
||||
Vec_StrForEachEntry( p->vStopsB, Stop, i )
|
||||
if ( Stop && Vec_IntEntry(vTimes, i) > Period )
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int Gia_ManSifMapComb( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, Id, Res = 0, nSize = nLutSize+1;
|
||||
Vec_IntFill( vTimes, Gia_ManObjNum(p), 0 );
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
Vec_IntWriteEntry( vCuts, Id*nSize, 1 );
|
||||
Gia_ManForEachCiId( p, Id, i )
|
||||
Vec_IntWriteEntry( vCuts, Id*nSize+1, Id << 8 );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
Gia_ManSifCutOne( p, i, vCuts, vTimes, nSize );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Res = Abc_MaxInt( Res, Vec_IntEntry(vTimes, Gia_ObjFaninId0p(p, pObj)) );
|
||||
return Res;
|
||||
}
|
||||
void Gia_ManSifPrintTimes( Gia_Man_t * p, Vec_Int_t * vTimes, int Period )
|
||||
{
|
||||
int i, Value, Pos[256] = {0}, Neg[256] = {0};
|
||||
Gia_ManForEachLut( p, i )
|
||||
{
|
||||
Value = Gia_ManSifTimeToCount( Vec_IntEntry(vTimes, i), Period );
|
||||
Value = Abc_MinInt( Value, 255 );
|
||||
Value = Abc_MaxInt( Value, -255 );
|
||||
if ( Value >= 0 )
|
||||
Pos[Value]++;
|
||||
else
|
||||
Neg[-Value]++;
|
||||
}
|
||||
printf( "Statistics: " );
|
||||
for ( i = 255; i > 0; i-- )
|
||||
if ( Neg[i] )
|
||||
printf( " -%d=%d", i, Neg[i] );
|
||||
for ( i = 0; i < 256; i++ )
|
||||
if ( Pos[i] )
|
||||
printf( " %d=%d", i, Pos[i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
int Gia_ManSifDeriveMapping_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCuts, int nSize )
|
||||
{
|
||||
int i, * pCut, Area = 1;
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
return 0;
|
||||
if ( Gia_ObjUpdateTravIdCurrent(p, pObj) )
|
||||
return 0;
|
||||
pCut = Vec_IntEntryP( vCuts, Gia_ObjId(p, pObj)*nSize );
|
||||
for ( i = 1; i <= pCut[0]; i++ )
|
||||
Area += Gia_ManSifDeriveMapping_rec( p, Gia_ManObj(p, pCut[i] >> 8), vCuts, nSize );
|
||||
Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) );
|
||||
Vec_IntPush( p->vMapping, pCut[0] );
|
||||
for ( i = 1; i <= pCut[0]; i++ )
|
||||
{
|
||||
Gia_Obj_t * pObj = Gia_ManObj(p, pCut[i] >> 8);
|
||||
assert( !Gia_ObjIsAnd(pObj) || Gia_ObjIsLut(p, pCut[i] >> 8) );
|
||||
Vec_IntPush( p->vMapping, pCut[i] >> 8 );
|
||||
}
|
||||
Vec_IntPush( p->vMapping, -1 );
|
||||
return Area;
|
||||
}
|
||||
int Gia_ManSifDeriveMapping( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int fVerbose )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, nArea = 0;
|
||||
if ( p->vMapping != NULL )
|
||||
{
|
||||
printf( "Removing available combinational mapping.\n" );
|
||||
Vec_IntFreeP( &p->vMapping );
|
||||
}
|
||||
assert( p->vMapping == NULL );
|
||||
p->vMapping = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
nArea += Gia_ManSifDeriveMapping_rec( p, Gia_ObjFanin0(pObj), vCuts, nLutSize+1 );
|
||||
return nArea;
|
||||
}
|
||||
Gia_Man_t * Gia_ManSifPerform( Gia_Man_t * p, int nLutSize, int fEvalOnly, int fVerbose )
|
||||
{
|
||||
Gia_Man_t * pNew = NULL;
|
||||
int nIters, Status, nSize = nLutSize+1; // (2+1+nSize)*4=40 bytes/node
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Int_t * vCuts = Vec_IntStart( Gia_ManObjNum(p) * nSize );
|
||||
Vec_Int_t * vTimes = Vec_IntAlloc( Gia_ManObjNum(p) );
|
||||
int Lower = 0;
|
||||
int Upper = Gia_ManSifMapComb( p, vCuts, vTimes, nLutSize );
|
||||
int CombD = Upper;
|
||||
if ( fVerbose && Gia_ManRegNum(p) )
|
||||
printf( "Clock period %2d is %s\n", Lower, 0 ? "Yes" : "No " );
|
||||
if ( fVerbose && Gia_ManRegNum(p) )
|
||||
printf( "Clock period %2d is %s\n", Upper, 1 ? "Yes" : "No " );
|
||||
while ( Gia_ManRegNum(p) > 0 && Upper - Lower > 1 )
|
||||
{
|
||||
int Middle = (Upper + Lower) / 2;
|
||||
int Status = Gia_ManSifCheckPeriod( p, vCuts, vTimes, nLutSize, Middle, &nIters );
|
||||
if ( Status )
|
||||
Upper = Middle;
|
||||
else
|
||||
Lower = Middle;
|
||||
if ( fVerbose )
|
||||
printf( "Clock period %2d is %s after %d iterations\n", Middle, Status ? "Yes" : "No ", nIters );
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "Best period = <<%d>> (%.2f %%) ", Upper, (float)(100.0*(CombD-Upper)/CombD) );
|
||||
if ( fVerbose )
|
||||
printf( "LUT size = %d ", nLutSize );
|
||||
if ( fVerbose )
|
||||
printf( "Memory usage = %.2f MB ", 4.0*(2+1+nSize)*Gia_ManObjNum(p)/(1 << 20) );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
if ( Upper == CombD )
|
||||
{
|
||||
Vec_IntFree( vCuts );
|
||||
Vec_IntFree( vTimes );
|
||||
printf( "Combinational delay (%d) cannot be improved.\n", CombD );
|
||||
return Gia_ManDup( p );
|
||||
}
|
||||
Status = Gia_ManSifCheckPeriod( p, vCuts, vTimes, nLutSize, Upper, &nIters );
|
||||
assert( Status );
|
||||
Status = Gia_ManSifDeriveMapping( p, vCuts, vTimes, nLutSize, Upper, fVerbose );
|
||||
if ( fEvalOnly )
|
||||
{
|
||||
printf( "Optimized level %2d (%6.2f %% less than comb level %2d). LUT size = %d. Area estimate = %d.\n",
|
||||
Upper, (float)(100.0*(CombD-Upper)/CombD), CombD, nLutSize, Gia_ManSifArea(p, vCuts, nLutSize+1) );
|
||||
printf( "The command is invoked in the evaluation mode. Retiming is not performed.\n" );
|
||||
}
|
||||
else
|
||||
pNew = Gia_ManSifTransform( p, vCuts, vTimes, nLutSize, Upper, fVerbose );
|
||||
Vec_IntFree( vCuts );
|
||||
Vec_IntFree( vTimes );
|
||||
//Gia_ManTransferTiming( pNew, p );
|
||||
if ( p->vNamesIn ) {
|
||||
char * pName; int i;
|
||||
pNew->vNamesIn = p->vNamesIn; p->vNamesIn = NULL;
|
||||
Vec_PtrForEachEntryStart( char *, pNew->vNamesIn, pName, i, Gia_ManPiNum(pNew) )
|
||||
ABC_FREE( pName );
|
||||
Vec_PtrShrink( pNew->vNamesIn, Gia_ManPiNum(pNew) );
|
||||
for ( i = 0; i < Gia_ManRegNum(pNew); i++ )
|
||||
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsavNum("_fo", i) );
|
||||
}
|
||||
if ( p->vNamesOut ) {
|
||||
char * pName; int i;
|
||||
pNew->vNamesOut = p->vNamesOut; p->vNamesOut = NULL;
|
||||
Vec_PtrForEachEntryStart( char *, pNew->vNamesOut, pName, i, Gia_ManPoNum(pNew) )
|
||||
ABC_FREE( pName );
|
||||
Vec_PtrShrink( pNew->vNamesOut, Gia_ManPoNum(pNew) );
|
||||
for ( i = 0; i < Gia_ManRegNum(pNew); i++ )
|
||||
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsavNum("_fi", i) );
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "gia.h"
|
||||
#include "map/if/if.h"
|
||||
#include "misc/tim/tim.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -32,6 +33,53 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int Gia_ManConfig2GetBytePos( Gia_Man_t * p, int iObj, If_LibCell_t * pCellLib )
|
||||
{
|
||||
int iLut, bytePos = 0;
|
||||
if ( p == NULL || p->vConfigs2 == NULL || pCellLib == NULL )
|
||||
return -1;
|
||||
Gia_ManForEachLut( p, iLut )
|
||||
{
|
||||
unsigned char CellId;
|
||||
int nRecordSize;
|
||||
if ( bytePos >= Vec_StrSize(p->vConfigs2) )
|
||||
return -1;
|
||||
if ( iLut == iObj )
|
||||
return bytePos;
|
||||
CellId = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos );
|
||||
if ( CellId >= IF_MAX_LUTSIZE )
|
||||
return -1;
|
||||
nRecordSize = pCellLib->pCellRecordSizes[CellId];
|
||||
if ( nRecordSize <= 0 )
|
||||
return -1;
|
||||
bytePos += nRecordSize;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
int Gia_ManConfig2DerivePinDelays( Gia_Man_t * p, int iObj, If_LibCell_t * pCellLib, int * pPinDelay, int nLutSize )
|
||||
{
|
||||
int bytePos, i, nPins;
|
||||
unsigned char CellId;
|
||||
if ( pCellLib == NULL || pPinDelay == NULL || nLutSize < 1 || nLutSize > 32 )
|
||||
return 0;
|
||||
for ( i = 0; i < nLutSize; i++ )
|
||||
pPinDelay[i] = 1;
|
||||
bytePos = Gia_ManConfig2GetBytePos( p, iObj, pCellLib );
|
||||
if ( bytePos < 0 || bytePos >= Vec_StrSize(p->vConfigs2) )
|
||||
return 0;
|
||||
CellId = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos );
|
||||
if ( CellId >= pCellLib->nCellNum )
|
||||
return 0;
|
||||
nPins = Abc_MinInt( pCellLib->nCellInputs[CellId], 9 );
|
||||
for ( i = 0; i < nPins; i++ )
|
||||
{
|
||||
int v = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos + 1 + i );
|
||||
if ( v >= 2 && v < 2 + nLutSize )
|
||||
pPinDelay[v - 2] = Abc_MaxInt( pPinDelay[v - 2], pCellLib->pCellPinDelays[CellId][i] );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sorts the pins in the decreasing order of delays.]
|
||||
|
|
@ -110,8 +158,9 @@ int Gia_LutWhereIsPin( Gia_Man_t * p, int iFanout, int iFanin, int * pPinPerm )
|
|||
float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
|
||||
{
|
||||
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
|
||||
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
|
||||
Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
|
||||
int k, iFanin, pPinPerm[32];
|
||||
int k, iFanin, pPinPerm[32], pPinDelay[32];
|
||||
float pPinDelays[32];
|
||||
float tArrival, * pDelays;
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
|
|
@ -120,12 +169,54 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
|
|||
return Gia_ObjTimeArrival(p, Gia_ObjFaninId0p(p, pObj) );
|
||||
assert( Gia_ObjIsLut(p, iObj) );
|
||||
tArrival = -TIM_ETERNITY;
|
||||
if ( pLutLib == NULL )
|
||||
if ( pLutLib == NULL && pCellLib == NULL )
|
||||
{
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + 1.0 )
|
||||
tArrival = Gia_ObjTimeArrival(p, iFanin) + 1.0;
|
||||
}
|
||||
else if ( pCellLib )
|
||||
{
|
||||
// Handle cell library delays (use integer delays directly)
|
||||
int nLutSize = Gia_ObjLutSize(p, iObj);
|
||||
int fHaveCfg2 = Gia_ManConfig2DerivePinDelays( p, iObj, pCellLib, pPinDelay, nLutSize );
|
||||
// Find matching cell (simple approach: use first cell with enough inputs)
|
||||
int cellId = -1;
|
||||
int i;
|
||||
if ( !fHaveCfg2 )
|
||||
for ( i = 0; i < pCellLib->nCellNum; i++ )
|
||||
if ( pCellLib->nCellInputs[i] >= nLutSize )
|
||||
{
|
||||
cellId = i;
|
||||
break;
|
||||
}
|
||||
if ( cellId >= 0 )
|
||||
{
|
||||
// Use cell delays as integers from the library
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
{
|
||||
float delay = (float)(pCellLib->pCellPinDelays[cellId][k]); // Integer delay from library
|
||||
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + delay )
|
||||
tArrival = Gia_ObjTimeArrival(p, iFanin) + delay;
|
||||
}
|
||||
}
|
||||
else if ( fHaveCfg2 )
|
||||
{
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
{
|
||||
float delay = (float)pPinDelay[k];
|
||||
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + delay )
|
||||
tArrival = Gia_ObjTimeArrival(p, iFanin) + delay;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fall back to default delay if no matching cell
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + 100.0 )
|
||||
tArrival = Gia_ObjTimeArrival(p, iFanin) + 100.0;
|
||||
}
|
||||
}
|
||||
else if ( !pLutLib->fVarPinDelays )
|
||||
{
|
||||
pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
|
||||
|
|
@ -170,18 +261,66 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
|
|||
float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting )
|
||||
{
|
||||
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
|
||||
int k, iFanin, pPinPerm[32];
|
||||
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
|
||||
int k, iFanin, pPinPerm[32], pPinDelay[32];
|
||||
float pPinDelays[32];
|
||||
float tRequired = 0.0; // Suppress "might be used uninitialized"
|
||||
float * pDelays;
|
||||
assert( Gia_ObjIsLut(p, iObj) );
|
||||
if ( pLutLib == NULL )
|
||||
// Infinity propagates unchanged
|
||||
if ( Gia_ObjTimeRequired( p, iObj ) >= TIM_ETERNITY )
|
||||
return TIM_ETERNITY;
|
||||
if ( pLutLib == NULL && pCellLib == NULL )
|
||||
{
|
||||
tRequired = Gia_ObjTimeRequired( p, iObj) - (float)1.0;
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
|
||||
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
|
||||
}
|
||||
else if ( pCellLib )
|
||||
{
|
||||
// Handle cell library delays (use integer delays directly)
|
||||
int nLutSize = Gia_ObjLutSize(p, iObj);
|
||||
int fHaveCfg2 = Gia_ManConfig2DerivePinDelays( p, iObj, pCellLib, pPinDelay, nLutSize );
|
||||
// Find matching cell (simple approach: use first cell with enough inputs)
|
||||
int cellId = -1;
|
||||
int i;
|
||||
if ( !fHaveCfg2 )
|
||||
for ( i = 0; i < pCellLib->nCellNum; i++ )
|
||||
if ( pCellLib->nCellInputs[i] >= nLutSize )
|
||||
{
|
||||
cellId = i;
|
||||
break;
|
||||
}
|
||||
if ( cellId >= 0 )
|
||||
{
|
||||
// Use cell delays as integers from the library
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
{
|
||||
float delay = (float)(pCellLib->pCellPinDelays[cellId][k]); // Integer delay from library
|
||||
tRequired = Gia_ObjTimeRequired( p, iObj) - delay;
|
||||
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
|
||||
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
|
||||
}
|
||||
}
|
||||
else if ( fHaveCfg2 )
|
||||
{
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
{
|
||||
tRequired = Gia_ObjTimeRequired( p, iObj ) - (float)pPinDelay[k];
|
||||
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
|
||||
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fall back to default delay if no matching cell
|
||||
tRequired = Gia_ObjTimeRequired( p, iObj) - 100.0;
|
||||
Gia_LutForEachFanin( p, iObj, iFanin, k )
|
||||
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
|
||||
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
|
||||
}
|
||||
}
|
||||
else if ( !pLutLib->fVarPinDelays )
|
||||
{
|
||||
pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
|
||||
|
|
@ -266,6 +405,32 @@ float Gia_ManDelayTraceLut( Gia_Man_t * p )
|
|||
Gia_ObjSetTimeArrival( p, i, tArrival );
|
||||
}
|
||||
|
||||
// update levels of box output CIs to reflect box structure
|
||||
// (Gia_ManLevelNum assigns level 0 to all CIs, but box output CIs
|
||||
// need higher levels so that Gia_ManOrderReverse processes them
|
||||
// before box input COs during the backward required-time pass)
|
||||
if ( p->pManTime )
|
||||
{
|
||||
Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
|
||||
int iBox, nBoxes = Tim_ManBoxNum( pManTime );
|
||||
for ( iBox = 0; iBox < nBoxes; iBox++ )
|
||||
{
|
||||
int nIns = Tim_ManBoxInputNum( pManTime, iBox );
|
||||
int nOuts = Tim_ManBoxOutputNum( pManTime, iBox );
|
||||
int iCoFirst = Tim_ManBoxInputFirst( pManTime, iBox );
|
||||
int iCiFirst = Tim_ManBoxOutputFirst( pManTime, iBox );
|
||||
int j, maxLevel = 0;
|
||||
for ( j = 0; j < nIns; j++ )
|
||||
{
|
||||
int coLevel = Gia_ObjLevel( p, Gia_ObjFanin0(Gia_ManCo(p, iCoFirst + j)) );
|
||||
if ( coLevel > maxLevel )
|
||||
maxLevel = coLevel;
|
||||
}
|
||||
for ( j = 0; j < nOuts; j++ )
|
||||
Gia_ObjSetLevel( p, Gia_ManCi(p, iCiFirst + j), maxLevel + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// get the latest arrival times
|
||||
tArrival = -TIM_ETERNITY;
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
|
|
@ -314,9 +479,11 @@ float Gia_ManDelayTraceLut( Gia_Man_t * p )
|
|||
}
|
||||
|
||||
// set slack for this object
|
||||
tSlack = Gia_ObjTimeRequired(p, iObj) - Gia_ObjTimeArrival(p, iObj);
|
||||
assert( tSlack + 0.01 > 0.0 );
|
||||
Gia_ObjSetTimeSlack( p, iObj, tSlack < 0.0 ? 0.0 : tSlack );
|
||||
if ( Gia_ObjTimeRequired(p, iObj) >= TIM_ETERNITY )
|
||||
tSlack = TIM_ETERNITY;
|
||||
else
|
||||
tSlack = Gia_ObjTimeRequired(p, iObj) - Gia_ObjTimeArrival(p, iObj);
|
||||
Gia_ObjSetTimeSlack( p, iObj, tSlack );
|
||||
}
|
||||
Vec_IntFree( vObjs );
|
||||
return tArrival;
|
||||
|
|
@ -441,20 +608,44 @@ int Gia_LutVerifyTiming( Gia_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
|
||||
float Gia_ManDelayTraceLutPrintInt( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
|
||||
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
|
||||
int i, Nodes, * pCounters;
|
||||
float tArrival, tDelta, nSteps, Num;
|
||||
// get the library
|
||||
const char * pDelayModel;
|
||||
|
||||
// determine delay model
|
||||
if ( pCellLib )
|
||||
pDelayModel = "cell library";
|
||||
else if ( pLutLib )
|
||||
pDelayModel = "LUT library";
|
||||
else
|
||||
pDelayModel = "unit-delay";
|
||||
|
||||
// check library compatibility
|
||||
if ( pLutLib && pLutLib->LutMax < Gia_ManLutSizeMax(p) )
|
||||
{
|
||||
printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
|
||||
printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
|
||||
pLutLib->LutMax, Gia_ManLutSizeMax(p) );
|
||||
return -ABC_INFINITY;
|
||||
}
|
||||
if ( pCellLib )
|
||||
{
|
||||
int nMaxInputs = 0;
|
||||
for ( i = 0; i < pCellLib->nCellNum; i++ )
|
||||
if ( pCellLib->nCellInputs[i] > nMaxInputs )
|
||||
nMaxInputs = pCellLib->nCellInputs[i];
|
||||
if ( nMaxInputs < Gia_ManLutSizeMax(p) )
|
||||
{
|
||||
printf( "The max cell inputs (%d) is less than the max fanin count (%d).\n",
|
||||
nMaxInputs, Gia_ManLutSizeMax(p) );
|
||||
return -ABC_INFINITY;
|
||||
}
|
||||
}
|
||||
// decide how many steps
|
||||
nSteps = pLutLib ? 20 : Gia_ManLutLevel(p, NULL);
|
||||
nSteps = (pLutLib || pCellLib) ? 20 : Gia_ManLutLevel(p, NULL);
|
||||
pCounters = ABC_ALLOC( int, nSteps + 1 );
|
||||
memset( pCounters, 0, sizeof(int)*(nSteps + 1) );
|
||||
// perform delay trace
|
||||
|
|
@ -471,16 +662,19 @@ float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
|
|||
assert( Num >=0 && Num <= nSteps );
|
||||
pCounters[(int)Num]++;
|
||||
}
|
||||
// print the results
|
||||
// print the results
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pLutLib? "LUT library" : "unit-delay" );
|
||||
if ( pCellLib )
|
||||
printf( "Max delay = %d. Delay trace using %s model:\n", (int)tArrival, pDelayModel );
|
||||
else
|
||||
printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pDelayModel );
|
||||
Nodes = 0;
|
||||
for ( i = 0; i < nSteps; i++ )
|
||||
{
|
||||
Nodes += pCounters[i];
|
||||
printf( "%3d %s : %5d (%6.2f %%)\n", pLutLib? 5*(i+1) : i+1,
|
||||
pLutLib? "%":"lev", Nodes, 100.0*Nodes/Gia_ManLutNum(p) );
|
||||
printf( "%3d %s : %5d (%6.2f %%)\n", (pLutLib || pCellLib)? 5*(i+1) : i+1,
|
||||
(pLutLib || pCellLib)? "%":"lev", Nodes, 100.0*Nodes/Gia_ManLutNum(p) );
|
||||
}
|
||||
}
|
||||
ABC_FREE( pCounters );
|
||||
|
|
@ -488,12 +682,61 @@ float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
|
|||
return tArrival;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Wrapper for delay trace that handles XIAGs with boxes.]
|
||||
|
||||
Description [For XIAGs with boxes, unnormalizes the AIG to ensure proper
|
||||
topological order during delay computation, similar to how
|
||||
Gia_ManPerformMapping handles it.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
float tArrival;
|
||||
// Check if we have boxes and the AIG is normalized (like in Gia_ManPerformMapping)
|
||||
if ( p->pManTime && Tim_ManBoxNum((Tim_Man_t*)p->pManTime) && Gia_ManIsNormalized(p) )
|
||||
{
|
||||
// For XIAGs with boxes, we need to unnormalize for proper topological order
|
||||
Gia_Man_t * pTemp = Gia_ManDupUnnormalize( p );
|
||||
if ( pTemp == NULL )
|
||||
{
|
||||
printf( "Failed to unnormalize AIG with boxes for delay trace.\n" );
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
// Transfer timing and mapping information
|
||||
Gia_ManTransferTiming( pTemp, p );
|
||||
Gia_ManTransferMapping( pTemp, p );
|
||||
|
||||
// Transfer library pointers
|
||||
pTemp->pLutLib = p->pLutLib;
|
||||
pTemp->pCellLib = p->pCellLib;
|
||||
|
||||
// Perform delay trace on unnormalized AIG
|
||||
tArrival = Gia_ManDelayTraceLutPrintInt( pTemp, fVerbose );
|
||||
|
||||
// Clean up temporary AIG
|
||||
Gia_ManStop( pTemp );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal case: no boxes or already unnormalized
|
||||
tArrival = Gia_ManDelayTraceLutPrintInt( p, fVerbose );
|
||||
}
|
||||
return tArrival;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Determines timing-critical edges of the node.]
|
||||
|
||||
Description []
|
||||
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
|
@ -803,4 +1046,3 @@ Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerb
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaDeep.c]
|
||||
FileName [giaStoch.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
|
|
@ -14,14 +14,23 @@
|
|||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaDeep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: giaStoch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
#include "aig/gia/giaAig.h"
|
||||
#include "proof/dch/dch.h"
|
||||
#include "base/main/main.h"
|
||||
#include "base/cmd/cmd.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#define unlink _unlink
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -32,6 +41,169 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Processing on a single core.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_StochProcessSingle( Gia_Man_t * p, char * pScript, int Rand, int TimeSecs )
|
||||
{
|
||||
Gia_Man_t * pTemp, * pNew = Gia_ManDup( p );
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(p) );
|
||||
if ( Abc_FrameIsBatchMode() )
|
||||
{
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Abc_FrameSetBatchMode( 1 );
|
||||
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
|
||||
{
|
||||
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
|
||||
return NULL;
|
||||
}
|
||||
Abc_FrameSetBatchMode( 0 );
|
||||
}
|
||||
pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
|
||||
if ( Gia_ManAndNum(pNew) > Gia_ManAndNum(pTemp) )
|
||||
{
|
||||
Gia_ManStop( pNew );
|
||||
pNew = Gia_ManDup( pTemp );
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
Vec_Int_t * Gia_StochProcessArray( Vec_Ptr_t * vGias, char * pScript, int TimeSecs, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vGains = Vec_IntStartFull( Vec_PtrSize(vGias) );
|
||||
Gia_Man_t * pGia, * pNew; int i;
|
||||
Vec_Int_t * vRands = Vec_IntAlloc( Vec_PtrSize(vGias) );
|
||||
Abc_Random(1);
|
||||
for ( i = 0; i < Vec_PtrSize(vGias); i++ )
|
||||
Vec_IntPush( vRands, Abc_Random(0) % 0x1000000 );
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
|
||||
{
|
||||
pNew = Gia_StochProcessSingle( pGia, pScript, Vec_IntEntry(vRands, i), TimeSecs );
|
||||
Vec_IntWriteEntry( vGains, i, Gia_ManAndNum(pGia) - Gia_ManAndNum(pNew) );
|
||||
Gia_ManStop( pGia );
|
||||
Vec_PtrWriteEntry( vGias, i, pNew );
|
||||
}
|
||||
Vec_IntFree( vRands );
|
||||
return vGains;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Processing on many cores.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_StochProcessOne( Gia_Man_t * p, char * pScript, int Rand, int TimeSecs )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
char FileName[100], Command[1000];
|
||||
sprintf( FileName, "%06x.aig", Rand );
|
||||
Gia_AigerWrite( p, FileName, 0, 0, 0 );
|
||||
sprintf( Command, "./abc -q \"&read %s; %s; &write %s\"", FileName, pScript, FileName );
|
||||
#if defined(__wasm)
|
||||
if ( 1 )
|
||||
#else
|
||||
if ( system( (char *)Command ) )
|
||||
#endif
|
||||
{
|
||||
fprintf( stderr, "The following command has returned non-zero exit status:\n" );
|
||||
fprintf( stderr, "\"%s\"\n", (char *)Command );
|
||||
fprintf( stderr, "Sorry for the inconvenience.\n" );
|
||||
fflush( stdout );
|
||||
unlink( FileName );
|
||||
return Gia_ManDup(p);
|
||||
}
|
||||
pNew = Gia_AigerRead( FileName, 0, 0, 0 );
|
||||
unlink( FileName );
|
||||
if ( pNew && Gia_ManAndNum(pNew) < Gia_ManAndNum(p) )
|
||||
return pNew;
|
||||
Gia_ManStopP( &pNew );
|
||||
return Gia_ManDup(p);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Generic concurrent processing.]
|
||||
|
||||
Description [User-defined problem-specific data and the way to process it.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct StochSynData_t_
|
||||
{
|
||||
Gia_Man_t * pIn;
|
||||
Gia_Man_t * pOut;
|
||||
char * pScript;
|
||||
int Rand;
|
||||
int TimeOut;
|
||||
} StochSynData_t;
|
||||
|
||||
int Gia_StochProcess1( void * p )
|
||||
{
|
||||
StochSynData_t * pData = (StochSynData_t *)p;
|
||||
assert( pData->pIn != NULL );
|
||||
assert( pData->pOut == NULL );
|
||||
pData->pOut = Gia_StochProcessOne( pData->pIn, pData->pScript, pData->Rand, pData->TimeOut );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Vec_Int_t * Gia_StochProcess( Vec_Ptr_t * vGias, char * pScript, int nProcs, int TimeSecs, int fVerbose )
|
||||
{
|
||||
if ( nProcs <= 2 ) {
|
||||
if ( fVerbose )
|
||||
printf( "Running non-concurrent synthesis.\n" ), fflush(stdout);
|
||||
return Gia_StochProcessArray( vGias, pScript, TimeSecs, fVerbose );
|
||||
}
|
||||
Vec_Int_t * vGains = Vec_IntStartFull( Vec_PtrSize(vGias) );
|
||||
StochSynData_t * pData = ABC_CALLOC( StochSynData_t, Vec_PtrSize(vGias) );
|
||||
Vec_Ptr_t * vData = Vec_PtrAlloc( Vec_PtrSize(vGias) );
|
||||
Gia_Man_t * pGia; int i;
|
||||
Abc_Random(1);
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) {
|
||||
pData[i].pIn = pGia;
|
||||
pData[i].pOut = NULL;
|
||||
pData[i].pScript = pScript;
|
||||
pData[i].Rand = Abc_Random(0) % 0x1000000;
|
||||
pData[i].TimeOut = TimeSecs;
|
||||
Vec_PtrPush( vData, pData+i );
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "Running concurrent synthesis with %d processes.\n", nProcs ), fflush(stdout);
|
||||
Util_ProcessThreads( Gia_StochProcess1, vData, nProcs, TimeSecs, fVerbose );
|
||||
// replace old AIGs by new AIGs
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) {
|
||||
Vec_IntWriteEntry( vGains, i, Gia_ManAndNum(pGia) - Gia_ManAndNum(pData[i].pOut) );
|
||||
Gia_ManStop( pGia );
|
||||
Vec_PtrWriteEntry( vGias, i, pData[i].pOut );
|
||||
}
|
||||
Vec_PtrFree( vData );
|
||||
ABC_FREE( pData );
|
||||
return vGains;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -114,6 +286,455 @@ void Gia_ManStochSynthesis( Vec_Ptr_t * vAigs, char * pScript )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManFilterPartitions( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvNodes, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins, Vec_Int_t * vGains, int fDelayOpt )
|
||||
{
|
||||
int RetValue = Vec_PtrSize(vvIns);
|
||||
Vec_Ptr_t * vvInsNew = Vec_PtrAlloc( 10 );
|
||||
Vec_Ptr_t * vvOutsNew = Vec_PtrAlloc( 10 );
|
||||
Vec_Ptr_t * vvWinsNew = Vec_PtrAlloc( 10 );
|
||||
Gia_ManIncrementTravId( p );
|
||||
while ( 1 ) {
|
||||
int i, Gain, iEntry = Vec_IntArgMax(vGains);
|
||||
if ( iEntry == -1 || Vec_IntEntry(vGains, iEntry) < 0 )
|
||||
break;
|
||||
//printf( "Selecting partition %d with gain %d.\n", iEntry, Vec_IntEntry(vGains, iEntry) );
|
||||
Vec_IntWriteEntry( vGains, iEntry, -1 );
|
||||
Vec_PtrPush( vvInsNew, Vec_IntDup((Vec_Int_t *)Vec_PtrEntry(vvIns, iEntry)) );
|
||||
Vec_PtrPush( vvOutsNew, Vec_IntDup((Vec_Int_t *)Vec_PtrEntry(vvOuts, iEntry)) );
|
||||
Vec_PtrPush( vvWinsNew, Gia_ManDupDfs((Gia_Man_t *)Vec_PtrEntry(vWins, iEntry)) );
|
||||
extern void Gia_ManMarkTfiTfo( Vec_Int_t * vOne, Gia_Man_t * pMan, int fDelayOpt );
|
||||
Gia_ManMarkTfiTfo( (Vec_Int_t *)Vec_PtrEntryLast(vvInsNew), p, fDelayOpt );
|
||||
Vec_IntForEachEntry( vGains, Gain, i ) {
|
||||
if ( Gain < 0 )
|
||||
continue;
|
||||
Vec_Int_t * vNodes = (Vec_Int_t *)Vec_PtrEntry(vvNodes, i);
|
||||
Gia_Obj_t * pNode; int j;
|
||||
Gia_ManForEachObjVec( vNodes, p, pNode, j )
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pNode) )
|
||||
break;
|
||||
if ( j < Vec_IntSize(vNodes) )
|
||||
Vec_IntWriteEntry( vGains, i, -1 );
|
||||
}
|
||||
}
|
||||
ABC_SWAP( Vec_Ptr_t, *vvInsNew, *vvIns );
|
||||
ABC_SWAP( Vec_Ptr_t, *vvOutsNew, *vvOuts );
|
||||
ABC_SWAP( Vec_Ptr_t, *vvWinsNew, *vWins );
|
||||
Vec_PtrFreeFunc( vvInsNew, (void (*)(void *)) Vec_IntFree );
|
||||
Vec_PtrFreeFunc( vvOutsNew, (void (*)(void *)) Vec_IntFree );
|
||||
Vec_PtrFreeFunc( vvWinsNew, (void (*)(void *)) Gia_ManStop );
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Partitioning.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ObjDfsMark_rec( Gia_Man_t * pGia, Gia_Obj_t * pObj )
|
||||
{
|
||||
assert( !pObj->fMark0 );
|
||||
if ( Gia_ObjIsTravIdCurrent( pGia, pObj ) )
|
||||
return;
|
||||
Gia_ObjSetTravIdCurrent( pGia, pObj );
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
return;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
Gia_ObjDfsMark_rec( pGia, Gia_ObjFanin0(pObj) );
|
||||
Gia_ObjDfsMark_rec( pGia, Gia_ObjFanin1(pObj) );
|
||||
}
|
||||
void Gia_ObjDfsMark2_rec( Gia_Man_t * pGia, Gia_Obj_t * pObj )
|
||||
{
|
||||
Gia_Obj_t * pFanout; int i;
|
||||
assert( !pObj->fMark0 );
|
||||
if ( Gia_ObjIsTravIdCurrent( pGia, pObj ) )
|
||||
return;
|
||||
Gia_ObjSetTravIdCurrent( pGia, pObj );
|
||||
Gia_ObjForEachFanoutStatic( pGia, pObj, pFanout, i )
|
||||
Gia_ObjDfsMark2_rec( pGia, pFanout );
|
||||
}
|
||||
Vec_Int_t * Gia_ManDeriveWinNodes( Gia_Man_t * pMan, Vec_Int_t * vIns, Vec_Wec_t * vStore )
|
||||
{
|
||||
Vec_Int_t * vLevel, * vNodes = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj, * pNext; int i, k, iLevel;
|
||||
Vec_WecForEachLevel( vStore, vLevel, i )
|
||||
Vec_IntClear( vLevel );
|
||||
// mark the TFI cones of the inputs
|
||||
Gia_ManIncrementTravId( pMan );
|
||||
Gia_ManForEachObjVec( vIns, pMan, pObj, i )
|
||||
Gia_ObjDfsMark_rec( pMan, pObj );
|
||||
// add unrelated fanouts of the inputs to storage
|
||||
Gia_ManForEachObjVec( vIns, pMan, pObj, i )
|
||||
Gia_ObjForEachFanoutStatic( pMan, pObj, pNext, k )
|
||||
if ( Gia_ObjIsAnd(pNext) && !Gia_ObjIsTravIdCurrent(pMan, pNext) && !pNext->fMark0 ) {
|
||||
pNext->fMark0 = 1;
|
||||
Vec_WecPush( vStore, Gia_ObjLevel(pMan, pNext), Gia_ObjId(pMan, pNext) );
|
||||
}
|
||||
// mark the inputs
|
||||
Gia_ManIncrementTravId( pMan );
|
||||
Gia_ManForEachObjVec( vIns, pMan, pObj, i )
|
||||
Gia_ObjSetTravIdCurrent(pMan, pObj);
|
||||
// collect those fanouts that are completely supported by the inputs
|
||||
Vec_WecForEachLevel( vStore, vLevel, iLevel )
|
||||
Gia_ManForEachObjVec( vLevel, pMan, pObj, i ) {
|
||||
assert( !Gia_ObjIsTravIdCurrent(pMan, pObj) );
|
||||
assert( pObj->fMark0 );
|
||||
pObj->fMark0 = 0;
|
||||
if ( !Gia_ObjIsTravIdCurrent(pMan, Gia_ObjFanin0(pObj)) ||
|
||||
!Gia_ObjIsTravIdCurrent(pMan, Gia_ObjFanin1(pObj)) )
|
||||
continue;
|
||||
Gia_ObjSetTravIdCurrent(pMan, pObj);
|
||||
Vec_IntPush( vNodes, Gia_ObjId(pMan, pObj) );
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
// add fanouts of this node to storage
|
||||
Gia_ObjForEachFanoutStatic( pMan, pObj, pNext, k )
|
||||
if ( Gia_ObjIsAnd(pNext) && !Gia_ObjIsTravIdCurrent(pMan, pNext) && !pNext->fMark0 ) {
|
||||
pNext->fMark0 = 1;
|
||||
assert( Gia_ObjLevel(pMan, pNext) > iLevel );
|
||||
Vec_WecPush( vStore, Gia_ObjLevel(pMan, pNext), Gia_ObjId(pMan, pNext) );
|
||||
}
|
||||
}
|
||||
Vec_IntSort( vNodes, 0 );
|
||||
return vNodes;
|
||||
}
|
||||
Vec_Ptr_t * Gia_ManDeriveWinNodesAll( Gia_Man_t * pMan, Vec_Ptr_t * vvIns, Vec_Wec_t * vStore )
|
||||
{
|
||||
Vec_Int_t * vIns; int i;
|
||||
Vec_Ptr_t * vvNodes = Vec_PtrAlloc( Vec_PtrSize(vvIns) );
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vvIns, vIns, i )
|
||||
Vec_PtrPush( vvNodes, Gia_ManDeriveWinNodes(pMan, vIns, vStore) );
|
||||
return vvNodes;
|
||||
}
|
||||
Vec_Int_t * Gia_ManDeriveWinOuts( Gia_Man_t * pMan, Vec_Int_t * vNodes )
|
||||
{
|
||||
Vec_Int_t * vOuts = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj, * pNext; int i, k;
|
||||
// mark the nodes in the window
|
||||
Gia_ManIncrementTravId( pMan );
|
||||
Gia_ManForEachObjVec( vNodes, pMan, pObj, i )
|
||||
Gia_ObjSetTravIdCurrent(pMan, pObj);
|
||||
// collect nodes that have unmarked fanouts
|
||||
Gia_ManForEachObjVec( vNodes, pMan, pObj, i ) {
|
||||
Gia_ObjForEachFanoutStatic( pMan, pObj, pNext, k )
|
||||
if ( !Gia_ObjIsTravIdCurrent(pMan, pNext) )
|
||||
break;
|
||||
if ( k < Gia_ObjFanoutNum(pMan, pObj) )
|
||||
Vec_IntPush( vOuts, Gia_ObjId(pMan, pObj) );
|
||||
}
|
||||
if ( Vec_IntSize(vOuts) == 0 )
|
||||
printf( "Window with %d internal nodes has no outputs (are these dangling nodes?).\n", Vec_IntSize(vNodes) );
|
||||
return vOuts;
|
||||
}
|
||||
Vec_Ptr_t * Gia_ManDeriveWinOutsAll( Gia_Man_t * pMan, Vec_Ptr_t * vvNodes )
|
||||
{
|
||||
Vec_Int_t * vNodes; int i;
|
||||
Vec_Ptr_t * vvOuts = Vec_PtrAlloc( Vec_PtrSize(vvNodes) );
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vvNodes, vNodes, i )
|
||||
Vec_PtrPush( vvOuts, Gia_ManDeriveWinOuts(pMan, vNodes) );
|
||||
return vvOuts;
|
||||
}
|
||||
void Gia_ManPermuteLevel( Gia_Man_t * pMan, int Level )
|
||||
{
|
||||
Gia_Obj_t * pObj, * pNext; int i, k;
|
||||
Gia_ManForEachAnd( pMan, pObj, i ) {
|
||||
int LevelMin = Gia_ObjLevel(pMan, pObj), LevelMax = Level + 1;
|
||||
Gia_ObjForEachFanoutStatic( pMan, pObj, pNext, k )
|
||||
if ( Gia_ObjIsAnd(pNext) )
|
||||
LevelMax = Abc_MinInt( LevelMax, Gia_ObjLevel(pMan, pNext) );
|
||||
if ( LevelMin == LevelMax ) continue;
|
||||
assert( LevelMin < LevelMax );
|
||||
// randomly set level between LevelMin and LevelMax-1
|
||||
Gia_ObjSetLevel( pMan, pObj, LevelMin + (Abc_Random(0) % (LevelMax - LevelMin)) );
|
||||
assert( Gia_ObjLevel(pMan, pObj) < LevelMax );
|
||||
}
|
||||
}
|
||||
Vec_Int_t * Gia_ManCollectObjectsPointedTo( Gia_Man_t * pMan, int Level )
|
||||
{
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
|
||||
Gia_Obj_t * pObj, * pFanin; int i, n;
|
||||
Gia_ManIncrementTravId( pMan );
|
||||
Gia_ManForEachAnd( pMan, pObj, i ) {
|
||||
if ( Gia_ObjLevel(pMan, pObj) <= Level )
|
||||
continue;
|
||||
for ( n = 0; n < 2; n++ ) {
|
||||
Gia_Obj_t * pFanin = n ? Gia_ObjFanin1(pObj) : Gia_ObjFanin0(pObj);
|
||||
if ( Gia_ObjLevel(pMan, pFanin) <= Level && !Gia_ObjIsTravIdCurrent(pMan, pFanin) ) {
|
||||
Gia_ObjSetTravIdCurrent(pMan, pFanin);
|
||||
Vec_IntPush( vRes, Gia_ObjId(pMan, pFanin) );
|
||||
}
|
||||
}
|
||||
}
|
||||
Gia_ManForEachCo( pMan, pObj, i ) {
|
||||
pFanin = Gia_ObjFanin0(pObj);
|
||||
if ( Gia_ObjLevel(pMan, pFanin) <= Level && !Gia_ObjIsTravIdCurrent(pMan, pFanin) && Gia_ObjIsAnd(pFanin) ) {
|
||||
Gia_ObjSetTravIdCurrent(pMan, pFanin);
|
||||
Vec_IntPush( vRes, Gia_ObjId(pMan, pFanin) );
|
||||
}
|
||||
}
|
||||
Vec_IntSort( vRes, 0 );
|
||||
return vRes;
|
||||
}
|
||||
Vec_Wec_t * Gia_ManCollectObjectsWithSuppLimit( Gia_Man_t * pMan, int Level, int nSuppMax )
|
||||
{
|
||||
Vec_Wec_t * vResSupps = NULL;
|
||||
Vec_Int_t * vBelow = Gia_ManCollectObjectsPointedTo( pMan, Level );
|
||||
Vec_Wec_t * vSupps = Vec_WecStart( Vec_IntSize(vBelow) );
|
||||
Vec_Int_t * vSuppIds = Vec_IntStartFull( Gia_ManObjNum(pMan) );
|
||||
Vec_Int_t * vTemp = Vec_IntAlloc(100);
|
||||
Gia_Obj_t * pObj; int i, Count = 0;
|
||||
Gia_ManForEachObjVec( vBelow, pMan, pObj, i ) {
|
||||
Vec_IntWriteEntry( vSuppIds, Gia_ObjId(pMan, pObj), i );
|
||||
Vec_IntPush( Vec_WecEntry(vSupps, i), Gia_ObjId(pMan, pObj) );
|
||||
}
|
||||
Gia_ManForEachAnd( pMan, pObj, i ) {
|
||||
if ( Gia_ObjLevel(pMan, pObj) <= Level )
|
||||
continue;
|
||||
int iSuppId0 = Vec_IntEntry( vSuppIds, Gia_ObjFaninId0(pObj, i) );
|
||||
int iSuppId1 = Vec_IntEntry( vSuppIds, Gia_ObjFaninId1(pObj, i) );
|
||||
if ( iSuppId0 == -1 || iSuppId1 == -1 ) {
|
||||
Count++;
|
||||
continue;
|
||||
}
|
||||
Vec_IntClear( vTemp );
|
||||
Vec_IntTwoMerge2( Vec_WecEntry(vSupps, iSuppId0), Vec_WecEntry(vSupps, iSuppId1), vTemp );
|
||||
if ( Vec_IntSize(vTemp) > nSuppMax ) {
|
||||
Count++;
|
||||
continue;
|
||||
}
|
||||
Vec_IntWriteEntry( vSuppIds, i, Vec_WecSize(vSupps) );
|
||||
Vec_IntAppend( Vec_WecPushLevel(vSupps), vTemp );
|
||||
}
|
||||
// remove those supported nodes that are in the TFI cones of others
|
||||
Gia_ManIncrementTravId( pMan );
|
||||
Gia_ManForEachAnd( pMan, pObj, i )
|
||||
if ( Gia_ObjLevel(pMan, pObj) > Level && Vec_IntEntry(vSuppIds, i) >= 0 && !Gia_ObjIsTravIdCurrent(pMan, pObj) ) {
|
||||
Gia_ObjDfsMark_rec(pMan, pObj);
|
||||
Gia_ObjSetTravIdPrevious(pMan, pObj);
|
||||
}
|
||||
// create the result
|
||||
vResSupps = Vec_WecAlloc( 100 );
|
||||
Gia_ManForEachAnd( pMan, pObj, i )
|
||||
if ( Gia_ObjLevel(pMan, pObj) > Level && Vec_IntEntry(vSuppIds, i) >= 0 && !Gia_ObjIsTravIdCurrent(pMan, pObj) ) {
|
||||
Vec_Int_t * vSupp = Vec_WecEntry( vSupps, Vec_IntEntry(vSuppIds, i) );
|
||||
if ( Vec_IntSize(vSupp) < 4 )
|
||||
continue;
|
||||
Vec_Int_t * vThis = Vec_WecPushLevel( vResSupps );
|
||||
Vec_IntGrow( vThis, Vec_IntSize(vSupp) + 1 );
|
||||
Vec_IntAppend( vThis, vSupp );
|
||||
//Vec_IntPush( vThis, Gia_ObjId(pObj) );
|
||||
}
|
||||
//printf( "Inputs = %d. Nodes with %d-support = %d. Nodes with larger support = %d. Selected outputs = %d.\n",
|
||||
// Vec_IntSize(vBelow), nSuppMax, Vec_WecSize(vSupps), Count, Vec_WecSize(vResSupps) );
|
||||
Vec_WecFree( vSupps );
|
||||
Vec_IntFree( vSuppIds );
|
||||
Vec_IntFree( vBelow );
|
||||
Vec_IntFree( vTemp );
|
||||
return vResSupps;
|
||||
}
|
||||
// removes all supports that overlap with this one
|
||||
void Gia_ManSelectRemove( Vec_Wec_t * vSupps, Vec_Int_t * vOne )
|
||||
{
|
||||
Vec_Int_t * vLevel; int i;
|
||||
Vec_WecForEachLevel( vSupps, vLevel, i )
|
||||
if ( Vec_IntTwoCountCommon(vLevel, vOne) > 0 )
|
||||
Vec_IntClear( vLevel );
|
||||
Vec_WecRemoveEmpty( vSupps );
|
||||
}
|
||||
// marks TFI/TFO of this one
|
||||
void Gia_ManMarkTfiTfo( Vec_Int_t * vOne, Gia_Man_t * pMan, int fDelayOpt )
|
||||
{
|
||||
int i; Gia_Obj_t * pObj;
|
||||
Gia_ManForEachObjVec( vOne, pMan, pObj, i ) {
|
||||
if ( fDelayOpt ) {
|
||||
Gia_ObjSetTravIdPrevious(pMan, pObj);
|
||||
Gia_ObjDfsMark_rec( pMan, pObj );
|
||||
}
|
||||
Gia_ObjSetTravIdPrevious(pMan, pObj);
|
||||
Gia_ObjDfsMark2_rec( pMan, pObj );
|
||||
}
|
||||
}
|
||||
// removes all supports that overlap with the TFI/TFO cones of this one
|
||||
void Gia_ManSelectRemove2( Vec_Wec_t * vSupps, Vec_Int_t * vOne, Gia_Man_t * pMan )
|
||||
{
|
||||
Vec_Int_t * vLevel; int i, k; Gia_Obj_t * pObj;
|
||||
Gia_ManForEachObjVec( vOne, pMan, pObj, i ) {
|
||||
Gia_ObjSetTravIdPrevious(pMan, pObj);
|
||||
Gia_ObjDfsMark_rec( pMan, pObj );
|
||||
Gia_ObjSetTravIdPrevious(pMan, pObj);
|
||||
Gia_ObjDfsMark2_rec( pMan, pObj );
|
||||
}
|
||||
Vec_WecForEachLevel( vSupps, vLevel, i ) {
|
||||
Gia_ManForEachObjVec( vLevel, pMan, pObj, k )
|
||||
if ( Gia_ObjIsTravIdCurrent(pMan, pObj) )
|
||||
break;
|
||||
if ( k < Vec_IntSize(vLevel) )
|
||||
Vec_IntClear( vLevel );
|
||||
}
|
||||
Vec_WecRemoveEmpty( vSupps );
|
||||
}
|
||||
// removes all supports that are contained in this one
|
||||
void Gia_ManSelectRemove3( Vec_Wec_t * vSupps, Vec_Int_t * vOne )
|
||||
{
|
||||
Vec_Int_t * vLevel; int i;
|
||||
Vec_WecForEachLevel( vSupps, vLevel, i )
|
||||
if ( Vec_IntTwoCountCommon(vLevel, vOne) == Vec_IntSize(vLevel) )
|
||||
Vec_IntClear( vLevel );
|
||||
Vec_WecRemoveEmpty( vSupps );
|
||||
}
|
||||
Vec_Ptr_t * Gia_ManDeriveWinInsAll( Vec_Wec_t * vSupps, int nSuppMax, Gia_Man_t * pMan, int fOverlap )
|
||||
{
|
||||
Vec_Ptr_t * vRes = Vec_PtrAlloc( 100 );
|
||||
Gia_ManIncrementTravId( pMan );
|
||||
while ( Vec_WecSize(vSupps) > 0 ) {
|
||||
int i, Item, iRand = Abc_Random(0) % Vec_WecSize(vSupps);
|
||||
Vec_Int_t * vLevel, * vLevel2 = Vec_WecEntry( vSupps, iRand );
|
||||
Vec_Int_t * vCopy = Vec_IntDup( vLevel2 );
|
||||
if ( Vec_IntSize(vLevel2) == nSuppMax ) {
|
||||
Vec_PtrPush( vRes, vCopy );
|
||||
if ( fOverlap )
|
||||
Gia_ManSelectRemove3( vSupps, vCopy );
|
||||
else
|
||||
Gia_ManSelectRemove2( vSupps, vCopy, pMan );
|
||||
continue;
|
||||
}
|
||||
// find another support, which maximizes the union but does not exceed nSuppMax
|
||||
int iBest = iRand, nUnion = Vec_IntSize(vCopy);
|
||||
Vec_WecForEachLevel( vSupps, vLevel, i ) {
|
||||
if ( i == iRand ) continue;
|
||||
int nCommon = Vec_IntTwoCountCommon(vLevel, vCopy);
|
||||
int nUnionCur = Vec_IntSize(vLevel) + Vec_IntSize(vCopy) - nCommon;
|
||||
if ( nUnionCur <= nSuppMax && nUnion < nUnionCur ) {
|
||||
nUnion = nUnionCur;
|
||||
iBest = i;
|
||||
}
|
||||
}
|
||||
vLevel = Vec_WecEntry( vSupps, iBest );
|
||||
Vec_IntForEachEntry( vLevel, Item, i )
|
||||
Vec_IntPushUniqueOrder( vCopy, Item );
|
||||
Vec_PtrPush( vRes, vCopy );
|
||||
if ( fOverlap )
|
||||
Gia_ManSelectRemove3( vSupps, vCopy );
|
||||
else
|
||||
Gia_ManSelectRemove2( vSupps, vCopy, pMan );
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupFromArrays( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, Vec_Int_t * vLevels[2], int nLevels )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
Gia_Obj_t * pObj;
|
||||
int i;
|
||||
pNew = Gia_ManStart( 5000 );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachObjVec( vCis, p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi( pNew );
|
||||
Gia_ManForEachObjVec( vAnds, p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachObjVec( vCos, p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
|
||||
if ( vLevels[0] && vLevels[1] ) {
|
||||
pNew->vCiArrs = Vec_IntAlloc( Gia_ManCiNum(pNew) );
|
||||
Gia_ManForEachObjVec( vCis, p, pObj, i ) {
|
||||
// Vec_IntPush( pNew->vCiArrs, Gia_ObjLevel(p, pObj) );
|
||||
Vec_IntPush( pNew->vCiArrs, Vec_IntEntry(vLevels[0], Gia_ObjId(p, pObj)) );
|
||||
}
|
||||
pNew->vCoReqs = Vec_IntAlloc( Gia_ManCoNum(pNew) );
|
||||
Gia_ManForEachObjVec( vCos, p, pObj, i ) {
|
||||
// Vec_IntPush( pNew->vCoReqs, nLevels - Gia_ObjLevel(p, pObj) );
|
||||
Vec_IntPush( pNew->vCoReqs, nLevels + 1 - Vec_IntEntry(vLevels[1], Gia_ObjId(p, pObj)) );
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
}
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
int Gia_ManLevelR( Gia_Man_t * pMan )
|
||||
{
|
||||
int i, LevelMax = Gia_ManLevelRNum( pMan );
|
||||
Gia_Obj_t * pNode;
|
||||
Gia_ManForEachObj( pMan, pNode, i )
|
||||
Gia_ObjSetLevel( pMan, pNode, (int)(LevelMax - Gia_ObjLevel(pMan, pNode) + 1) );
|
||||
Gia_ManForEachCi( pMan, pNode, i )
|
||||
Gia_ObjSetLevel( pMan, pNode, 0 );
|
||||
return LevelMax;
|
||||
}
|
||||
Vec_Ptr_t * Gia_ManDupWindows( Gia_Man_t * pMan, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvNodes, Vec_Ptr_t * vvOuts, int fDelayOpt )
|
||||
{
|
||||
// compute direct and reverse level
|
||||
Vec_Int_t * vLevels[2] = {NULL};
|
||||
if ( fDelayOpt ) {
|
||||
int Levels[2];
|
||||
Levels[0] = Gia_ManLevelNum( pMan );
|
||||
ABC_SWAP( Vec_Int_t *, vLevels[0], pMan->vLevels );
|
||||
Levels[1] = Gia_ManLevelRNum( pMan );
|
||||
ABC_SWAP( Vec_Int_t *, vLevels[1], pMan->vLevels );
|
||||
assert( (Levels[0] + 1) == Levels[1] );
|
||||
}
|
||||
Vec_Int_t * vNodes; int i;
|
||||
Vec_Ptr_t * vWins = Vec_PtrAlloc( Vec_PtrSize(vvIns) );
|
||||
assert( Vec_PtrSize(vvIns) == Vec_PtrSize(vvNodes) );
|
||||
assert( Vec_PtrSize(vvOuts) == Vec_PtrSize(vvNodes) );
|
||||
Gia_ManFillValue( pMan );
|
||||
Gia_ManCleanMark01( pMan );
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vvNodes, vNodes, i ) {
|
||||
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, i);
|
||||
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, i);
|
||||
Gia_Man_t * pNew = Gia_ManDupFromArrays( pMan, vIns, vNodes, vOuts, vLevels, pMan->nLevels );
|
||||
Vec_PtrPush( vWins, pNew );
|
||||
}
|
||||
Vec_IntFreeP( &vLevels[0] );
|
||||
Vec_IntFreeP( &vLevels[1] );
|
||||
return vWins;
|
||||
}
|
||||
Vec_Ptr_t * Gia_ManExtractPartitions( Gia_Man_t * pMan, int Iter, int nSuppMax, Vec_Ptr_t ** pvIns, Vec_Ptr_t ** pvOuts, Vec_Ptr_t ** pvNodes, int fOverlap, int fDelayOpt )
|
||||
{
|
||||
// if ( Gia_ManCiNum(pMan) <= nSuppMax ) {
|
||||
// Vec_Ptr_t * vWins = Vec_PtrAlloc( 1 );
|
||||
// Vec_PtrPush( vWins, Gia_ManDupDfs(pMan) );
|
||||
// *pvIns = *pvOuts = *pvNodes = NULL;
|
||||
// return vWins;
|
||||
// }
|
||||
// int iUseRevL = Iter % 3 == 0 ? 0 : Abc_Random(0) & 1;
|
||||
int iUseRevL = Abc_Random(0) & 1;
|
||||
int LevelMax = iUseRevL ? Gia_ManLevelR(pMan) : Gia_ManLevelNum(pMan);
|
||||
// int LevelCut = Iter % 3 == 0 ? 0 : LevelMax > 8 ? 2 + (Abc_Random(0) % (LevelMax - 4)) : 0;
|
||||
int LevelCut = LevelMax > 8 ? (Abc_Random(0) % (LevelMax - 4)) : 0;
|
||||
//printf( "Using %s cut level %d (out of %d)\n", iUseRevL ? "reverse": "direct", LevelCut, LevelMax );
|
||||
// Gia_ManPermuteLevel( pMan, LevelMax );
|
||||
Vec_Wec_t * vStore = Vec_WecStart( LevelMax+1 );
|
||||
Vec_Wec_t * vSupps = Gia_ManCollectObjectsWithSuppLimit( pMan, LevelCut, nSuppMax );
|
||||
Vec_Ptr_t * vIns = Gia_ManDeriveWinInsAll( vSupps, nSuppMax, pMan, fOverlap );
|
||||
Vec_Ptr_t * vNodes = Gia_ManDeriveWinNodesAll( pMan, vIns, vStore );
|
||||
Vec_Ptr_t * vOuts = Gia_ManDeriveWinOutsAll( pMan, vNodes );
|
||||
Vec_Ptr_t * vWins = Gia_ManDupWindows( pMan, vIns, vNodes, vOuts, fDelayOpt );
|
||||
Vec_WecFree( vSupps );
|
||||
Vec_WecFree( vStore );
|
||||
*pvIns = vIns;
|
||||
*pvOuts = vOuts;
|
||||
*pvNodes = vNodes;
|
||||
return vWins;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -150,7 +771,7 @@ void Gia_ManCollectNodes( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Ve
|
|||
Vec_IntForEachEntry( vCos, iObj, i )
|
||||
Gia_ManCollectNodes_rec( p, iObj, vAnds );
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos )
|
||||
Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, Vec_Int_t * vLevels[2], int nLevels )
|
||||
{
|
||||
Vec_Int_t * vMapping; int i;
|
||||
Gia_Man_t * pNew; Gia_Obj_t * pObj;
|
||||
|
|
@ -165,8 +786,16 @@ Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vA
|
|||
Gia_ManForEachObjVec( vCos, p, pObj, i )
|
||||
Gia_ManAppendCo( pNew, pObj->Value );
|
||||
assert( Gia_ManCiNum(pNew) > 0 && Gia_ManCoNum(pNew) > 0 );
|
||||
if ( !Gia_ManHasMapping(p) )
|
||||
if ( !Gia_ManHasMapping(p) ) {
|
||||
if ( vLevels[0] == NULL ) return pNew;
|
||||
pNew->vCiArrs = Vec_IntAlloc( Gia_ManCiNum(pNew) );
|
||||
Gia_ManForEachObjVec( vCis, p, pObj, i )
|
||||
Vec_IntPush( pNew->vCiArrs, Gia_ObjLevel(p, pObj) );
|
||||
pNew->vCoReqs = Vec_IntAlloc( Gia_ManCoNum(pNew) );
|
||||
Gia_ManForEachObjVec( vCos, p, pObj, i )
|
||||
Vec_IntPush( pNew->vCoReqs, nLevels - Gia_ObjLevel(p, pObj) );
|
||||
return pNew;
|
||||
}
|
||||
vMapping = Vec_IntAlloc( 4*Gia_ManObjNum(pNew) );
|
||||
Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 );
|
||||
Gia_ManForEachObjVec( vAnds, p, pObj, i )
|
||||
|
|
@ -184,15 +813,29 @@ Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vA
|
|||
pNew->vMapping = vMapping;
|
||||
return pNew;
|
||||
}
|
||||
Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript )
|
||||
Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript, int nProcs, int TimeOut, int fDelayOpt )
|
||||
{
|
||||
// compute direct and reverse level
|
||||
Vec_Int_t * vLevels[2] = {NULL};
|
||||
if ( fDelayOpt ) {
|
||||
int Levels[2];
|
||||
Levels[0] = Gia_ManLevelNum( p );
|
||||
ABC_SWAP( Vec_Int_t *, vLevels[0], p->vLevels );
|
||||
Levels[1] = Gia_ManLevelRNum( p );
|
||||
ABC_SWAP( Vec_Int_t *, vLevels[1], p->vLevels );
|
||||
// assert( Levels[0] == Levels[1] );
|
||||
}
|
||||
Vec_Ptr_t * vAigs = Vec_PtrAlloc( Vec_WecSize(vCis) ); int i;
|
||||
for ( i = 0; i < Vec_WecSize(vCis); i++ )
|
||||
{
|
||||
Gia_ManCollectNodes( p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i) );
|
||||
Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i)) );
|
||||
Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i), vLevels, p->nLevels) );
|
||||
}
|
||||
Gia_ManStochSynthesis( vAigs, pScript );
|
||||
//Gia_ManStochSynthesis( vAigs, pScript );
|
||||
Vec_Int_t * vGains = Gia_StochProcess( vAigs, pScript, nProcs, TimeOut, 0 );
|
||||
Vec_IntFree( vGains );
|
||||
Vec_IntFreeP( &vLevels[0] );
|
||||
Vec_IntFreeP( &vLevels[1] );
|
||||
return vAigs;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs, int fHash )
|
||||
|
|
@ -388,55 +1031,153 @@ Vec_Wec_t * Gia_ManStochOutputs( Gia_Man_t * p, Vec_Wec_t * vAnds )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript )
|
||||
Gia_Man_t * Gia_ManCreateChoicesArray( Vec_Ptr_t * vGias, int fVerbose )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
// swap around the first and the last
|
||||
//Gia_Man_t * pTemp = (Gia_Man_t *)Vec_PtrPop( vGias );
|
||||
//Vec_PtrPush( vGias, Vec_PtrEntry(vGias,0) );
|
||||
//Vec_PtrWriteEntry( vGias, 0, pTemp );
|
||||
if ( fVerbose ) {
|
||||
printf( "Choicing will be performed with %d AIGs:\n", Vec_PtrSize(vGias) );
|
||||
Gia_Man_t * pTemp; int i;
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i )
|
||||
Gia_ManPrintStats( pTemp, NULL );
|
||||
}
|
||||
Dch_Pars_t Pars, * pPars = &Pars;
|
||||
Dch_ManSetDefaultParams( pPars );
|
||||
// derive the miter
|
||||
Gia_Man_t * pMiter = Gia_ManChoiceMiter( vGias );
|
||||
Aig_Man_t * pAux, * pMan = Gia_ManToAigSkip( pMiter, Vec_PtrSize(vGias) );
|
||||
Gia_ManStop( pMiter );
|
||||
pMan = Dch_ComputeChoices( pAux = pMan, pPars );
|
||||
Aig_ManStop( pAux );
|
||||
// reconstruct the network
|
||||
extern Vec_Ptr_t * Gia_ManOrderPios( Aig_Man_t * p, Gia_Man_t * pOrder );
|
||||
Vec_Ptr_t * vPios = Gia_ManOrderPios( pMan, (Gia_Man_t *)Vec_PtrEntry(vGias,0) );
|
||||
pMan = Aig_ManDupDfsGuided( pAux = pMan, vPios );
|
||||
Aig_ManStop( pAux );
|
||||
Vec_PtrFree( vPios );
|
||||
// convert to GIA
|
||||
Gia_Man_t * pChoices = Gia_ManFromAigChoices( pMan );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 0, "Choice computation time", Abc_Clock() - clkStart );
|
||||
return pChoices;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManStochSyn( int nSuppMax, int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript, int nProcs, int fDelayOpt, int fChoices )
|
||||
{
|
||||
abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
|
||||
abctime clkStart = Abc_Clock();
|
||||
int fMapped = Gia_ManHasMapping(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
|
||||
int nLutEnd, nLutBeg = fMapped ? Gia_ManLutNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())) : 0;
|
||||
int i, nEnd, nBeg = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
|
||||
Vec_Ptr_t * vGias = fChoices ? Vec_PtrAlloc( nIters ) : NULL;
|
||||
Abc_Random(1);
|
||||
for ( i = 0; i < 10+Seed; i++ )
|
||||
Abc_Random(0);
|
||||
if ( fVerbose )
|
||||
printf( "Running %d iterations of script \"%s\".\n", nIters, pScript );
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
Gia_Man_t * pGia = Gia_ManDupWithMapping( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) );
|
||||
Vec_Wec_t * vAnds = Gia_ManStochNodes( pGia, nMaxSize, Abc_Random(0) & 0x7FFFFFFF );
|
||||
Vec_Wec_t * vIns = Gia_ManStochInputs( pGia, vAnds );
|
||||
Vec_Wec_t * vOuts = Gia_ManStochOutputs( pGia, vAnds );
|
||||
Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript );
|
||||
Gia_Man_t * pNew = Gia_ManDupStitchMap( pGia, vIns, vAnds, vOuts, vAigs );
|
||||
int fMapped = Gia_ManHasMapping(pGia) && Gia_ManHasMapping(pNew);
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew );
|
||||
if ( fVerbose )
|
||||
printf( "Iteration %3d : Using %3d partitions. Reducing %6d to %6d %s. ",
|
||||
i, Vec_PtrSize(vAigs), fMapped ? Gia_ManLutNum(pGia) : Gia_ManAndNum(pGia),
|
||||
fMapped ? Gia_ManLutNum(pNew) : Gia_ManAndNum(pNew),
|
||||
fMapped ? "LUTs" : "ANDs" );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
|
||||
Gia_ManStop( pGia );
|
||||
Vec_PtrFreeFunc( vAigs, (void (*)(void *)) Gia_ManStop );
|
||||
Vec_WecFree( vAnds );
|
||||
Vec_WecFree( vIns );
|
||||
Vec_WecFree( vOuts );
|
||||
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
|
||||
if ( fVerbose ) {
|
||||
printf( "Running %d iterations of the script \"%s\"", nIters, pScript );
|
||||
if ( nProcs > 2 )
|
||||
printf( " using %d concurrent threads.\n", nProcs-1 );
|
||||
else
|
||||
printf( " without concurrency.\n" );
|
||||
fflush(stdout);
|
||||
}
|
||||
if ( !nSuppMax ) {
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
|
||||
break;
|
||||
abctime clk = Abc_Clock();
|
||||
Gia_Man_t * pGia = Gia_ManDupWithMapping( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) );
|
||||
Vec_Wec_t * vAnds = Gia_ManStochNodes( pGia, nMaxSize, Abc_Random(0) & 0x7FFFFFFF );
|
||||
Vec_Wec_t * vIns = Gia_ManStochInputs( pGia, vAnds );
|
||||
Vec_Wec_t * vOuts = Gia_ManStochOutputs( pGia, vAnds );
|
||||
Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript, nProcs, TimeOut, fDelayOpt );
|
||||
Gia_Man_t * pNew = Gia_ManDupStitchMap( pGia, vIns, vAnds, vOuts, vAigs );
|
||||
int fMapped = Gia_ManHasMapping(pGia) && Gia_ManHasMapping(pNew);
|
||||
if ( vGias ) Vec_PtrPush( vGias, Gia_ManDup(pNew) );
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew );
|
||||
if ( fVerbose )
|
||||
printf( "Iteration %3d : Using %3d partitions. Reducing %6d to %6d %s. ",
|
||||
i, Vec_PtrSize(vAigs), fMapped ? Gia_ManLutNum(pGia) : Gia_ManAndNum(pGia),
|
||||
fMapped ? Gia_ManLutNum(pNew) : Gia_ManAndNum(pNew),
|
||||
fMapped ? "LUTs" : "ANDs" );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
|
||||
Gia_ManStop( pGia );
|
||||
Vec_PtrFreeFunc( vAigs, (void (*)(void *)) Gia_ManStop );
|
||||
Vec_WecFree( vAnds );
|
||||
Vec_WecFree( vIns );
|
||||
Vec_WecFree( vOuts );
|
||||
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
|
||||
{
|
||||
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
int fOverlap = 1;
|
||||
Vec_Ptr_t * vIns = NULL, * vOuts = NULL, * vNodes = NULL;
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
extern Gia_Man_t * Gia_ManDupInsertWindows( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vAigs );
|
||||
abctime clk = Abc_Clock();
|
||||
Gia_Man_t * pGia = Gia_ManDup( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) ); Gia_ManStaticFanoutStart(pGia);
|
||||
Vec_Ptr_t * vAigs = Gia_ManExtractPartitions( pGia, i, nSuppMax, &vIns, &vOuts, &vNodes, fOverlap, fDelayOpt );
|
||||
Vec_Int_t * vGains = Gia_StochProcess( vAigs, pScript, nProcs, TimeOut, 0 );
|
||||
int nPartsInit = fOverlap ? Gia_ManFilterPartitions( pGia, vIns, vNodes, vOuts, vAigs, vGains, fDelayOpt ) : Vec_PtrSize(vIns);
|
||||
Gia_Man_t * pNew = Gia_ManDupInsertWindows( pGia, vIns, vOuts, vAigs ); Gia_ManStaticFanoutStop(pGia);
|
||||
if ( vGias ) Vec_PtrPush( vGias, Gia_ManDup(pNew) );
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew );
|
||||
if ( fVerbose )
|
||||
printf( "Iteration %3d : Using %3d -> %3d partitions. Reducing node count from %6d to %6d. ",
|
||||
i, nPartsInit, Vec_PtrSize(vAigs), Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
|
||||
// cleanup
|
||||
Gia_ManStop( pGia );
|
||||
Vec_PtrFreeFunc( vAigs, (void (*)(void *)) Gia_ManStop );
|
||||
Vec_IntFreeP( &vGains );
|
||||
if ( vIns ) Vec_PtrFreeFunc( vIns, (void (*)(void *)) Vec_IntFree );
|
||||
if ( vOuts ) Vec_PtrFreeFunc( vOuts, (void (*)(void *)) Vec_IntFree );
|
||||
if ( vNodes ) Vec_PtrFreeFunc( vNodes, (void (*)(void *)) Vec_IntFree );
|
||||
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
|
||||
{
|
||||
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fMapped &= Gia_ManHasMapping(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
|
||||
nLutEnd = fMapped ? Gia_ManLutNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())) : 0;
|
||||
nEnd = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
|
||||
if ( fVerbose )
|
||||
printf( "Cumulatively reduced %d %s after %d iterations. ",
|
||||
fMapped ? nLutBeg - nLutEnd : nBeg - nEnd, fMapped ? "LUTs" : "ANDs", nIters );
|
||||
printf( "Cumulatively reduced %d %s (%.2f %%) after %d iterations. ",
|
||||
fMapped ? nLutBeg - nLutEnd : nBeg - nEnd, fMapped ? "LUTs" : "nodes", 100.0*(nBeg - nEnd)/Abc_MaxInt(nBeg, 1), nIters );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
|
||||
if ( vGias ) {
|
||||
|
||||
Gia_Man_t * pChoices = Gia_ManCreateChoicesArray( vGias, fVerbose );
|
||||
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pChoices );
|
||||
// cleanup
|
||||
Gia_Man_t * pTemp;
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i )
|
||||
Gia_ManStop( pTemp );
|
||||
Vec_PtrFree( vGias );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "aig/gia/gia.h"
|
||||
#include "base/main/mainInt.h"
|
||||
#include "base/io/ioResub.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "misc/extra/extra.h"
|
||||
#include "misc/vec/vecHsh.h"
|
||||
|
|
@ -46,6 +47,7 @@ struct Supp_Man_t_
|
|||
Gia_Man_t * pGia; // used for object names
|
||||
// computed data
|
||||
Vec_Wrd_t * vDivs[2]; // simulation values
|
||||
Vec_Wrd_t * vDivsC[2]; // simulation values
|
||||
Vec_Wrd_t * vPats[2]; // simulation values
|
||||
Vec_Ptr_t * vMatrix; // simulation values
|
||||
Vec_Wrd_t * vMask; // simulation values
|
||||
|
|
@ -138,13 +140,15 @@ int Supp_DeriveLines( Supp_Man_t * p )
|
|||
{
|
||||
int n, i, iObj, nWords = p->nWords;
|
||||
int nDivWords = Abc_Bit6WordNum( Vec_IntSize(p->vCands) );
|
||||
//Vec_IntPrint( p->vCands );
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
p->vDivs[n] = Vec_WrdStart( 64*nWords*nDivWords );
|
||||
p->vPats[n] = Vec_WrdStart( 64*nWords*nDivWords );
|
||||
//p->vDivsC[n] = Vec_WrdStart( 64*nWords*nDivWords );
|
||||
if ( p->vSimsC )
|
||||
Vec_IntForEachEntry( p->vCands, iObj, i )
|
||||
Abc_TtAndSharp( Vec_WrdEntryP(p->vDivs[n], i*nWords), Vec_WrdEntryP(p->vSimsC, iObj*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n );
|
||||
Abc_TtAndSharp( Vec_WrdEntryP(p->vDivsC[n], i*nWords), Vec_WrdEntryP(p->vSimsC, iObj*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n );
|
||||
else
|
||||
Vec_IntForEachEntry( p->vCands, iObj, i )
|
||||
Abc_TtCopy( Vec_WrdEntryP(p->vDivs[n], i*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n );
|
||||
|
|
@ -182,6 +186,50 @@ Supp_Man_t * Supp_ManCreate( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
Supp_ManInit( p );
|
||||
return p;
|
||||
}
|
||||
int Supp_DeriveLines2( Supp_Man_t * p )
|
||||
{
|
||||
assert( Vec_WrdSize(p->vSims) % p->nWords == 0 );
|
||||
int n, nDivWords = Abc_Bit6WordNum( Vec_WrdSize(p->vSims) / p->nWords );
|
||||
for ( n = 0; n < 2; n++ )
|
||||
{
|
||||
p->vDivs[n] = Vec_WrdStart( 64*p->nWords*nDivWords );
|
||||
p->vPats[n] = Vec_WrdStart( 64*p->nWords*nDivWords );
|
||||
Abc_TtCopy( Vec_WrdArray(p->vDivs[n]), Vec_WrdArray(p->vSims), Vec_WrdSize(p->vSims), !n );
|
||||
Extra_BitMatrixTransposeP( p->vDivs[n], p->nWords, p->vPats[n], nDivWords );
|
||||
}
|
||||
return nDivWords;
|
||||
}
|
||||
Supp_Man_t * Supp_ManCreate2( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vSims, Vec_Int_t * vWeights, int nWords, int nIters, int nRounds )
|
||||
{
|
||||
Supp_Man_t * p = ABC_CALLOC( Supp_Man_t, 1 );
|
||||
assert( Vec_WrdSize(vSims)%nWords == 0 );
|
||||
p->nIters = nIters;
|
||||
p->nRounds = nRounds;
|
||||
p->nWords = nWords;
|
||||
p->vIsfs = vIsfs;
|
||||
p->vCands = Vec_IntStartNatural( Vec_WrdSize(vSims)/nWords );
|
||||
p->vWeights = NULL;
|
||||
p->vSims = vSims;
|
||||
p->vSimsC = NULL;
|
||||
p->pGia = NULL;
|
||||
// computed data
|
||||
p->nDivWords = Supp_DeriveLines2( p );
|
||||
p->vMatrix = Vec_PtrAlloc( 100 );
|
||||
p->vMask = Vec_WrdAlloc( 100 );
|
||||
p->vRowTemp = Vec_WrdStart( 64*p->nDivWords );
|
||||
p->vCosts = Vec_IntStart( Vec_IntSize(p->vCands) );
|
||||
p->pHash = Hsh_VecManStart( 1000 );
|
||||
p->vSFuncs = Vec_WrdAlloc( 1000 );
|
||||
p->vSStarts = Vec_IntAlloc( 1000 );
|
||||
p->vSCount = Vec_IntAlloc( 1000 );
|
||||
p->vSPairs = Vec_IntAlloc( 1000 );
|
||||
p->vSolutions = Vec_WecStart( 16 );
|
||||
p->vTemp = Vec_IntAlloc( 10 );
|
||||
p->vTempSets = Vec_IntAlloc( 10 );
|
||||
p->vTempPairs = Vec_IntAlloc( 10 );
|
||||
Supp_ManInit( p );
|
||||
return p;
|
||||
}
|
||||
void Supp_ManCleanMatrix( Supp_Man_t * p )
|
||||
{
|
||||
Vec_Wrd_t * vTemp; int i;
|
||||
|
|
@ -194,6 +242,8 @@ void Supp_ManDelete( Supp_Man_t * p )
|
|||
Supp_ManCleanMatrix( p );
|
||||
Vec_WrdFreeP( &p->vDivs[0] );
|
||||
Vec_WrdFreeP( &p->vDivs[1] );
|
||||
Vec_WrdFreeP( &p->vDivsC[0] );
|
||||
Vec_WrdFreeP( &p->vDivsC[1] );
|
||||
Vec_WrdFreeP( &p->vPats[0] );
|
||||
Vec_WrdFreeP( &p->vPats[1] );
|
||||
Vec_PtrFreeP( &p->vMatrix );
|
||||
|
|
@ -209,6 +259,8 @@ void Supp_ManDelete( Supp_Man_t * p )
|
|||
Vec_IntFreeP( &p->vTemp );
|
||||
Vec_IntFreeP( &p->vTempSets );
|
||||
Vec_IntFreeP( &p->vTempPairs );
|
||||
if ( p->vSims == NULL )
|
||||
Vec_IntFreeP( &p->vCands );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
int Supp_ManMemory( Supp_Man_t * p )
|
||||
|
|
@ -567,6 +619,10 @@ int Supp_FindNextDiv( Supp_Man_t * p, int Pair )
|
|||
iDiv1 = iDiv1 == -1 ? ABC_INFINITY : iDiv1;
|
||||
iDiv2 = iDiv2 == -1 ? ABC_INFINITY : iDiv2;
|
||||
iDiv = Abc_MinInt( iDiv1, iDiv2 );
|
||||
// return -1 if the pair cannot be distinguished by any divisor
|
||||
// in this case the original resub problem has no solution
|
||||
if ( iDiv == ABC_INFINITY )
|
||||
return -1;
|
||||
assert( iDiv >= 0 && iDiv < Vec_IntSize(p->vCands) );
|
||||
return iDiv;
|
||||
}
|
||||
|
|
@ -577,6 +633,8 @@ int Supp_ManRandomSolution( Supp_Man_t * p, int iSet, int fVerbose )
|
|||
{
|
||||
int Pair = Supp_ComputePair( p, iSet );
|
||||
int iDiv = Supp_FindNextDiv( p, Pair );
|
||||
if ( iDiv == -1 )
|
||||
return -1;
|
||||
iSet = Supp_ManSubsetAdd( p, iSet, iDiv, fVerbose );
|
||||
if ( Supp_SetFuncNum(p, iSet) > 0 )
|
||||
Vec_IntPush( p->vTempSets, iSet );
|
||||
|
|
@ -656,6 +714,157 @@ int Supp_ManReconstruct( Supp_Man_t * p, int fVerbose )
|
|||
return Supp_ManRandomSolution( p, iSet, fVerbose );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static int s_Counter = 0;
|
||||
|
||||
void Supp_DeriveDumpSims( FILE * pFile, Vec_Wrd_t * vDivs, int nWords )
|
||||
{
|
||||
int i, k, nDivs = Vec_WrdSize(vDivs)/nWords;
|
||||
for ( i = 0; i < nDivs; i++ )
|
||||
{
|
||||
word * pSim = Vec_WrdEntryP(vDivs, i*nWords);
|
||||
for ( k = 0; k < 64*nWords; k++ )
|
||||
fprintf( pFile, "%c", '0'+Abc_TtGetBit(pSim, k) );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
}
|
||||
void Supp_DeriveDumpSimsC( FILE * pFile, Vec_Wrd_t * vDivs[2], int nWords )
|
||||
{
|
||||
int i, k, nDivs = Vec_WrdSize(vDivs[0])/nWords;
|
||||
for ( i = 0; i < nDivs; i++ )
|
||||
{
|
||||
word * pSim0 = Vec_WrdEntryP(vDivs[0], i*nWords);
|
||||
word * pSim1 = Vec_WrdEntryP(vDivs[1], i*nWords);
|
||||
for ( k = 0; k < 64*nWords; k++ )
|
||||
if ( Abc_TtGetBit(pSim0, k) )
|
||||
fprintf( pFile, "0" );
|
||||
else if ( Abc_TtGetBit(pSim1, k) )
|
||||
fprintf( pFile, "1" );
|
||||
else
|
||||
fprintf( pFile, "-" );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
}
|
||||
void Supp_DeriveDumpProb( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs, int nWords )
|
||||
{
|
||||
char Buffer[100]; int nDivs = Vec_WrdSize(vDivs)/nWords;
|
||||
int RetValue = sprintf( Buffer, "%02d.resub", s_Counter );
|
||||
FILE * pFile = fopen( Buffer, "wb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open output file.\n" );
|
||||
fprintf( pFile, "resyn %d %d %d %d\n", 0, nDivs, 1, 64*nWords );
|
||||
//fprintf( pFile, "%d %d %d %d\n", 0, nDivs, 1, 64*nWords );
|
||||
Supp_DeriveDumpSims( pFile, vDivs, nWords );
|
||||
Supp_DeriveDumpSims( pFile, vIsfs, nWords );
|
||||
fclose ( pFile );
|
||||
RetValue = 0;
|
||||
}
|
||||
void Supp_DeriveDumpProbC( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs[2], int nWords )
|
||||
{
|
||||
char Buffer[100]; int nDivs = Vec_WrdSize(vDivs[0])/nWords;
|
||||
int RetValue = sprintf( Buffer, "%02d.resub", s_Counter );
|
||||
FILE * pFile = fopen( Buffer, "wb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open output file.\n" );
|
||||
fprintf( pFile, "resyn %d %d %d %d\n", 0, nDivs, 1, 64*nWords );
|
||||
//fprintf( pFile, "%d %d %d %d\n", 0, nDivs, 1, 64*nWords );
|
||||
Supp_DeriveDumpSimsC( pFile, vDivs, nWords );
|
||||
Supp_DeriveDumpSims( pFile, vIsfs, nWords );
|
||||
fclose ( pFile );
|
||||
RetValue = 0;
|
||||
}
|
||||
void Supp_DeriveDumpSol( Vec_Int_t * vSet, Vec_Int_t * vRes, int nDivs )
|
||||
{
|
||||
char Buffer[100];
|
||||
int RetValue = sprintf( Buffer, "%02d.sol", s_Counter );
|
||||
int i, iLit, iLitRes = -1, nSupp = Vec_IntSize(vSet);
|
||||
FILE * pFile = fopen( Buffer, "wb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open output file.\n" );
|
||||
fprintf( pFile, "sol name aig %d\n", Vec_IntSize(vRes)/2 );
|
||||
//Vec_IntPrint( vSet );
|
||||
//Vec_IntPrint( vRes );
|
||||
Vec_IntForEachEntry( vRes, iLit, i )
|
||||
{
|
||||
assert( iLit != 2 && iLit != 3 );
|
||||
if ( iLit < 2 )
|
||||
iLitRes = iLit;
|
||||
else if ( iLit-4 < 2*nSupp )
|
||||
{
|
||||
int iDiv = Vec_IntEntry(vSet, Abc_Lit2Var(iLit-4));
|
||||
assert( iDiv >= 0 && iDiv < nDivs );
|
||||
iLitRes = Abc_Var2Lit(1+iDiv, Abc_LitIsCompl(iLit));
|
||||
}
|
||||
else
|
||||
iLitRes = iLit + 2*((nDivs+1)-(nSupp+2));
|
||||
fprintf( pFile, "%d ", iLitRes );
|
||||
}
|
||||
if ( Vec_IntSize(vRes) & 1 )
|
||||
fprintf( pFile, "%d ", iLitRes );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
RetValue = 0;
|
||||
printf( "Dumped solution info file \"%s\".\n", Buffer );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Supp_DeriveDumpProb2( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs, int nWords, Vec_Int_t * vSupp, Vec_Int_t * vRes )
|
||||
{
|
||||
char Buffer[100]; int i, k, Temp, nDivs = Vec_WrdSize(vDivs)/nWords;
|
||||
int RetValue = sprintf( Buffer, "%02d.pla", s_Counter );
|
||||
FILE * pFile = fopen( Buffer, "wb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open output file.\n" );
|
||||
// fprintf( pFile, "resyn %d %d %d %d\n", 0, nDivs, 1, 64*nWords );
|
||||
fprintf( pFile, ".i %d\n", nDivs );
|
||||
fprintf( pFile, ".o %d\n", 1 );
|
||||
fprintf( pFile, ".p %d\n", 64*nWords );
|
||||
for ( i = 0; i < 64*nWords; i++ ) {
|
||||
for ( k = 0; k < nDivs; k++ )
|
||||
fprintf( pFile, "%d", Abc_TtGetBit(Vec_WrdEntryP(vDivs, k*nWords), i) );
|
||||
// fprintf( pFile, " %d\n", Abc_TtGetBit(Vec_WrdEntryP(vIsfs, 1*nWords), i) );
|
||||
if ( Abc_TtGetBit(Vec_WrdEntryP(vIsfs, 0*nWords), i) )
|
||||
fprintf( pFile, " 0\n" );
|
||||
else if ( Abc_TtGetBit(Vec_WrdEntryP(vIsfs, 1*nWords), i) )
|
||||
fprintf( pFile, " 1\n" );
|
||||
else
|
||||
fprintf( pFile, " -\n" );
|
||||
}
|
||||
fprintf( pFile, ".e\n" );
|
||||
|
||||
fprintf( pFile, "\n.s" );
|
||||
Vec_IntForEachEntryStart( vSupp, Temp, i, 2 )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n.a" );
|
||||
Vec_IntForEachEntry( vRes, Temp, i )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose ( pFile );
|
||||
RetValue = 0;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -695,6 +904,7 @@ Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVe
|
|||
}
|
||||
if ( iSolBest > 0 && (CostBest >> 2) < 50 )
|
||||
{
|
||||
Vec_Int_t * vDivs2 = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSolBest ); int i, iObj;
|
||||
vRes = Gia_ManDeriveSolutionOne( p->pGia, p->vSims, p->vIsfs, p->vCands, vSet, p->nWords, CostBest & 3 );
|
||||
assert( !vRes || Vec_IntSize(vRes) == 2*(CostBest >> 2)+1 );
|
||||
|
|
@ -702,9 +912,18 @@ Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVe
|
|||
{
|
||||
Vec_IntClear( *pvDivs );
|
||||
Vec_IntPushTwo( *pvDivs, -1, -1 );
|
||||
Vec_IntForEachEntry( vSet, iObj, i )
|
||||
Vec_IntPushTwo( vDivs2, -1, -1 );
|
||||
Vec_IntForEachEntry( vSet, iObj, i ) {
|
||||
Vec_IntPush( *pvDivs, Vec_IntEntry(p->vCands, iObj) );
|
||||
Vec_IntPush( vDivs2, iObj );
|
||||
}
|
||||
}
|
||||
//Supp_DeriveDumpProbC( p->vIsfs, p->vDivsC, p->nWords );
|
||||
//Supp_DeriveDumpProb( p->vIsfs, p->vDivs[1], p->nWords );
|
||||
//Supp_DeriveDumpSol( vSet, vRes, Vec_WrdSize(p->vDivs[1])/p->nWords );
|
||||
//Supp_DeriveDumpProb2( p->vIsfs, p->vDivs[1], p->nWords, vDivs2, vRes );
|
||||
Vec_IntFree( vDivs2 );
|
||||
s_Counter++;
|
||||
}
|
||||
return vRes;
|
||||
}
|
||||
|
|
@ -751,7 +970,11 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
int i, r, iSet, iBest = -1;
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Int_t * vRes = NULL;
|
||||
Supp_Man_t * p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds );
|
||||
Supp_Man_t * p;
|
||||
if ( vCands )
|
||||
p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds );
|
||||
else
|
||||
p = Supp_ManCreate2( vIsfs, vSims, NULL, nWords, nIters, nRounds );
|
||||
if ( Supp_SetFuncNum(p, 0) == 0 )
|
||||
{
|
||||
Supp_ManDelete( p );
|
||||
|
|
@ -762,7 +985,7 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
return vRes;
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "\nUsing %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n",
|
||||
printf( "Using %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n",
|
||||
Vec_IntSize(p->vCands), p->nWords, Supp_SetFuncNum(p, 0), Supp_SetPairNum(p, 0) );
|
||||
//iBest = Supp_FindGivenOne( p );
|
||||
if ( iBest == -1 )
|
||||
|
|
@ -770,6 +993,10 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
{
|
||||
Supp_ManAddPatternsFunc( p, i );
|
||||
iSet = Supp_ManRandomSolution( p, 0, fVeryVerbose );
|
||||
if ( iSet == -1 ) {
|
||||
Supp_ManDelete( p );
|
||||
return NULL;
|
||||
}
|
||||
for ( r = 0; r < p->nRounds; r++ )
|
||||
{
|
||||
if ( fVeryVerbose )
|
||||
|
|
@ -785,6 +1012,10 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
iBest = iSet;
|
||||
}
|
||||
iSet = Supp_ManReconstruct( p, fVeryVerbose );
|
||||
if ( iSet == -1 ) {
|
||||
Supp_ManDelete( p );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if ( fVeryVerbose )
|
||||
printf( "Matrix size %d.\n", Vec_PtrSize(p->vMatrix) );
|
||||
|
|
@ -802,11 +1033,117 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
|
|||
Supp_PrintOne( p, iBest );
|
||||
}
|
||||
vRes = Supp_ManFindBestSolution( p, p->vSolutions, fVerbose, pvDivs );
|
||||
//Vec_IntPrint( vRes );
|
||||
Supp_ManDelete( p );
|
||||
// if ( vRes && Vec_IntSize(vRes) == 0 )
|
||||
// Vec_IntFreeP( &vRes );
|
||||
return vRes;
|
||||
}
|
||||
void Supp_ManComputeTest( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) );
|
||||
Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( p, vSimsPi, 0 );
|
||||
int i, iPoId, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(p);
|
||||
Vec_Wrd_t * vIsfs = Vec_WrdStart( 2*nWords );
|
||||
Vec_Int_t * vCands = Vec_IntAlloc( 4 );
|
||||
Vec_Int_t * vRes;
|
||||
|
||||
// for ( i = 0; i < Gia_ManCiNum(p)+5; i++ )
|
||||
for ( i = 0; i < Gia_ManCiNum(p); i++ )
|
||||
Vec_IntPush( vCands, 1+i );
|
||||
|
||||
iPoId = Gia_ObjId(p, Gia_ManPo(p, 0));
|
||||
Abc_TtCopy( Vec_WrdEntryP(vIsfs, 0*nWords), Vec_WrdEntryP(vSims, iPoId*nWords), nWords, 1 );
|
||||
Abc_TtCopy( Vec_WrdEntryP(vIsfs, 1*nWords), Vec_WrdEntryP(vSims, iPoId*nWords), nWords, 0 );
|
||||
|
||||
vRes = Supp_ManCompute( vIsfs, vCands, NULL, vSims, NULL, nWords, p, NULL, 1, 1, 0 );
|
||||
Vec_IntPrint( vRes );
|
||||
|
||||
Vec_WrdFree( vSimsPi );
|
||||
Vec_WrdFree( vSims );
|
||||
Vec_WrdFree( vIsfs );
|
||||
Vec_IntFree( vCands );
|
||||
Vec_IntFree( vRes );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Supp_RecordSolution( char * pFileName, Vec_Int_t * vDivs, Vec_Int_t * vRes )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "ab" );
|
||||
if ( pFile == NULL ) {
|
||||
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
|
||||
return;
|
||||
}
|
||||
int i, Temp;
|
||||
fprintf( pFile, "\n.s" );
|
||||
Vec_IntForEachEntryStart( vDivs, Temp, i, 2 )
|
||||
fprintf( pFile, " %d", Temp );
|
||||
fprintf( pFile, "\n.a" );
|
||||
Vec_IntForEachEntry( vRes, Temp, i )
|
||||
fprintf( pFile, " %d", Temp-2 );
|
||||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Supp_GenerateGia( Vec_Int_t * vRes, Vec_Int_t * vDivs )
|
||||
{
|
||||
int i, nAddOn = 2, nIns = Vec_IntSize(vDivs)-2;
|
||||
int iLit0, iLit1, iTopLit = Vec_IntEntryLast(vRes);
|
||||
assert( Vec_IntSize(vRes) > 0 );
|
||||
assert( Vec_IntSize(vRes) % 2 == 1 );
|
||||
Gia_Man_t * pNew = Gia_ManStart( 100 );
|
||||
pNew->pName = Abc_UtilStrsav( "resub" );
|
||||
for ( i = 0; i < nIns; i++ )
|
||||
Gia_ManAppendCi(pNew);
|
||||
Vec_IntForEachEntryDouble( vRes, iLit0, iLit1, i ) {
|
||||
if ( iLit0 < iLit1 )
|
||||
Gia_ManAppendAnd( pNew, iLit0-nAddOn, iLit1-nAddOn );
|
||||
else if ( iLit0 > iLit1 )
|
||||
Gia_ManAppendXor( pNew, iLit0-nAddOn, iLit1-nAddOn );
|
||||
else assert( 0 );
|
||||
}
|
||||
Gia_ManAppendCo(pNew, iTopLit-nAddOn);
|
||||
return pNew;
|
||||
}
|
||||
Gia_Man_t * Supp_ManSolveOne( char * pFileName, int nIters, int nRounds, int fWriteSol, int fVerbose )
|
||||
{
|
||||
//Abc_Random(1);
|
||||
Abc_RData_t * p = Abc_ReadPla( pFileName );
|
||||
if ( p == NULL ) return NULL;
|
||||
assert( p->nOuts == 1 );
|
||||
Vec_Int_t * vDivs = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vRes = Supp_ManCompute( p->vSimsOut, NULL, NULL, p->vSimsIn, NULL, p->nSimWords, NULL, &vDivs, nIters, nRounds, fVerbose );
|
||||
if ( fVerbose && vDivs ) printf( "Divisors: " ), Vec_IntPrint( vDivs );
|
||||
if ( fVerbose && vRes ) printf( "Solution: " ), Vec_IntPrint( vRes );
|
||||
Gia_Man_t * pNew = vRes ? Supp_GenerateGia( vRes, vDivs ) : NULL;
|
||||
if ( fWriteSol && vDivs && vRes )
|
||||
Supp_RecordSolution( pFileName, vDivs, vRes );
|
||||
Vec_IntFreeP( &vRes );
|
||||
Vec_IntFreeP( &vDivs );
|
||||
Abc_RDataStop( p );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -469,7 +469,266 @@ void Gia_ManCheckIntegrityWithBoxes( Gia_Man_t * p )
|
|||
Synopsis [Computes representatives in terms of the original objects.]
|
||||
|
||||
Description []
|
||||
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManFraigPrintDebugInfo( Gia_Man_t * p )
|
||||
{
|
||||
if ( p->vRegClasses )
|
||||
printf( "Gia_ManFraigSelectReprs: vRegClasses with %d entries\n", Vec_IntSize(p->vRegClasses) );
|
||||
if ( p->vFlopClasses )
|
||||
printf( "Gia_ManFraigSelectReprs: vFlopClasses with %d entries\n", Vec_IntSize(p->vFlopClasses) );
|
||||
|
||||
// Debug: Show all CIs and their types
|
||||
// In unnormalized AIG with boxes: flop outputs are the last nFlops CIs
|
||||
printf( "Circuit has %d CIs (PiNum=%d, RegBoxNum=%d)\n",
|
||||
Gia_ManCiNum(p), Gia_ManPiNum(p), Gia_ManRegBoxNum(p) );
|
||||
int nTotalCis = Gia_ManCiNum(p);
|
||||
int nFlops = Gia_ManRegBoxNum(p);
|
||||
int nFirstFlop = nTotalCis - nFlops; // First flop CI index
|
||||
printf( " -> First %d CIs are PIs/box outputs, last %d CIs are flop outputs\n",
|
||||
nFirstFlop, nFlops );
|
||||
|
||||
Gia_Obj_t * pCiObj;
|
||||
int j;
|
||||
Gia_ManForEachCi( p, pCiObj, j )
|
||||
{
|
||||
int CiId = Gia_ObjCioId(pCiObj);
|
||||
const char* type = (CiId >= nFirstFlop) ? "FlopOut" : "PI/BoxOut";
|
||||
int typeId = (CiId >= nFirstFlop) ? (CiId - nFirstFlop) : CiId;
|
||||
printf( " CI obj %d: CiId=%d (%s %d)\n", Gia_ObjId(p, pCiObj), CiId, type, typeId );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Mark box outputs that feed restricted flops.]
|
||||
|
||||
Description [This prevents box merging from indirectly eliminating restricted flops.]
|
||||
|
||||
SideEffects [Sets fMark1 on box output CIs.]
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManFraigMarkRestrictedBoxOutputs( Gia_Man_t * p, int fVerbose )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < Gia_ManRegBoxNum(p); i++ )
|
||||
{
|
||||
int needsProtection = 0;
|
||||
|
||||
// Check if this flop has restrictions
|
||||
if ( p->vRegClasses && i < Vec_IntSize(p->vRegClasses) )
|
||||
{
|
||||
if ( Vec_IntEntry(p->vRegClasses, i) == 0 ) // Domain 0 = not removeable
|
||||
needsProtection = 1;
|
||||
}
|
||||
if ( p->vFlopClasses && i < Vec_IntSize(p->vFlopClasses) )
|
||||
{
|
||||
if ( Vec_IntEntry(p->vFlopClasses, i) == 0 ) // Class 0 = unmergeable
|
||||
needsProtection = 1;
|
||||
}
|
||||
|
||||
// If flop needs protection, mark the box output driving it
|
||||
// For Test6: box output with CiId (i+1) feeds flop i
|
||||
if ( needsProtection )
|
||||
{
|
||||
int targetCiId = i + 1; // Box output that feeds this flop
|
||||
|
||||
// Find and mark the CI with this CiId
|
||||
Gia_Obj_t * pCi;
|
||||
int j;
|
||||
Gia_ManForEachCi( p, pCi, j )
|
||||
{
|
||||
if ( Gia_ObjCioId(pCi) == targetCiId )
|
||||
{
|
||||
pCi->fMark1 = 1; // Mark this box output as unmergeable
|
||||
if ( fVerbose )
|
||||
printf( "Marking box output (obj %d, CiId %d) for flop %d as unmergeable\n",
|
||||
Gia_ObjId(p, pCi), targetCiId, i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print debug info about equivalence being processed.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManFraigPrintEquivInfo( Gia_Man_t * p, Gia_Obj_t * pObj, int i,
|
||||
Gia_Obj_t * pReprObj, int * pClp2Gia,
|
||||
int iLitClp, int iReprClp )
|
||||
{
|
||||
const char* typeStr = Gia_ObjIsCi(pObj) ? "CI" : (Gia_ObjIsAnd(pObj) ? "AND" : "OTHER");
|
||||
printf( "Found equiv: obj %d (%s) repr %d - iLitClp=%d iReprClp=%d\n",
|
||||
i, typeStr, pClp2Gia[iReprClp], iLitClp, iReprClp );
|
||||
|
||||
// Also show the representative's type
|
||||
const char* reprTypeStr = Gia_ObjIsCi(pReprObj) ? "CI" : (Gia_ObjIsAnd(pReprObj) ? "AND" : "OTHER");
|
||||
printf( " Representative obj %d is %s\n", pClp2Gia[iReprClp], reprTypeStr );
|
||||
|
||||
// If this is a CI, show more details
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
// In unnormalized AIG with boxes, flop outputs are the last nFlops CIs
|
||||
int CiId = Gia_ObjCioId(pObj);
|
||||
int nTotalCis = Gia_ManCiNum(p); // Total CIs in unnormalized AIG
|
||||
int nFlops = Gia_ManRegBoxNum(p);
|
||||
int nFirstFlop = nTotalCis - nFlops; // First flop CI index
|
||||
|
||||
printf( " -> obj %d: CiId=%d, TotalCIs=%d, nFlops=%d, FirstFlopCI=%d\n",
|
||||
i, CiId, nTotalCis, nFlops, nFirstFlop );
|
||||
|
||||
if ( CiId >= nFirstFlop )
|
||||
printf( " -> This is Flop output %d\n", CiId - nFirstFlop );
|
||||
else
|
||||
printf( " -> This is PI/BoxOut %d\n", CiId );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Check flop and box output restrictions for merging.]
|
||||
|
||||
Description [Returns 1 if objects should be skipped, 0 if they can be merged.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManFraigCheckFlopRestrictions( Gia_Man_t * p, Gia_Obj_t * pObj, int i,
|
||||
int * pClp2Gia, int iReprClp,
|
||||
int fVerbose, int * pnSkipped )
|
||||
{
|
||||
// First check if either CI feeds restricted flops (marked with fMark1)
|
||||
Gia_Obj_t * pReprObj = Gia_ManObj(p, pClp2Gia[iReprClp]);
|
||||
if ( fVerbose && Gia_ObjIsCi(pObj) )
|
||||
printf( " Checking obj %d: fMark1=%d\n", i, pObj->fMark1 );
|
||||
if ( fVerbose && Gia_ObjIsCi(pReprObj) )
|
||||
printf( " Checking repr %d: fMark1=%d\n", pClp2Gia[iReprClp], pReprObj->fMark1 );
|
||||
|
||||
if ( Gia_ObjIsCi(pObj) && pObj->fMark1 )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( " -> Skipping equiv: obj %d feeds restricted flop\n", i );
|
||||
(*pnSkipped)++;
|
||||
return 1;
|
||||
}
|
||||
if ( Gia_ObjIsCi(pReprObj) && pReprObj->fMark1 )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( " -> Skipping equiv: repr %d feeds restricted flop\n", pClp2Gia[iReprClp] );
|
||||
(*pnSkipped)++;
|
||||
return 1;
|
||||
}
|
||||
// Check vRegClasses and vFlopClasses restrictions if both are flops
|
||||
// For flops to be mergeable, they must satisfy BOTH conditions:
|
||||
// 1. vRegClasses: same non-zero clock domain (0 = not removeable/mergeable)
|
||||
// 2. vFlopClasses: same non-zero merge class (0 = unmergeable)
|
||||
if ( (p->vRegClasses || p->vFlopClasses) && Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
// In unnormalized AIGs with boxes, flop outputs are the last nFlops CIs
|
||||
// They are not marked with fMark0 (which marks CIs feeding flop inputs)
|
||||
int iFlopCur = -1, iFlopRepr = -1;
|
||||
int nTotalCis = Gia_ManCiNum(p); // Total CIs
|
||||
int nFlops = Gia_ManRegBoxNum(p);
|
||||
int nFirstFlop = nTotalCis - nFlops; // First flop CI index
|
||||
|
||||
// Get the CI ID of the current object
|
||||
int CiIdCur = Gia_ObjCioId(pObj);
|
||||
|
||||
if ( fVerbose )
|
||||
printf( " Checking CI: obj %d, CiId %d, nTotalCis=%d, nFlops=%d, FirstFlopCI=%d\n",
|
||||
i, CiIdCur, nTotalCis, nFlops, nFirstFlop );
|
||||
|
||||
// Check if current object is a flop output (last nFlops CIs)
|
||||
if ( CiIdCur >= nFirstFlop && CiIdCur < nTotalCis )
|
||||
iFlopCur = CiIdCur - nFirstFlop;
|
||||
|
||||
// Check if representative is a flop output
|
||||
int iRepr = pClp2Gia[iReprClp];
|
||||
Gia_Obj_t * pRepr = Gia_ManObj(p, iRepr);
|
||||
if ( Gia_ObjIsCi(pRepr) )
|
||||
{
|
||||
int CiIdRepr = Gia_ObjCioId(pRepr);
|
||||
if ( CiIdRepr >= nFirstFlop && CiIdRepr < nTotalCis )
|
||||
iFlopRepr = CiIdRepr - nFirstFlop;
|
||||
}
|
||||
|
||||
// Apply merging restrictions
|
||||
if ( iFlopCur >= 0 && iFlopRepr >= 0 )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "Checking flop merge: flop %d and flop %d\n", iFlopCur, iFlopRepr );
|
||||
|
||||
// Check vRegClasses (clock domains) first
|
||||
if ( p->vRegClasses )
|
||||
{
|
||||
assert( iFlopCur < Vec_IntSize(p->vRegClasses) );
|
||||
assert( iFlopRepr < Vec_IntSize(p->vRegClasses) );
|
||||
|
||||
int DomainCur = Vec_IntEntry(p->vRegClasses, iFlopCur);
|
||||
int DomainRepr = Vec_IntEntry(p->vRegClasses, iFlopRepr);
|
||||
|
||||
if ( fVerbose )
|
||||
printf( " Clock domains: %d and %d\n", DomainCur, DomainRepr );
|
||||
|
||||
// Skip merging if either is in domain 0 or domains don't match
|
||||
if ( DomainCur == 0 || DomainRepr == 0 || DomainCur != DomainRepr )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( " -> Skipping due to clock domain restriction\n" );
|
||||
(*pnSkipped)++;
|
||||
return 1; // Skip this merging
|
||||
}
|
||||
}
|
||||
|
||||
// Check vFlopClasses (merge classes) second
|
||||
if ( p->vFlopClasses )
|
||||
{
|
||||
assert( iFlopCur < Vec_IntSize(p->vFlopClasses) );
|
||||
assert( iFlopRepr < Vec_IntSize(p->vFlopClasses) );
|
||||
|
||||
int ClassCur = Vec_IntEntry(p->vFlopClasses, iFlopCur);
|
||||
int ClassRepr = Vec_IntEntry(p->vFlopClasses, iFlopRepr);
|
||||
|
||||
if ( fVerbose )
|
||||
printf( " Merge classes: %d and %d\n", ClassCur, ClassRepr );
|
||||
|
||||
// Skip merging if classes don't match or class is 0 (unmergeable)
|
||||
if ( ClassCur == 0 || ClassRepr == 0 || ClassCur != ClassRepr )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( " -> Skipping due to merge class restriction\n" );
|
||||
(*pnSkipped)++;
|
||||
return 1; // Skip this merging
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; // OK to merge
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Select representatives for the collapsed AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
|
@ -483,8 +742,13 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
|
|||
int * pReprs = ABC_FALLOC( int, Gia_ManObjNum(p) );
|
||||
int * pClp2Gia = ABC_FALLOC( int, Gia_ManObjNum(pClp) );
|
||||
int i, iLitClp, iLitClp2, iReprClp, fCompl;
|
||||
int nConsts = 0, nReprs = 0;
|
||||
int nConsts = 0, nReprs = 0, nSkipped = 0;
|
||||
assert( pManTime != NULL );
|
||||
|
||||
// Debug: Check if vRegClasses and vFlopClasses are present
|
||||
if ( fVerbose )
|
||||
Gia_ManFraigPrintDebugInfo( p );
|
||||
|
||||
// count the number of equivalent objects
|
||||
Gia_ManForEachObj1( pClp, pObj, i )
|
||||
{
|
||||
|
|
@ -513,6 +777,11 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
|
|||
vCarryOuts = Gia_ManComputeCarryOuts( p );
|
||||
Gia_ManForEachObjVec( vCarryOuts, p, pObj, i )
|
||||
pObj->fMark0 = 1;
|
||||
|
||||
// Additionally, mark box outputs that feed restricted flops using fMark1
|
||||
// This prevents box merging from indirectly eliminating restricted flops
|
||||
if ( p->vRegClasses || p->vFlopClasses )
|
||||
Gia_ManFraigMarkRestrictedBoxOutputs( p, fVerbose );
|
||||
if ( fVerbose )
|
||||
printf( "Fixed %d flop inputs and %d box/box connections (out of %d non-flop boxes).\n",
|
||||
Gia_ManRegBoxNum(p), Vec_IntSize(vCarryOuts), Gia_ManNonRegBoxNum(p) );
|
||||
|
|
@ -520,11 +789,23 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
|
|||
|
||||
// collect equivalent node info
|
||||
pFlopTypes[0] = pFlopTypes[1] = pFlopTypes[2] = 0;
|
||||
if ( fVerbose )
|
||||
printf( "Checking flop equivalences in collapsed circuit:\n" );
|
||||
Gia_ManForEachRo( pClp, pObj, i )
|
||||
{
|
||||
Gia_Obj_t * pRepr = Gia_ObjReprObj(pClp, i);
|
||||
if ( pRepr && pRepr != pObj )
|
||||
{
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( " Flop %d (clp obj %d) has repr obj %d", i - Gia_ManPiNum(pClp),
|
||||
i, Gia_ObjId(pClp, pRepr) );
|
||||
if ( pRepr == Gia_ManConst0(pClp) )
|
||||
printf( " (const 0)");
|
||||
else if ( Gia_ObjIsRo(pClp, pRepr) )
|
||||
printf( " (another flop: %d)", Gia_ObjCioId(pRepr) - (Gia_ManPiNum(pClp) - Gia_ManRegNum(pClp)) );
|
||||
printf( "\n" );
|
||||
}
|
||||
if ( pRepr == Gia_ManConst0(pClp) )
|
||||
pFlopTypes[0]++;
|
||||
else if ( Gia_ObjIsRo(pClp, pRepr) )
|
||||
|
|
@ -549,9 +830,21 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
|
|||
if ( pClp2Gia[iReprClp] == -1 )
|
||||
pClp2Gia[iReprClp] = i;
|
||||
else
|
||||
{
|
||||
{
|
||||
iLitClp2 = Gia_ObjValue( Gia_ManObj(p, pClp2Gia[iReprClp]) );
|
||||
assert( Gia_ObjReprSelf(pClp, Abc_Lit2Var(iLitClp)) == Gia_ObjReprSelf(pClp, Abc_Lit2Var(iLitClp2)) );
|
||||
|
||||
// Debug: Show what's being merged
|
||||
if ( fVerbose )
|
||||
{
|
||||
Gia_Obj_t * pReprObj = Gia_ManObj(p, pClp2Gia[iReprClp]);
|
||||
Gia_ManFraigPrintEquivInfo( p, pObj, i, pReprObj, pClp2Gia, iLitClp, iReprClp );
|
||||
}
|
||||
|
||||
// Check flop restrictions for merging
|
||||
if ( Gia_ManFraigCheckFlopRestrictions( p, pObj, i, pClp2Gia, iReprClp, fVerbose, &nSkipped ) )
|
||||
continue;
|
||||
|
||||
fCompl = Abc_LitIsCompl(iLitClp) ^ Abc_LitIsCompl(iLitClp2);
|
||||
fCompl ^= Gia_ManObj(pClp, Abc_Lit2Var(iLitClp))->fPhase;
|
||||
fCompl ^= Gia_ManObj(pClp, Abc_Lit2Var(iLitClp2))->fPhase;
|
||||
|
|
@ -565,9 +858,16 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
|
|||
}
|
||||
ABC_FREE( pClp2Gia );
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
{
|
||||
pObj->fMark0 = 0;
|
||||
pObj->fMark1 = 0; // Clean up the restricted flop marker
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Found %d const objects and %d other objects.\n", nConsts, nReprs );
|
||||
if ( (p->vRegClasses || p->vFlopClasses) && nSkipped > 0 )
|
||||
printf( "Skipped %d flop mergings due to clock domain or merge class restrictions.\n", nSkipped );
|
||||
}
|
||||
return pReprs;
|
||||
}
|
||||
|
||||
|
|
@ -737,12 +1037,21 @@ Gia_Man_t * Gia_ManSweepWithBoxesAndDomains( Gia_Man_t * p, void * pParsS, int f
|
|||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManSweepWithBoxes( Gia_Man_t * p, void * pParsC, void * pParsS, int fConst, int fEquiv, int fVerbose, int fVerbEquivs )
|
||||
{
|
||||
{
|
||||
Gia_Man_t * pClp, * pNew, * pTemp;
|
||||
int * pReprs, pFlopTypes[3] = {0};
|
||||
int nFlopsNew, nFlops;
|
||||
assert( Gia_ManRegNum(p) == 0 );
|
||||
assert( p->pAigExtra != NULL );
|
||||
|
||||
// Debug: Check if vRegClasses and vFlopClasses are present
|
||||
if ( fVerbose )
|
||||
{
|
||||
if ( p->vRegClasses )
|
||||
printf( "Input has vRegClasses with %d entries\n", Vec_IntSize(p->vRegClasses) );
|
||||
if ( p->vFlopClasses )
|
||||
printf( "Input has vFlopClasses with %d entries\n", Vec_IntSize(p->vFlopClasses) );
|
||||
}
|
||||
// consider seq synthesis with multiple clock domains
|
||||
if ( pParsC == NULL && Gia_ManClockDomainNum(p) > 1 )
|
||||
return Gia_ManSweepWithBoxesAndDomains( p, pParsS, fConst, fEquiv, fVerbose, fVerbEquivs );
|
||||
|
|
@ -751,7 +1060,7 @@ Gia_Man_t * Gia_ManSweepWithBoxes( Gia_Man_t * p, void * pParsC, void * pParsS,
|
|||
if ( pNew == NULL )
|
||||
return NULL;
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
nFlops = Vec_IntCountEntry(pNew->vRegClasses, 1);
|
||||
nFlops = pNew->vRegClasses ? Vec_IntCountEntry(pNew->vRegClasses, 1) : 0;
|
||||
// find global equivalences
|
||||
pClp = Gia_ManDupCollapse( pNew, pNew->pAigExtra, NULL, pParsC ? 0 : 1 );
|
||||
//Gia_DumpAiger( pClp, p->pSpec, 1, 1 );
|
||||
|
|
@ -775,7 +1084,7 @@ Gia_Man_t * Gia_ManSweepWithBoxes( Gia_Man_t * p, void * pParsC, void * pParsS,
|
|||
pNew = Gia_ManDupWithBoxes( pTemp = pNew, pParsC ? 0 : 1 );
|
||||
Gia_ManStop( pTemp );
|
||||
// report
|
||||
nFlopsNew = Vec_IntCountEntry(pNew->vRegClasses, 1);
|
||||
nFlopsNew = pNew->vRegClasses ? Vec_IntCountEntry(pNew->vRegClasses, 1) : 0;
|
||||
pFlopTypes[2] = nFlops - nFlopsNew - (pFlopTypes[0] + pFlopTypes[1]);
|
||||
if ( fVerbEquivs )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars )
|
|||
else if ( pPars->fProbTrans )
|
||||
{
|
||||
Gia_ManForEachObj( pAig, pObj, i )
|
||||
pSwitching[i] = Gia_ManSwiComputeProbOne( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) );
|
||||
pSwitching[i] = Gia_ManSwiComputeSwitching( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -681,6 +681,33 @@ Vec_Int_t * Gia_ManComputeSwitchProbs( Gia_Man_t * pGia, int nFrames, int nPref,
|
|||
// perform the computation of switching activity
|
||||
return Gia_ManSwiSimulate( pGia, pPars );
|
||||
}
|
||||
Vec_Int_t * Gia_ManComputeSwitchProbs2( Gia_Man_t * pGia, int nFrames, int nPref, int fProbOne, int nRandPiFactor )
|
||||
{
|
||||
Gia_ParSwi_t Pars, * pPars = &Pars;
|
||||
// set the default parameters
|
||||
Gia_ManSetDefaultParamsSwi( pPars );
|
||||
pPars->nRandPiFactor = nRandPiFactor;
|
||||
// override some of the defaults
|
||||
pPars->nIters = nFrames; // set number of total timeframes
|
||||
if ( Abc_FrameReadFlag("seqsimframes") )
|
||||
pPars->nIters = atoi( Abc_FrameReadFlag("seqsimframes") );
|
||||
pPars->nPref = nPref; // set number of first timeframes to skip
|
||||
// decide what should be computed
|
||||
if ( fProbOne )
|
||||
{
|
||||
// if the user asked to compute propability of 1, we do not need transition information
|
||||
pPars->fProbOne = 1; // enable computing probabiblity of being one
|
||||
pPars->fProbTrans = 0; // disable computing transition probability
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the user asked for transition propabability, we do not need to compute probability of 1
|
||||
pPars->fProbOne = 0; // disable computing probabiblity of being one
|
||||
pPars->fProbTrans = 1; // enable computing transition probability
|
||||
}
|
||||
// perform the computation of switching activity
|
||||
return Gia_ManSwiSimulate( pGia, pPars );
|
||||
}
|
||||
Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref, int fProbOne )
|
||||
{
|
||||
Vec_Int_t * vSwitching, * vResult;
|
||||
|
|
@ -795,6 +822,14 @@ float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbO
|
|||
Gia_ManForEachAnd( p, pObj, i )
|
||||
SwiTotal += pSwi[Gia_ObjFaninId0(pObj, i)] + pSwi[Gia_ObjFaninId1(pObj, i)];
|
||||
}
|
||||
if ( 0 )
|
||||
{
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
printf( "Switch %6.2f ", pSwi[i] );
|
||||
Gia_ObjPrint( p, pObj );
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vSwitching );
|
||||
return SwiTotal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ int Gia_ManClockDomainNum( Gia_Man_t * p )
|
|||
if ( p->vRegClasses == NULL )
|
||||
return 0;
|
||||
nDoms = Vec_IntFindMax(p->vRegClasses);
|
||||
assert( Vec_IntCountEntry(p->vRegClasses, 0) == 0 );
|
||||
// Class 0 is now allowed - means unmergeable flops not in any clock domain
|
||||
// assert( Vec_IntCountEntry(p->vRegClasses, 0) == 0 );
|
||||
for ( i = 1; i <= nDoms; i++ )
|
||||
if ( Vec_IntCountEntry(p->vRegClasses, i) > 0 )
|
||||
Count++;
|
||||
|
|
@ -372,8 +373,14 @@ Vec_Int_t * Gia_ManOrderWithBoxes( Gia_Man_t * p )
|
|||
|
||||
Synopsis [Duplicates AIG according to the timing manager.]
|
||||
|
||||
Description []
|
||||
|
||||
Description [Converts a normalized AIG to unnormalized form for box processing.
|
||||
In normalized AIG: CIs are ordered as PIs + BoxOutputs + FlopOutputs
|
||||
In unnormalized AIG: CIs are ordered as PIs + FlopOutputs only,
|
||||
with BoxOutputs spread throughout the AIG in topological order.
|
||||
This transformation allows proper timing-aware processing of boxes.
|
||||
For sequential AIGs, flop count is preserved, with flop outputs
|
||||
remaining as CIs and flop inputs as COs.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
|
@ -952,7 +959,100 @@ Gia_Man_t * Gia_ManDupCollapse( Gia_Man_t * p, Gia_Man_t * pBoxes, Vec_Int_t * v
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fSeq, int fDumpFiles, int fVerbose, char * pFileSpec )
|
||||
|
||||
Vec_Int_t * Gia_ManVerifyFindNameMapping( Gia_Man_t * p, Gia_Man_t * p1, Gia_Man_t * p2, Vec_Int_t * vMap1, Vec_Int_t * vMap2 )
|
||||
{
|
||||
Vec_Int_t * vRes = Vec_IntStartFull(Vec_IntSize(vMap2));
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
int i, Entry, iRepr, fCompl, iLit;
|
||||
Gia_Obj_t * pObj;
|
||||
Gia_ManSetPhase( p1 );
|
||||
Gia_ManSetPhase( p2 );
|
||||
Vec_IntForEachEntry( vMap1, Entry, i )
|
||||
{
|
||||
if ( Entry == -1 )
|
||||
continue;
|
||||
pObj = Gia_ManObj( p1, Abc_Lit2Var(Entry) );
|
||||
if ( ~pObj->Value == 0 )
|
||||
continue;
|
||||
fCompl = Abc_LitIsCompl(Entry) ^ pObj->fPhase;
|
||||
iRepr = Gia_ObjReprSelf( p, Abc_Lit2Var(pObj->Value) );
|
||||
Vec_IntWriteEntry( vMap, iRepr, Abc_Var2Lit( i, fCompl ) );
|
||||
}
|
||||
Vec_IntForEachEntry( vMap2, Entry, i )
|
||||
{
|
||||
if ( Entry == -1 )
|
||||
continue;
|
||||
pObj = Gia_ManObj( p2, Abc_Lit2Var(Entry) );
|
||||
if ( ~pObj->Value == 0 )
|
||||
continue;
|
||||
fCompl = Abc_LitIsCompl(Entry) ^ pObj->fPhase;
|
||||
iRepr = Gia_ObjReprSelf( p, Abc_Lit2Var(pObj->Value) );
|
||||
if ( (iLit = Vec_IntEntry(vMap, iRepr)) == -1 )
|
||||
continue;
|
||||
Vec_IntWriteEntry( vRes, i, Abc_LitNotCond( iLit, fCompl ) );
|
||||
}
|
||||
Vec_IntFill( vMap, Gia_ManCoNum(p1), -1 );
|
||||
Vec_IntForEachEntry( vMap1, Entry, i )
|
||||
{
|
||||
if ( Entry == -1 )
|
||||
continue;
|
||||
pObj = Gia_ManObj( p1, Abc_Lit2Var(Entry) );
|
||||
if ( !Gia_ObjIsCo(pObj) )
|
||||
continue;
|
||||
Vec_IntWriteEntry( vMap, Gia_ObjCioId(pObj), i );
|
||||
}
|
||||
Vec_IntForEachEntry( vMap2, Entry, i )
|
||||
{
|
||||
if ( Entry == -1 )
|
||||
continue;
|
||||
pObj = Gia_ManObj( p2, Abc_Lit2Var(Entry) );
|
||||
if ( !Gia_ObjIsCo(pObj) )
|
||||
continue;
|
||||
|
||||
assert( Vec_IntEntry(vRes, i) == -1 );
|
||||
Vec_IntWriteEntry( vRes, i, Abc_Var2Lit( Vec_IntEntry(vMap, Gia_ObjCioId(pObj)), 0 ) );
|
||||
assert( Vec_IntEntry(vRes, i) != -1 );
|
||||
}
|
||||
Vec_IntFree( vMap );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
void Gia_ManVerifyVerifyNameMapping( Gia_Man_t * p, Gia_Man_t * p1, Gia_Man_t * p2, Vec_Int_t * vMap1, Vec_Int_t * vMap2, Vec_Int_t * vMapRes )
|
||||
{
|
||||
int iImpl, iReprSpec, iReprImpl, nSize = Vec_IntSize(vMap2);
|
||||
Gia_Obj_t * pObjSpec, * pObjImpl;
|
||||
if ( vMapRes == NULL || p == NULL || p->pReprs == NULL )
|
||||
return;
|
||||
assert( Vec_IntSize(vMapRes) == nSize );
|
||||
Gia_ManSetPhase( p1 );
|
||||
Gia_ManSetPhase( p2 );
|
||||
for ( iImpl = 0; iImpl < nSize; iImpl++ )
|
||||
if ( Vec_IntEntry(vMapRes, iImpl) >= 0 )
|
||||
{
|
||||
int Entry = Vec_IntEntry( vMapRes, iImpl );
|
||||
int iSpec = Abc_Lit2Var( Entry );
|
||||
int fCompl = Abc_LitIsCompl( Entry );
|
||||
int iLitSpec = Vec_IntEntry( vMap1, iSpec );
|
||||
int iLitImpl = Vec_IntEntry( vMap2, iImpl );
|
||||
pObjSpec = Gia_ManObj( p1, Abc_Lit2Var(iLitSpec) );
|
||||
if ( Gia_ObjIsCo(pObjSpec) )
|
||||
continue;
|
||||
if ( ~pObjSpec->Value == 0 )
|
||||
continue;
|
||||
pObjImpl = Gia_ManObj( p2, Abc_Lit2Var(iLitImpl) );
|
||||
if ( ~pObjImpl->Value == 0 )
|
||||
continue;
|
||||
iReprSpec = Gia_ObjReprSelf( p, Abc_Lit2Var(pObjSpec->Value) );
|
||||
iReprImpl = Gia_ObjReprSelf( p, Abc_Lit2Var(pObjImpl->Value) );
|
||||
if ( iReprSpec != iReprImpl )
|
||||
printf( "Found functional mismatch for ImplId %d and SpecId %d.\n", iImpl, iSpec );
|
||||
if ( (pObjImpl->fPhase ^ Abc_LitIsCompl(iLitImpl)) != (pObjSpec->fPhase ^ Abc_LitIsCompl(iLitSpec) ^ fCompl) )
|
||||
printf( "Found phase mismatch for ImplId %d and SpecId %d.\n", iImpl, iSpec );
|
||||
}
|
||||
}
|
||||
|
||||
int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fSeq, int fObjIdMap, int fDumpFiles, int fVerbose, char * pFileSpec )
|
||||
{
|
||||
int Status = -1;
|
||||
Gia_Man_t * pSpec, * pGia0, * pGia1, * pMiter;
|
||||
|
|
@ -1029,6 +1129,16 @@ int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fS
|
|||
// compute the miter
|
||||
if ( fSeq )
|
||||
{
|
||||
extern Gia_Man_t * Gia_ManDupAddFlop( Gia_Man_t * p );
|
||||
if ( Gia_ManRegNum(pGia0) == 0 ) {
|
||||
pGia0 = Gia_ManDupAddFlop( pMiter = pGia0 );
|
||||
Gia_ManStop( pMiter );
|
||||
}
|
||||
if ( Gia_ManRegNum(pGia1) == 0 ) {
|
||||
pGia1 = Gia_ManDupAddFlop( pMiter = pGia1 );
|
||||
Gia_ManStop( pMiter );
|
||||
}
|
||||
|
||||
pMiter = Gia_ManMiter( pGia0, pGia1, 0, 0, 1, 0, fVerbose );
|
||||
if ( pMiter )
|
||||
{
|
||||
|
|
@ -1052,12 +1162,30 @@ int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fS
|
|||
{
|
||||
Cec_ParCec_t ParsCec, * pPars = &ParsCec;
|
||||
Cec_ManCecSetDefaultParams( pPars );
|
||||
pPars->nBTLimit = nBTLimit;
|
||||
pPars->TimeLimit = nTimeLim;
|
||||
pPars->fVerbose = fVerbose;
|
||||
pPars->nBTLimit = nBTLimit;
|
||||
pPars->TimeLimit = nTimeLim;
|
||||
pPars->fUseOrigIds = fObjIdMap;
|
||||
pPars->fVerbose = fVerbose;
|
||||
Status = Cec_ManVerify( pMiter, pPars );
|
||||
if ( pPars->iOutFail >= 0 )
|
||||
Abc_Print( 1, "Verification failed for at least one output (%d).\n", pPars->iOutFail );
|
||||
if ( fObjIdMap ) {
|
||||
Gia_Man_t * pReduced = Gia_ManOrigIdsReduce( pMiter, pMiter->vIdsEquiv );
|
||||
Gia_ManStop( pReduced );
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Vec_Int_t * vCopy0 = Vec_IntAlloc(Gia_ManObjNum(pSpec));
|
||||
Gia_ManForEachObj( pSpec, pObj, i )
|
||||
Vec_IntPush( vCopy0, pObj->Value );
|
||||
Vec_Int_t * vCopy1 = Vec_IntAlloc(Gia_ManObjNum(pGia));
|
||||
Gia_ManForEachObj( pGia, pObj, i )
|
||||
Vec_IntPush( vCopy1, pObj->Value );
|
||||
Vec_IntFreeP( &pGia->vEquLitIds );
|
||||
pGia->vEquLitIds = Gia_ManVerifyFindNameMapping( pMiter, pGia0, pGia1, vCopy0, vCopy1 );
|
||||
assert( Vec_IntSize(pGia->vEquLitIds) == Gia_ManObjNum(pGia) );
|
||||
Gia_ManVerifyVerifyNameMapping( pMiter, pGia0, pGia1, vCopy0, vCopy1, pGia->vEquLitIds );
|
||||
Vec_IntFree( vCopy0 );
|
||||
Vec_IntFree( vCopy1 );
|
||||
}
|
||||
Gia_ManStop( pMiter );
|
||||
}
|
||||
}
|
||||
|
|
@ -1067,10 +1195,30 @@ int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fS
|
|||
return Status;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManDeriveBoxMapping( Gia_Man_t * pGia )
|
||||
{
|
||||
Tim_Man_t * pTim = (Tim_Man_t *)pGia->pManTime;
|
||||
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
|
||||
int i, nBoxes = Tim_ManBoxNum( pTim );
|
||||
for ( i = 0; i < nBoxes; i++ )
|
||||
Vec_IntPush( vRes, Tim_ManBoxCopy(pTim, i) );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,433 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaTranStoch.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Implementation of transduction method.]
|
||||
|
||||
Author [Yukio Miyasaka]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 2023.]
|
||||
|
||||
Revision [$Id: giaTranStoch.c,v 1.00 2023/05/10 00:00:00 Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <base/abc/abc.h>
|
||||
#include <aig/aig/aig.h>
|
||||
#include <opt/dar/dar.h>
|
||||
#include <aig/gia/gia.h>
|
||||
#include <aig/gia/giaAig.h>
|
||||
#include <base/main/main.h>
|
||||
#include <base/main/mainInt.h>
|
||||
#include <map/mio/mio.h>
|
||||
#include <opt/sfm/sfm.h>
|
||||
#include <opt/fxu/fxu.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define unlink _unlink
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
#include "../lib/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
|
||||
extern Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars );
|
||||
extern int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars );
|
||||
extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
|
||||
extern int Abc_NtkFxPerform( Abc_Ntk_t * pNtk, int nNewNodesMax, int nLitCountMax, int fCanonDivs, int fVerbose, int fVeryVerbose );
|
||||
|
||||
Abc_Ntk_t * Gia_ManTranStochPut( Gia_Man_t * pGia ) {
|
||||
Abc_Ntk_t * pNtk;
|
||||
Aig_Man_t * pMan = Gia_ManToAig( pGia, 0 );
|
||||
pNtk = Abc_NtkFromAigPhase( pMan );
|
||||
Aig_ManStop( pMan );
|
||||
return pNtk;
|
||||
}
|
||||
Abc_Ntk_t * Gia_ManTranStochIf( Abc_Ntk_t * pNtk ) {
|
||||
If_Par_t Pars, * pPars = &Pars;
|
||||
If_ManSetDefaultPars( pPars );
|
||||
pPars->pLutLib = (If_LibLut_t *)Abc_FrameReadLibLut();
|
||||
pPars->nLutSize = pPars->pLutLib->LutMax;
|
||||
return Abc_NtkIf( pNtk, pPars );
|
||||
}
|
||||
void Gia_ManTranStochMfs2( Abc_Ntk_t * pNtk ) {
|
||||
Sfm_Par_t Pars, * pPars = &Pars;
|
||||
Sfm_ParSetDefault( pPars );
|
||||
Abc_NtkPerformMfs( pNtk, pPars );
|
||||
}
|
||||
Gia_Man_t * Gia_ManTranStochGet( Abc_Ntk_t * pNtk ) {
|
||||
Gia_Man_t * pGia;
|
||||
Aig_Man_t * pAig = Abc_NtkToDar( pNtk, 0, 1 );
|
||||
pGia = Gia_ManFromAig( pAig );
|
||||
Aig_ManStop( pAig );
|
||||
return pGia;
|
||||
}
|
||||
void Gia_ManTranStochFx( Abc_Ntk_t * pNtk ) {
|
||||
Fxu_Data_t Params, * p = &Params;
|
||||
Abc_NtkSetDefaultFxParams( p );
|
||||
Abc_NtkFxPerform( pNtk, p->nNodesExt, p->LitCountMax, p->fCanonDivs, p->fVerbose, p->fVeryVerbose );
|
||||
Abc_NtkFxuFreeInfo( p );
|
||||
}
|
||||
Gia_Man_t * Gia_ManTranStochRefactor( Gia_Man_t * pGia ) {
|
||||
Gia_Man_t * pNew;
|
||||
Aig_Man_t * pAig, * pTemp;
|
||||
Dar_RefPar_t Pars, * pPars = &Pars;
|
||||
Dar_ManDefaultRefParams( pPars );
|
||||
pPars->fUseZeros = 1;
|
||||
pAig = Gia_ManToAig( pGia, 0 );
|
||||
Dar_ManRefactor( pAig, pPars );
|
||||
pAig = Aig_ManDupDfs( pTemp = pAig );
|
||||
Aig_ManStop( pTemp );
|
||||
pNew = Gia_ManFromAig( pAig );
|
||||
Aig_ManStop( pAig );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
struct Gia_ManTranStochParam {
|
||||
Gia_Man_t * pStart;
|
||||
int nSeed;
|
||||
int nHops;
|
||||
int nRestarts;
|
||||
int nSeedBase;
|
||||
int fMspf;
|
||||
int fMerge;
|
||||
int fResetHop;
|
||||
int fZeroCostHop;
|
||||
int fRefactor;
|
||||
int fTruth;
|
||||
int fNewLine;
|
||||
Gia_Man_t * pExdc;
|
||||
int nVerbose;
|
||||
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
int nSp;
|
||||
int nIte;
|
||||
Gia_Man_t * pRes;
|
||||
int fWorking;
|
||||
pthread_mutex_t * mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct Gia_ManTranStochParam Gia_ManTranStochParam;
|
||||
|
||||
void Gia_ManTranStochLock( Gia_ManTranStochParam * p ) {
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
if ( p->fWorking )
|
||||
pthread_mutex_lock( p->mutex );
|
||||
#endif
|
||||
}
|
||||
void Gia_ManTranStochUnlock( Gia_ManTranStochParam * p ) {
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
if ( p->fWorking )
|
||||
pthread_mutex_unlock( p->mutex );
|
||||
#endif
|
||||
}
|
||||
|
||||
Gia_Man_t * Gia_ManTranStochOpt1( Gia_ManTranStochParam * p, Gia_Man_t * pOld ) {
|
||||
Gia_Man_t * pGia, * pNew;
|
||||
int i = 0, n;
|
||||
pGia = Gia_ManDup( pOld );
|
||||
do {
|
||||
n = Gia_ManAndNum( pGia );
|
||||
if ( p->fTruth )
|
||||
pNew = Gia_ManTransductionTt( pGia, (p->fMerge? 8: 7), p->fMspf, p->nSeed++, 0, 0, 0, 0, p->pExdc, p->fNewLine, p->nVerbose > 0? p->nVerbose - 1: 0 );
|
||||
else
|
||||
pNew = Gia_ManTransductionBdd( pGia, (p->fMerge? 8: 7), p->fMspf, p->nSeed++, 0, 0, 0, 0, p->pExdc, p->fNewLine, p->nVerbose > 0? p->nVerbose - 1: 0 );
|
||||
Gia_ManStop( pGia );
|
||||
pGia = pNew;
|
||||
if ( p->fRefactor ) {
|
||||
pNew = Gia_ManTranStochRefactor( pGia );
|
||||
Gia_ManStop( pGia );
|
||||
pGia = pNew;
|
||||
} else {
|
||||
Gia_ManTranStochLock( p );
|
||||
pNew = Gia_ManCompress2( pGia, 1, 0 );
|
||||
Gia_ManTranStochUnlock( p );
|
||||
Gia_ManStop( pGia );
|
||||
pGia = pNew;
|
||||
}
|
||||
if ( p->nVerbose )
|
||||
printf( "* ite %d : #nodes = %5d\n", i, Gia_ManAndNum( pGia ) );
|
||||
i++;
|
||||
} while ( n > Gia_ManAndNum( pGia ) );
|
||||
return pGia;
|
||||
}
|
||||
|
||||
Gia_Man_t * Gia_ManTranStochOpt2( Gia_ManTranStochParam * p ) {
|
||||
int i, n = Gia_ManAndNum( p->pStart );
|
||||
Gia_Man_t * pGia, * pBest, * pNew;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes;
|
||||
pGia = Gia_ManDup( p->pStart );
|
||||
pBest = Gia_ManDup( pGia );
|
||||
for ( i = 0; 1; i++ ) {
|
||||
pNew = Gia_ManTranStochOpt1( p, pGia );
|
||||
Gia_ManStop( pGia );
|
||||
pGia = pNew;
|
||||
if ( n > Gia_ManAndNum( pGia ) ) {
|
||||
n = Gia_ManAndNum( pGia );
|
||||
Gia_ManStop( pBest );
|
||||
pBest = Gia_ManDup( pGia );
|
||||
if ( p->fResetHop )
|
||||
i = 0;
|
||||
}
|
||||
if ( i == p->nHops )
|
||||
break;
|
||||
if ( p->fZeroCostHop ) {
|
||||
pNew = Gia_ManTranStochRefactor( pGia );
|
||||
Gia_ManStop( pGia );
|
||||
pGia = pNew;
|
||||
} else {
|
||||
Gia_ManTranStochLock( p );
|
||||
pNtk = Gia_ManTranStochPut( pGia );
|
||||
Gia_ManTranStochUnlock( p );
|
||||
Gia_ManStop( pGia );
|
||||
pNtkRes = Gia_ManTranStochIf( pNtk );
|
||||
Abc_NtkDelete( pNtk );
|
||||
pNtk = pNtkRes;
|
||||
Gia_ManTranStochMfs2( pNtk );
|
||||
Gia_ManTranStochLock( p );
|
||||
pNtkRes = Abc_NtkStrash( pNtk, 0, 1, 0 );
|
||||
Gia_ManTranStochUnlock( p );
|
||||
Abc_NtkDelete( pNtk );
|
||||
pNtk = pNtkRes;
|
||||
pGia = Gia_ManTranStochGet( pNtk );
|
||||
Abc_NtkDelete( pNtk );
|
||||
}
|
||||
if ( p->nVerbose )
|
||||
printf( "* hop %d : #nodes = %5d\n", i, Gia_ManAndNum( pGia ) );
|
||||
}
|
||||
Gia_ManStop( pGia );
|
||||
return pBest;
|
||||
}
|
||||
|
||||
Gia_Man_t * Gia_ManTranStochOpt3( Gia_ManTranStochParam * p ) {
|
||||
int i, n = Gia_ManAndNum( p->pStart );
|
||||
Gia_Man_t * pBest, * pNew;
|
||||
pBest = Gia_ManDup( p->pStart );
|
||||
for ( i = 0; i <= p->nRestarts; i++ ) {
|
||||
p->nSeed = 1234 * (i + p->nSeedBase);
|
||||
pNew = Gia_ManTranStochOpt2( p );
|
||||
if ( p->nRestarts && p->nVerbose )
|
||||
printf( "* res %2d : #nodes = %5d\n", i, Gia_ManAndNum( pNew ) );
|
||||
if ( n > Gia_ManAndNum( pNew ) ) {
|
||||
n = Gia_ManAndNum( pNew );
|
||||
Gia_ManStop( pBest );
|
||||
pBest = pNew;
|
||||
} else {
|
||||
Gia_ManStop( pNew );
|
||||
}
|
||||
}
|
||||
return pBest;
|
||||
}
|
||||
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
void * Gia_ManTranStochWorkerThread( void * pArg ) {
|
||||
Gia_ManTranStochParam * p = (Gia_ManTranStochParam *)pArg;
|
||||
volatile int * pPlace = &p->fWorking;
|
||||
while ( 1 ) {
|
||||
while ( *pPlace == 0 );
|
||||
assert( p->fWorking );
|
||||
if ( p->pStart == NULL ) {
|
||||
pthread_exit( NULL );
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
p->nSeed = 1234 * (p->nIte + p->nSeedBase);
|
||||
p->pRes = Gia_ManTranStochOpt2( p );
|
||||
p->fWorking = 0;
|
||||
}
|
||||
assert( 0 );
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
Gia_Man_t * Gia_ManTranStoch( Gia_Man_t * pGia, int nRestarts, int nHops, int nSeedBase, int fMspf, int fMerge, int fResetHop, int fZeroCostHop, int fRefactor, int fTruth, int fSingle, int fOriginalOnly, int fNewLine, Gia_Man_t * pExdc, int nThreads, int nVerbose ) {
|
||||
int i, j = 0;
|
||||
Gia_Man_t * pNew, * pBest, * pStart;
|
||||
Abc_Ntk_t * pNtk, * pNtkRes; Vec_Ptr_t * vpStarts;
|
||||
Gia_ManTranStochParam Par, *p = &Par;
|
||||
p->nRestarts = nRestarts;
|
||||
p->nHops = nHops;
|
||||
p->nSeedBase = nSeedBase;
|
||||
p->fMspf = fMspf;
|
||||
p->fMerge = fMerge;
|
||||
p->fResetHop = fResetHop;
|
||||
p->fZeroCostHop = fZeroCostHop;
|
||||
p->fRefactor = fRefactor;
|
||||
p->fTruth = fTruth;
|
||||
p->fNewLine = fNewLine;
|
||||
p->pExdc = pExdc;
|
||||
p->nVerbose = nVerbose;
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
p->fWorking = 0;
|
||||
#endif
|
||||
// setup start points
|
||||
vpStarts = Vec_PtrAlloc( 4 );
|
||||
Vec_PtrPush( vpStarts, Gia_ManDup( pGia ) );
|
||||
if ( !fOriginalOnly ) {
|
||||
{ // &put; collapse; st; &get;
|
||||
pNtk = Gia_ManTranStochPut( pGia );
|
||||
pNtkRes = Abc_NtkCollapse( pNtk, ABC_INFINITY, 0, 1, 0, 0, 0 );
|
||||
Abc_NtkDelete( pNtk );
|
||||
pNtk = pNtkRes;
|
||||
pNtkRes = Abc_NtkStrash( pNtk, 0, 1, 0 );
|
||||
Abc_NtkDelete( pNtk );
|
||||
pNtk = pNtkRes;
|
||||
pNew = Gia_ManTranStochGet( pNtk );
|
||||
Abc_NtkDelete( pNtk );
|
||||
Vec_PtrPush( vpStarts, pNew );
|
||||
}
|
||||
{ // &ttopt;
|
||||
pNew = Gia_ManTtopt( pGia, Gia_ManCiNum( pGia ), Gia_ManCoNum( pGia ), 100 );
|
||||
Vec_PtrPush( vpStarts, pNew );
|
||||
}
|
||||
{ // &put; collapse; sop; fx;
|
||||
pNtk = Gia_ManTranStochPut( pGia );
|
||||
pNtkRes = Abc_NtkCollapse( pNtk, ABC_INFINITY, 0, 1, 0, 0, 0 );
|
||||
Abc_NtkDelete( pNtk );
|
||||
pNtk = pNtkRes;
|
||||
Abc_NtkToSop( pNtk, -1, ABC_INFINITY );
|
||||
Gia_ManTranStochFx( pNtk );
|
||||
pNtkRes = Abc_NtkStrash( pNtk, 0, 1, 0 );
|
||||
Abc_NtkDelete( pNtk );
|
||||
pNtk = pNtkRes;
|
||||
pNew = Gia_ManTranStochGet( pNtk );
|
||||
Abc_NtkDelete( pNtk );
|
||||
Vec_PtrPush( vpStarts, pNew );
|
||||
}
|
||||
}
|
||||
if ( fSingle ) {
|
||||
pBest = (Gia_Man_t *)Vec_PtrEntry( vpStarts, 0 );
|
||||
for ( i = 1; i < Vec_PtrSize( vpStarts ); i++ ) {
|
||||
pStart = (Gia_Man_t *)Vec_PtrEntry( vpStarts, i );
|
||||
if ( Gia_ManAndNum( pStart ) < Gia_ManAndNum( pBest ) ) {
|
||||
Gia_ManStop( pBest );
|
||||
pBest = pStart;
|
||||
j = i;
|
||||
} else {
|
||||
Gia_ManStop( pStart );
|
||||
}
|
||||
}
|
||||
Vec_PtrClear( vpStarts );
|
||||
Vec_PtrPush( vpStarts, pBest );
|
||||
}
|
||||
// optimize
|
||||
pBest = Gia_ManDup( pGia );
|
||||
if ( nThreads == 1 ) {
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vpStarts, pStart, i ) {
|
||||
if ( p->nVerbose )
|
||||
printf( "*begin starting point %d: #nodes = %5d\n", i + j, Gia_ManAndNum( pStart ) );
|
||||
p->pStart = pStart;
|
||||
pNew = Gia_ManTranStochOpt3( p );
|
||||
if ( p->nVerbose )
|
||||
printf( "*end starting point %d: #nodes = %5d\n", i + j, Gia_ManAndNum( pNew ) );
|
||||
if ( Gia_ManAndNum( pBest ) > Gia_ManAndNum( pNew ) ) {
|
||||
Gia_ManStop( pBest );
|
||||
pBest = pNew;
|
||||
} else {
|
||||
Gia_ManStop( pNew );
|
||||
}
|
||||
Gia_ManStop( pStart );
|
||||
}
|
||||
} else {
|
||||
#ifdef ABC_USE_PTHREADS
|
||||
static pthread_mutex_t mutex;
|
||||
int k, status, nIte, fAssigned, fWorking;
|
||||
Gia_ManTranStochParam ThData[100];
|
||||
pthread_t WorkerThread[100];
|
||||
p->pRes = NULL;
|
||||
p->mutex = &mutex;
|
||||
if ( p->nVerbose )
|
||||
p->nVerbose--;
|
||||
for ( i = 0; i < nThreads; i++ ) {
|
||||
ThData[i] = *p;
|
||||
status = pthread_create( WorkerThread + i, NULL, Gia_ManTranStochWorkerThread, (void *)(ThData + i) );
|
||||
assert( status == 0 );
|
||||
}
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vpStarts, pStart, k ) {
|
||||
for ( nIte = 0; nIte <= p->nRestarts; nIte++ ) {
|
||||
fAssigned = 0;
|
||||
while ( !fAssigned ) {
|
||||
for ( i = 0; i < nThreads; i++ ) {
|
||||
if ( ThData[i].fWorking )
|
||||
continue;
|
||||
if ( ThData[i].pRes != NULL ) {
|
||||
if( nVerbose )
|
||||
printf( "*sp %d res %4d : #nodes = %5d\n", ThData[i].nSp, ThData[i].nIte, Gia_ManAndNum( ThData[i].pRes ) );
|
||||
if ( Gia_ManAndNum( pBest ) > Gia_ManAndNum( ThData[i].pRes ) ) {
|
||||
Gia_ManStop( pBest );
|
||||
pBest = ThData[i].pRes;
|
||||
} else {
|
||||
Gia_ManStop( ThData[i].pRes );
|
||||
}
|
||||
ThData[i].pRes = NULL;
|
||||
}
|
||||
ThData[i].nSp = j + k;
|
||||
ThData[i].nIte = nIte;
|
||||
ThData[i].pStart = pStart;
|
||||
ThData[i].fWorking = 1;
|
||||
fAssigned = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fWorking = 1;
|
||||
while ( fWorking ) {
|
||||
fWorking = 0;
|
||||
for ( i = 0; i < nThreads; i++ ) {
|
||||
if( ThData[i].fWorking ) {
|
||||
fWorking = 1;
|
||||
continue;
|
||||
}
|
||||
if ( ThData[i].pRes != NULL ) {
|
||||
if( nVerbose )
|
||||
printf( "*sp %d res %4d : #nodes = %5d\n", ThData[i].nSp, ThData[i].nIte, Gia_ManAndNum( ThData[i].pRes ) );
|
||||
if ( Gia_ManAndNum( pBest ) > Gia_ManAndNum( ThData[i].pRes ) ) {
|
||||
Gia_ManStop( pBest );
|
||||
pBest = ThData[i].pRes;
|
||||
} else {
|
||||
Gia_ManStop( ThData[i].pRes );
|
||||
}
|
||||
ThData[i].pRes = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( i = 0; i < nThreads; i++ ) {
|
||||
ThData[i].pStart = NULL;
|
||||
ThData[i].fWorking = 1;
|
||||
}
|
||||
#else
|
||||
printf( "ERROR: pthread is off" );
|
||||
#endif
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vpStarts, pStart, i )
|
||||
Gia_ManStop( pStart );
|
||||
}
|
||||
if ( nVerbose )
|
||||
printf( "best: %d\n", Gia_ManAndNum( pBest ) );
|
||||
Vec_PtrFree( vpStarts );
|
||||
ABC_FREE( pBest->pName );
|
||||
ABC_FREE( pBest->pSpec );
|
||||
pBest->pName = Abc_UtilStrsav( pGia->pName );
|
||||
pBest->pSpec = Abc_UtilStrsav( pGia->pSpec );
|
||||
return pBest;
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaTransduction.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Implementation of transduction method.]
|
||||
|
||||
Author [Yukio Miyasaka]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - May 2023.]
|
||||
|
||||
Revision [$Id: giaTransduction.c,v 1.00 2023/05/10 00:00:00 Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma warning(disable : 4786) // warning C4786: identifier was truncated to '255' characters in the browser information
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "giaTransduction.h"
|
||||
#include "giaNewBdd.h"
|
||||
#include "giaNewTt.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
Gia_Man_t *Gia_ManTransductionBdd(Gia_Man_t *pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t *pExdc, int fNewLine, int nVerbose) {
|
||||
if(nRandom) {
|
||||
srand(nRandom);
|
||||
nSortType = rand() % 4;
|
||||
nPiShuffle = rand();
|
||||
nParameter = rand() % 16;
|
||||
}
|
||||
NewBdd::Param p;
|
||||
Transduction::Transduction<NewBdd::Man, NewBdd::Param, NewBdd::lit, 0xffffffff> t(pGia, nVerbose, fNewLine, nSortType, nPiShuffle, fLevel, pExdc, p);
|
||||
int count = t.CountWires();
|
||||
switch(nType) {
|
||||
case 0:
|
||||
count -= fMspf? t.Mspf(): t.Cspf();
|
||||
break;
|
||||
case 1:
|
||||
count -= t.Resub(fMspf);
|
||||
break;
|
||||
case 2:
|
||||
count -= t.ResubMono(fMspf);
|
||||
break;
|
||||
case 3:
|
||||
count -= t.ResubShared(fMspf);
|
||||
break;
|
||||
case 4:
|
||||
count -= t.RepeatResub(false, fMspf);
|
||||
break;
|
||||
case 5:
|
||||
count -= t.RepeatResub(true, fMspf);
|
||||
break;
|
||||
case 6: {
|
||||
bool fInner = (nParameter / 4) % 2;
|
||||
count -= t.RepeatInner(fMspf, fInner);
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
bool fInner = (nParameter / 4) % 2;
|
||||
bool fOuter = (nParameter / 8) % 2;
|
||||
count -= t.RepeatOuter(fMspf, fInner, fOuter);
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
bool fFirstMerge = nParameter % 2;
|
||||
bool fMspfMerge = fMspf? (nParameter / 2) % 2: false;
|
||||
bool fInner = (nParameter / 4) % 2;
|
||||
bool fOuter = (nParameter / 8) % 2;
|
||||
count -= t.RepeatAll(fFirstMerge, fMspfMerge, fMspf, fInner, fOuter);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
std::cout << "Unknown transduction type " << nType << std::endl;
|
||||
}
|
||||
assert(t.Verify());
|
||||
assert(count == t.CountWires());
|
||||
return t.GenerateAig();
|
||||
}
|
||||
|
||||
Gia_Man_t *Gia_ManTransductionTt(Gia_Man_t *pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t *pExdc, int fNewLine, int nVerbose) {
|
||||
if(nRandom) {
|
||||
srand(nRandom);
|
||||
nSortType = rand() % 4;
|
||||
nPiShuffle = rand();
|
||||
nParameter = rand() % 16;
|
||||
}
|
||||
NewTt::Param p;
|
||||
Transduction::Transduction<NewTt::Man, NewTt::Param, NewTt::lit, 0xffffffff> t(pGia, nVerbose, fNewLine, nSortType, nPiShuffle, fLevel, pExdc, p);
|
||||
int count = t.CountWires();
|
||||
switch(nType) {
|
||||
case 0:
|
||||
count -= fMspf? t.Mspf(): t.Cspf();
|
||||
break;
|
||||
case 1:
|
||||
count -= t.Resub(fMspf);
|
||||
break;
|
||||
case 2:
|
||||
count -= t.ResubMono(fMspf);
|
||||
break;
|
||||
case 3:
|
||||
count -= t.ResubShared(fMspf);
|
||||
break;
|
||||
case 4:
|
||||
count -= t.RepeatResub(false, fMspf);
|
||||
break;
|
||||
case 5:
|
||||
count -= t.RepeatResub(true, fMspf);
|
||||
break;
|
||||
case 6: {
|
||||
bool fInner = (nParameter / 4) % 2;
|
||||
count -= t.RepeatInner(fMspf, fInner);
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
bool fInner = (nParameter / 4) % 2;
|
||||
bool fOuter = (nParameter / 8) % 2;
|
||||
count -= t.RepeatOuter(fMspf, fInner, fOuter);
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
bool fFirstMerge = nParameter % 2;
|
||||
bool fMspfMerge = fMspf? (nParameter / 2) % 2: false;
|
||||
bool fInner = (nParameter / 4) % 2;
|
||||
bool fOuter = (nParameter / 8) % 2;
|
||||
count -= t.RepeatAll(fFirstMerge, fMspfMerge, fMspf, fInner, fOuter);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
std::cout << "Unknown transduction type " << nType << std::endl;
|
||||
}
|
||||
assert(t.Verify());
|
||||
assert(count == t.CountWires());
|
||||
return t.GenerateAig();
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
#else
|
||||
|
||||
#include "gia.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
Gia_Man_t * Gia_ManTransductionBdd(Gia_Man_t *pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t *pExdc, int fNewLine, int nVerbose)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
Gia_Man_t * Gia_ManTransductionTt(Gia_Man_t *pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t *pExdc, int fNewLine, int nVerbose)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -22,6 +22,7 @@
|
|||
#include "misc/vec/vecMem.h"
|
||||
#include "misc/vec/vecWec.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "bool/lucky/lucky.h"
|
||||
#include "opt/dau/dau.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
|
@ -559,6 +560,11 @@ void Gia_ObjComputeTruthTableStart( Gia_Man_t * p, int nVarsMax )
|
|||
p->vTtMemory = Vec_WrdStart( p->nTtWords * 64 );
|
||||
p->vTtNums = Vec_IntAlloc( Gia_ManObjNum(p) + 1000 );
|
||||
Vec_IntFill( p->vTtNums, Vec_IntCap(p->vTtNums), -ABC_INFINITY );
|
||||
if ( nVarsMax >= 6 ) {
|
||||
word * pTruth; int i;
|
||||
Vec_PtrForEachEntry( word *, p->vTtInputs, pTruth, i )
|
||||
Abc_TtFlipVar5( pTruth, nVarsMax );
|
||||
}
|
||||
}
|
||||
void Gia_ObjComputeTruthTableStop( Gia_Man_t * p )
|
||||
{
|
||||
|
|
@ -804,10 +810,73 @@ Gia_Man_t * Gia_ManIsoNpnReduce( Gia_Man_t * p, Vec_Ptr_t ** pvPosEquivs, int fV
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManNodeFunctionProfile( Gia_Man_t * p, int nVars )
|
||||
{
|
||||
int fCanonicize = 1;
|
||||
Gia_Obj_t * pObj;
|
||||
Vec_Int_t * vLeaves = Vec_IntAlloc( 100 );
|
||||
int nWords = Abc_Truth6WordNum( nVars );
|
||||
Vec_Mem_t * pTtMem = Vec_MemAlloc( nWords, 12 ); // supports up to nVars words
|
||||
Vec_MemHashAlloc( pTtMem, 1000 );
|
||||
Vec_Int_t * vCounts = Vec_IntAlloc( 100 );
|
||||
permInfo * pi = setPermInfoPtr( nVars );
|
||||
word pAuxWord[DAU_MAX_WORD], pAuxWord1[DAU_MAX_WORD], Truth[DAU_MAX_WORD], * pTruth; int i;
|
||||
assert( nVars <= 7 );
|
||||
Gia_ObjComputeTruthTableStart( p, nVars );
|
||||
Gia_ManForEachAnd( p, pObj, i ) {
|
||||
if ( Gia_ManSuppSize(p, &i, 1) != nVars )
|
||||
continue;
|
||||
Gia_ManCollectCis( p, &i, 1, vLeaves );
|
||||
assert( Vec_IntSize(vLeaves) == nVars );
|
||||
pTruth = Gia_ObjComputeTruthTableCut( p, pObj, vLeaves );
|
||||
if ( fCanonicize ) {
|
||||
memcpy( Truth, pTruth, sizeof(word) * nWords );
|
||||
simpleMinimal( Truth, pAuxWord, pAuxWord1, pi, nVars ); // NPN canonical form
|
||||
}
|
||||
else {
|
||||
memcpy( Truth, pTruth, sizeof(word) * nWords );
|
||||
}
|
||||
{
|
||||
int nEntries = Vec_MemEntryNum( pTtMem );
|
||||
int Value = Vec_MemHashInsert( pTtMem, Truth );
|
||||
if ( Vec_MemEntryNum( pTtMem ) == nEntries )
|
||||
Vec_IntAddToEntry( vCounts, Value, 1 );
|
||||
else
|
||||
{
|
||||
assert( Value == nEntries );
|
||||
Vec_IntPush( vCounts, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( i = 0; i < Vec_MemEntryNum(pTtMem); i++ ) {
|
||||
word * pCanon = Vec_MemReadEntry( pTtMem, i );
|
||||
int Count = Vec_IntEntry( vCounts, i );
|
||||
Abc_TtPrintHexRev( stdout, pCanon, nVars );
|
||||
printf( " %d\n", Count );
|
||||
}
|
||||
Gia_ObjComputeTruthTableStop( p );
|
||||
Vec_IntFree( vLeaves );
|
||||
Vec_IntFree( vCounts );
|
||||
Vec_MemHashFree( pTtMem );
|
||||
Vec_MemFree( pTtMem );
|
||||
freePermInfoPtr( pi );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -84,9 +84,11 @@ Gia_ManTer_t * Gia_ManTerCreate( Gia_Man_t * pAig )
|
|||
p = ABC_CALLOC( Gia_ManTer_t, 1 );
|
||||
p->pAig = Gia_ManFront( pAig );
|
||||
p->nIters = 300;
|
||||
p->pDataSim = ABC_ALLOC( unsigned, Abc_BitWordNum(2*p->pAig->nFront) );
|
||||
p->pDataSimCis = ABC_ALLOC( unsigned, Abc_BitWordNum(2*Gia_ManCiNum(p->pAig)) );
|
||||
p->pDataSimCos = ABC_ALLOC( unsigned, Abc_BitWordNum(2*Gia_ManCoNum(p->pAig)) );
|
||||
// these buffers are accessed through XOR-based setters that read the current word first,
|
||||
// so they must be zero-initialized to avoid touching undefined data on the first update
|
||||
p->pDataSim = ABC_CALLOC( unsigned, Abc_BitWordNum(2*p->pAig->nFront) );
|
||||
p->pDataSimCis = ABC_CALLOC( unsigned, Abc_BitWordNum(2*Gia_ManCiNum(p->pAig)) );
|
||||
p->pDataSimCos = ABC_CALLOC( unsigned, Abc_BitWordNum(2*Gia_ManCoNum(p->pAig)) );
|
||||
// allocate storage for terminary states
|
||||
p->nStateWords = Abc_BitWordNum( 2*Gia_ManRegNum(pAig) );
|
||||
p->vStates = Vec_PtrAlloc( 1000 );
|
||||
|
|
@ -754,4 +756,3 @@ Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose )
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -48,8 +48,13 @@ ABC_NAMESPACE_IMPL_START
|
|||
***********************************************************************/
|
||||
unsigned Gia_ManRandom( int fReset )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
static unsigned int m_z = NUMBER1;
|
||||
static unsigned int m_w = NUMBER2;
|
||||
#else
|
||||
static __thread unsigned int m_z = NUMBER1;
|
||||
static __thread unsigned int m_w = NUMBER2;
|
||||
#endif
|
||||
if ( fReset )
|
||||
{
|
||||
m_z = NUMBER1;
|
||||
|
|
@ -135,6 +140,42 @@ char * Gia_FileNameGenericAppend( char * pBase, char * pSuffix )
|
|||
return Buffer;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Gia_GetFakeNames( int nNames, int fCaps )
|
||||
{
|
||||
Vec_Ptr_t * vNames;
|
||||
char Buffer[5];
|
||||
int i;
|
||||
|
||||
vNames = Vec_PtrAlloc( nNames );
|
||||
for ( i = 0; i < nNames; i++ )
|
||||
{
|
||||
if ( nNames < 26 )
|
||||
{
|
||||
Buffer[0] = (fCaps ? 'A' : 'a') + i;
|
||||
Buffer[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer[0] = (fCaps ? 'A' : 'a') + i%26;
|
||||
Buffer[1] = '0' + i/26;
|
||||
Buffer[2] = 0;
|
||||
}
|
||||
Vec_PtrPush( vNames, Extra_UtilStrsav(Buffer) );
|
||||
}
|
||||
return vNames;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -755,6 +796,23 @@ void Gia_ManCreateRefs( Gia_Man_t * p )
|
|||
Gia_ObjRefFanin0Inc( p, pObj );
|
||||
}
|
||||
}
|
||||
void Gia_ManCreateLitRefs( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int i;
|
||||
assert( p->pRefs == NULL );
|
||||
p->pRefs = ABC_CALLOC( int, 2*Gia_ManObjNum(p) );
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjIsAnd(pObj) )
|
||||
{
|
||||
p->pRefs[Gia_ObjFaninLit0(pObj, i)]++;
|
||||
p->pRefs[Gia_ObjFaninLit1(pObj, i)]++;
|
||||
}
|
||||
else if ( Gia_ObjIsCo(pObj) )
|
||||
p->pRefs[Gia_ObjFaninLit0(pObj, i)]++;
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -3080,12 +3138,861 @@ Gia_Man_t * Gia_ManTransformCond( Gia_Man_t * p )
|
|||
Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
|
||||
return NULL;
|
||||
}
|
||||
void Gia_ManWriteSol( Gia_Man_t * p, char * pFileName )
|
||||
{
|
||||
char * pBasicName = Extra_FileNameGeneric( pFileName );
|
||||
char * pFileName2 = Abc_UtilStrsavTwo( pBasicName, ".sol" );
|
||||
FILE * pFile = fopen( pFileName2, "wb" );
|
||||
ABC_FREE( pBasicName );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open output file \"%s\".\n", pFileName2 );
|
||||
else
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
fprintf( pFile, "%d %d ", Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
fprintf( pFile, "%d %d ", Gia_ObjFaninLit0p(p, pObj), Gia_ObjFaninLit0p(p, pObj) );
|
||||
fclose( pFile );
|
||||
printf( "Finished writing solution file \"%s\".\n", pFileName2 );
|
||||
}
|
||||
ABC_FREE( pFileName2 );
|
||||
}
|
||||
void Gia_ManWriteResub( Gia_Man_t * p, char * pFileName )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open output file \"%s\".\n", pFileName );
|
||||
else
|
||||
{
|
||||
Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) );
|
||||
Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( p, vSimsPi, 1 );
|
||||
int i, k, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(p);
|
||||
word * pTemp = ABC_ALLOC( word, nWords );
|
||||
fprintf( pFile, "%d %d %d %d\n", Gia_ManCiNum(p), 0, Gia_ManCoNum(p), 1 << Gia_ManCiNum(p) );
|
||||
for ( i = 0; i < Gia_ManCiNum(p); i++ )
|
||||
Abc_TtPrintBinary1( pFile, Vec_WrdEntryP(vSimsPi, i*nWords), Gia_ManCiNum(p) ), fprintf(pFile, "\n");
|
||||
for ( i = 0; i < (1 << Gia_ManCoNum(p)); i++ )
|
||||
{
|
||||
Abc_TtFill( pTemp, nWords );
|
||||
for ( k = 0; k < Gia_ManCoNum(p); k++ )
|
||||
Abc_TtAndCompl( pTemp, pTemp, 0, Vec_WrdEntryP(vSimsPo, k*nWords), !((i>>k)&1), nWords );
|
||||
Abc_TtPrintBinary1( pFile, pTemp, Gia_ManCiNum(p) ), fprintf(pFile, "\n");
|
||||
}
|
||||
ABC_FREE( pTemp );
|
||||
fclose( pFile );
|
||||
Vec_WrdFree( vSimsPi );
|
||||
Vec_WrdFree( vSimsPo );
|
||||
printf( "Finished writing resub file \"%s\".\n", pFileName );
|
||||
Gia_ManWriteSol( p, pFileName );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transform flops.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManPrintArray( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, nSize = Gia_ManObjNum(p);
|
||||
printf( "static int s_ArraySize = %d;\n", nSize );
|
||||
printf( "static int s_ArrayData[%d] = {\n", 2*nSize );
|
||||
printf( " 0, 0," );
|
||||
printf( "\n " );
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
printf( "0, 0, " );
|
||||
printf( "\n " );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
printf( "%d, %d, ", Gia_ObjFaninLit0p(p, pObj), Gia_ObjFaninLit1p(p, pObj) );
|
||||
printf( "\n " );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
printf( "%d, %d, ", Gia_ObjFaninLit0p(p, pObj), Gia_ObjFaninLit0p(p, pObj) );
|
||||
printf( "\n" );
|
||||
printf( "};\n" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_GetMValue( int i, int nIns, int Mint, unsigned Truth )
|
||||
{
|
||||
assert( i >= 0 && i < 16 );
|
||||
if ( i < nIns )
|
||||
return (Mint >> i) & 1;
|
||||
if ( i == nIns )
|
||||
{
|
||||
if ( Mint < (1 << nIns) )
|
||||
return (Truth >> Mint) & 1;
|
||||
else
|
||||
return ((Truth >> (Mint-(1 << nIns))) & 1) == 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
void Gia_ManTestProblem()
|
||||
{
|
||||
unsigned Truth = 0xFE;
|
||||
int i, j, k, c, nIns = 3, nAux = 3;
|
||||
int nTotal = nIns + 1 + nAux;
|
||||
int nPairs = nTotal * (nTotal - 1) / 2;
|
||||
int nMints = (1 << (nIns+1));
|
||||
int M[64][100] = {{0}};
|
||||
float Value[64] = {0};
|
||||
float Solution[100] = {0};
|
||||
assert( nMints <= 64 );
|
||||
assert( nPairs <= 100 );
|
||||
// 7 nodes: 3 inputs + 1 output + 3 aux
|
||||
// 7*6/2 = 21 pairs
|
||||
// 16 minterms
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
{
|
||||
for ( i = c = 0; i < nTotal; i++ )
|
||||
for ( j = i+1; j < nTotal; j++ )
|
||||
{
|
||||
int iVal = Gia_GetMValue( i, nIns, k, Truth );
|
||||
int jVal = Gia_GetMValue( j, nIns, k, Truth );
|
||||
M[k][c++] = iVal == jVal ? 1 : -1;
|
||||
}
|
||||
Value[k] = k < (1 << nIns) ? -1 : 1;
|
||||
assert( c == nPairs );
|
||||
}
|
||||
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
{
|
||||
for ( c = 0; c < nPairs; c++ )
|
||||
printf( "%2d ", M[k][c] );
|
||||
printf( "%3f\n", Value[k] );
|
||||
}
|
||||
|
||||
// solve
|
||||
float Delta = 0.02;
|
||||
for ( i = 0; i < 100; i++ )
|
||||
{
|
||||
float Error = 0;
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
Error += Value[k] > 0 ? Value[k] : -Value[k];
|
||||
printf( "Round %3d : Error = %5f ", i, Error );
|
||||
for ( c = 0; c < nPairs; c++ )
|
||||
printf( "%2f ", Solution[c] );
|
||||
printf( "\n" );
|
||||
|
||||
//if ( Error < 1 )
|
||||
// Delta /= 10;
|
||||
|
||||
for ( c = 0; c < nPairs; c++ )
|
||||
{
|
||||
int Count = 0;
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
if ( (M[k][c] > 0 && Value[k] > 0) || (M[k][c] < 0 && Value[k] < 0) )
|
||||
Count++;
|
||||
else
|
||||
Count--;
|
||||
if ( Count == 0 )
|
||||
continue;
|
||||
printf( "Count = %3d ", Count );
|
||||
if ( Count > 0 )
|
||||
{
|
||||
printf( "Increasing %d by %f\n", c, Delta );
|
||||
Solution[c] += Delta;
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
if ( M[k][c] > 0 )
|
||||
Value[k] -= Delta;
|
||||
else
|
||||
Value[k] -= Delta;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Reducing %d by %f\n", c, Delta );
|
||||
Solution[c] -= Delta;
|
||||
for ( k = 0; k < nMints; k++ )
|
||||
if ( M[k][c] > 0 )
|
||||
Value[k] += Delta;
|
||||
else
|
||||
Value[k] += Delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if this window has a topo error (forward path from an output to an input).]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManWindowCheckTopoError_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
|
||||
{
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
return 0;
|
||||
if ( Gia_ObjIsTravIdPrevious(p, pObj) )
|
||||
return 1; // there is an error
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
return 0; // there is no error; visited this node before
|
||||
Gia_ObjSetTravIdPrevious(p, pObj);
|
||||
if ( Gia_ManWindowCheckTopoError_rec(p, Gia_ObjFanin0(pObj)) || Gia_ManWindowCheckTopoError_rec(p, Gia_ObjFanin1(pObj)) )
|
||||
return 1;
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
return 0;
|
||||
}
|
||||
int Gia_ManWindowCheckTopoError( Gia_Man_t * p, Vec_Int_t * vIns, Vec_Int_t * vOuts )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i, fError = 0;
|
||||
// outputs should be internal nodes
|
||||
Gia_ManForEachObjVec( vOuts, p, pObj, i )
|
||||
assert(Gia_ObjIsAnd(pObj));
|
||||
// mark outputs
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachObjVec( vOuts, p, pObj, i )
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
// start from inputs and make sure we do not reach any of the outputs
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachObjVec( vIns, p, pObj, i )
|
||||
fError |= Gia_ManWindowCheckTopoError_rec(p, pObj);
|
||||
return fError;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Updates the AIG after multiple windows have been optimized.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManDupInsertWindows_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vMap, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins )
|
||||
{
|
||||
if ( ~pObj->Value )
|
||||
return pObj->Value;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
if ( Vec_IntEntry(vMap, Gia_ObjId(p, pObj)) == -1 ) // this is a regular node
|
||||
{
|
||||
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin0(pObj), vMap, vvIns, vvOuts, vWins );
|
||||
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin1(pObj), vMap, vvIns, vvOuts, vWins );
|
||||
return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
}
|
||||
// this node is an output of a window
|
||||
int iWin = Vec_IntEntry(vMap, Gia_ObjId(p, pObj));
|
||||
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, iWin);
|
||||
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, iWin);
|
||||
Gia_Man_t * pWin = (Gia_Man_t *)Vec_PtrEntry(vWins, iWin);
|
||||
// build transinvite fanins of window inputs
|
||||
Gia_Obj_t * pNode; int i;
|
||||
Gia_ManConst0(pWin)->Value = 0;
|
||||
Gia_ManForEachObjVec( vIns, p, pNode, i )
|
||||
Gia_ManPi(pWin, i)->Value = Gia_ManDupInsertWindows_rec( pNew, p, pNode, vMap, vvIns, vvOuts, vWins );
|
||||
// add window nodes
|
||||
Gia_ManForEachAnd( pWin, pNode, i )
|
||||
pNode->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pNode), Gia_ObjFanin1Copy(pNode) );
|
||||
// transfer to window outputs
|
||||
Gia_ManForEachObjVec( vOuts, p, pNode, i )
|
||||
pNode->Value = Gia_ObjFanin0Copy(Gia_ManPo(pWin, i));
|
||||
assert( ~pObj->Value );
|
||||
return pObj->Value;
|
||||
}
|
||||
Gia_Man_t * Gia_ManDupInsertWindows( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins )
|
||||
{
|
||||
// check consistency of input data
|
||||
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, k, iNode;
|
||||
Vec_PtrForEachEntry( Gia_Man_t *, vWins, pTemp, i ) {
|
||||
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, i);
|
||||
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, i);
|
||||
assert( Vec_IntSize(vIns) == Gia_ManPiNum(pTemp) );
|
||||
assert( Vec_IntSize(vOuts) == Gia_ManPoNum(pTemp) );
|
||||
assert( !Gia_ManWindowCheckTopoError(p, vIns, vOuts) );
|
||||
}
|
||||
// create mapping of window outputs into window IDs
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ), * vOuts;
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vvOuts, vOuts, i )
|
||||
Vec_IntForEachEntry( vOuts, iNode, k )
|
||||
Vec_IntWriteEntry( vMap, iNode, i );
|
||||
// create the resulting AIG by performing DFS from the POs of the original AIG
|
||||
// it goes recursively through original nodes and windows until it reaches the PIs of the original AIG
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin0(pObj), vMap, vvIns, vvOuts, vWins );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
// cleanup and return
|
||||
Vec_IntFree( vMap );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
//Gia_ManPrint( pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computing equivalent nodes across the two AIGs.]
|
||||
|
||||
Description [Assumes that both AIGs are structurally hashed without dandling nodes.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManCreateDualOutputMiter( Gia_Man_t * p0, Gia_Man_t * p1 )
|
||||
{
|
||||
Gia_Man_t * pNew; Gia_Obj_t * pObj; int i;
|
||||
assert( Gia_ManCiNum(p0) == Gia_ManCiNum(p1) );
|
||||
assert( Gia_ManCoNum(p0) == Gia_ManCoNum(p1) );
|
||||
// start the manager
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p0) + Gia_ManObjNum(p1) );
|
||||
pNew->pName = Abc_UtilStrsav( "miter" );
|
||||
Gia_ManFillValue( p0 );
|
||||
Gia_ManFillValue( p1 );
|
||||
// map combinational inputs
|
||||
Gia_ManConst0(p0)->Value = 0;
|
||||
Gia_ManConst0(p1)->Value = 0;
|
||||
Gia_ManForEachCi( p0, pObj, i )
|
||||
Gia_ManCi(p1, i)->Value = pObj->Value = Gia_ManAppendCi( pNew );
|
||||
// map internal nodes and outputs
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Gia_ManForEachAnd( p0, pObj, i )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
assert( Gia_ManAndNum(pNew) == Gia_ManAndNum(p0) ); // the input AIG p0 is structurally hashed
|
||||
Gia_ManForEachAnd( p1, pObj, i )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
// add the outputs
|
||||
Gia_ManForEachCo( p0, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManForEachCo( p1, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
printf( "The two AIGs have %d structurally equivalent nodes.\n", Gia_ManAndNum(p0) + Gia_ManAndNum(p1) - Gia_ManAndNum(pNew) );
|
||||
// there should be no dangling nodes (otherwise, the second AIG may not be structurally hashed)
|
||||
int nDangling = Gia_ManMarkDangling(pNew);
|
||||
assert( nDangling == 0 );
|
||||
Gia_ManCleanMark01(pNew);
|
||||
return pNew;
|
||||
}
|
||||
Vec_Int_t * Gia_ManFindMutualEquivs( Gia_Man_t * p0, Gia_Man_t * p1, int nConflictLimit, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vPairs = Vec_IntAlloc( 100 );
|
||||
// derive the miter
|
||||
Gia_Man_t * pMiter = Gia_ManCreateDualOutputMiter( p0, p1 );
|
||||
//Gia_ManPrintStats( pMiter, NULL );
|
||||
//Gia_AigerWrite( pMiter, "out.aig", 0, 0, 0 );
|
||||
// perform SAT sweeping
|
||||
extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
|
||||
Gia_Man_t * pNew = Cec4_ManSimulateTest3( pMiter, nConflictLimit, fVerbose );
|
||||
Gia_ManStop( pNew );
|
||||
// now, pMiter is annotated with the equiv class info
|
||||
|
||||
// here we collect AIG node pairs with the following properties:
|
||||
// - the first node belongs to p0; the second node belongs to p1
|
||||
// - both nodes are internal nodes of p0 and p1 (not primary inputs/outputs)
|
||||
// - these nodes are combinationally equivalent (possibly up to the complement)
|
||||
// - these nodes are "singleton" equivalences (no other nodes in p0 and p1 are equivalent to them)
|
||||
// - these nodes are not structurally equivalent (that is, they have structurally different TFI logic cones)
|
||||
|
||||
// count the number of nodes in each equivalence class
|
||||
Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(pMiter) );
|
||||
Gia_Obj_t * pObj; int i, k;
|
||||
Gia_ManForEachClass( pMiter, i )
|
||||
Gia_ClassForEachObj( pMiter, i, k )
|
||||
Vec_IntAddToEntry( vCounts, i, 1 );
|
||||
|
||||
// map each miter node coming from p1 into the corresponding node in p1
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(pMiter) );
|
||||
int iStartP1 = 1 + Gia_ManPiNum(p0) + Gia_ManAndNum(p0);
|
||||
Gia_ManForEachAnd( p1, pObj, i )
|
||||
if ( Abc_Lit2Var(pObj->Value) >= iStartP1 ) // node from p1 (not from p0)
|
||||
Vec_IntWriteEntry( vMap, Abc_Lit2Var(pObj->Value), i );
|
||||
|
||||
// go through functionally (not structurally!) equivalent nodes in the second AIG
|
||||
// and collect those node pairs from p0 and p1 whose equivalence class contains exactly two nodes
|
||||
for ( i = iStartP1; i < Gia_ManObjNum(pMiter) - Gia_ManCoNum(pMiter); i++ ) {
|
||||
assert( Gia_ObjIsAnd(Gia_ManObj(pMiter, i)) );
|
||||
int Repr = Gia_ObjRepr(pMiter, i);
|
||||
if ( Repr == GIA_VOID || Repr >= iStartP1 || Vec_IntEntry(vCounts, Repr) != 2 )
|
||||
continue;
|
||||
assert( Repr < iStartP1 ); // node in p0
|
||||
assert( Vec_IntEntry(vMap, i) > 0 ); // node in p1
|
||||
Vec_IntPushTwo( vPairs, Repr, Vec_IntEntry(vMap, i) );
|
||||
}
|
||||
// cleanup
|
||||
Vec_IntFree( vMap );
|
||||
Vec_IntFree( vCounts );
|
||||
Gia_ManStop( pMiter );
|
||||
return vPairs;
|
||||
}
|
||||
void Gia_ManFindMutualEquivsTest()
|
||||
{
|
||||
Gia_Man_t * p0 = Gia_AigerRead( "p0.aig", 0, 0, 0 );
|
||||
Gia_Man_t * p1 = Gia_AigerRead( "p1.aig", 0, 0, 0 );
|
||||
Vec_Int_t * vPairs = Gia_ManFindMutualEquivs( p0, p1, 0, 0 );
|
||||
printf( "Pair Aig0 node Aig1 node\n" );
|
||||
int i, Obj0, Obj1;
|
||||
Vec_IntForEachEntryDouble( vPairs, Obj0, Obj1, i )
|
||||
printf( "%3d %6d %6d\n", i/2, Obj0, Obj1 );
|
||||
Gia_ManStop( p0 );
|
||||
Gia_ManStop( p1 );
|
||||
Vec_IntFree( vPairs );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Prints longest combinational paths between seq endpoints.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static char * Gia_ManPrintPathNameFallback( Gia_Man_t * p, int fCi, int iTerm, char * pBuffer )
|
||||
{
|
||||
if ( fCi )
|
||||
{
|
||||
if ( iTerm < Gia_ManPiNum(p) )
|
||||
sprintf( pBuffer, "pi%d", iTerm );
|
||||
else
|
||||
sprintf( pBuffer, "ro%d", iTerm - Gia_ManPiNum(p) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( iTerm < Gia_ManPoNum(p) )
|
||||
sprintf( pBuffer, "po%d", iTerm );
|
||||
else
|
||||
sprintf( pBuffer, "ri%d", iTerm - Gia_ManPoNum(p) );
|
||||
}
|
||||
return pBuffer;
|
||||
}
|
||||
static int Gia_ManPrintPathNameBufferSize( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Ptr_t * vNames;
|
||||
char * pName;
|
||||
int i, nSize = 64;
|
||||
vNames = p->vNamesIn;
|
||||
if ( vNames )
|
||||
Vec_PtrForEachEntry( char *, vNames, pName, i )
|
||||
if ( pName )
|
||||
nSize = Abc_MaxInt( nSize, (int)strlen(pName) + 64 );
|
||||
vNames = p->vNamesOut;
|
||||
if ( vNames )
|
||||
Vec_PtrForEachEntry( char *, vNames, pName, i )
|
||||
if ( pName )
|
||||
nSize = Abc_MaxInt( nSize, (int)strlen(pName) + 64 );
|
||||
return nSize;
|
||||
}
|
||||
static void Gia_ManPrintPathCopyToken( char * pBuffer, char * pBeg, char * pEnd )
|
||||
{
|
||||
int nChars = pEnd ? (int)(pEnd - pBeg) : (int)strlen(pBeg);
|
||||
memcpy( pBuffer, pBeg, nChars );
|
||||
pBuffer[nChars] = 0;
|
||||
}
|
||||
static char * Gia_ManPrintPathName( Gia_Man_t * p, int fCi, int iTerm, char * pBuffer, int fFull, int fLeaf )
|
||||
{
|
||||
Vec_Ptr_t * vNames = fCi ? p->vNamesIn : p->vNamesOut;
|
||||
char * pName = vNames && iTerm < Vec_PtrSize(vNames) ? (char *)Vec_PtrEntry(vNames, iTerm) : NULL;
|
||||
char * pBeg, * pEnd, * pFirst, * pFirstEnd;
|
||||
if ( pName == NULL )
|
||||
return Gia_ManPrintPathNameFallback( p, fCi, iTerm, pBuffer );
|
||||
if ( fFull )
|
||||
return pName;
|
||||
if ( fLeaf )
|
||||
{
|
||||
pBeg = strrchr( pName, ' ' );
|
||||
return pBeg ? pBeg + 1 : pName;
|
||||
}
|
||||
pFirst = pName;
|
||||
pFirstEnd = strchr( pFirst, ' ' );
|
||||
for ( pBeg = pName; pBeg && *pBeg; pBeg = pEnd ? pEnd + 1 : NULL )
|
||||
{
|
||||
pEnd = strchr( pBeg, ' ' );
|
||||
if ( strstr( pBeg, "reg_" ) && (pEnd == NULL || pEnd > strstr( pBeg, "reg_" )) )
|
||||
{
|
||||
Gia_ManPrintPathCopyToken( pBuffer, pBeg, pEnd );
|
||||
return pBuffer;
|
||||
}
|
||||
}
|
||||
Gia_ManPrintPathCopyToken( pBuffer, pFirst, pFirstEnd );
|
||||
return pBuffer;
|
||||
}
|
||||
static char * Gia_ManPrintPathKind( Gia_Man_t * p, int fCi, int iTerm )
|
||||
{
|
||||
if ( fCi )
|
||||
return iTerm < Gia_ManPiNum(p) ? (char *)"PI" : (char *)"RO";
|
||||
return iTerm < Gia_ManPoNum(p) ? (char *)"PO" : (char *)"RI";
|
||||
}
|
||||
static int Gia_ManPrintPathTermIndex( Gia_Man_t * p, int fCi, int iTerm )
|
||||
{
|
||||
if ( fCi )
|
||||
return iTerm < Gia_ManPiNum(p) ? iTerm : iTerm - Gia_ManPiNum(p);
|
||||
return iTerm < Gia_ManPoNum(p) ? iTerm : iTerm - Gia_ManPoNum(p);
|
||||
}
|
||||
static int Gia_ManPrintPathParseBit( char * pName, char * pBase, int * pBit, char * pSuffix )
|
||||
{
|
||||
char * pLeft = strrchr( pName, '[' );
|
||||
char * pRight = pLeft ? strchr( pLeft, ']' ) : NULL;
|
||||
char * pTemp;
|
||||
if ( pLeft == NULL || pRight == NULL )
|
||||
return 0;
|
||||
for ( pTemp = pLeft + 1; pTemp < pRight; pTemp++ )
|
||||
if ( *pTemp < '0' || *pTemp > '9' )
|
||||
return 0;
|
||||
Gia_ManPrintPathCopyToken( pBase, pName, pLeft );
|
||||
Gia_ManPrintPathCopyToken( pSuffix, pRight + 1, NULL );
|
||||
*pBit = atoi( pLeft + 1 );
|
||||
return 1;
|
||||
}
|
||||
static void Gia_ManPrintPathFormatTermRange( char * pBuffer, char * pKind, int iBeg, int iEnd )
|
||||
{
|
||||
if ( iBeg == iEnd )
|
||||
sprintf( pBuffer, "%s[%d]", pKind, iBeg );
|
||||
else
|
||||
sprintf( pBuffer, "%s[%d..%d]", pKind, iBeg, iEnd );
|
||||
}
|
||||
static void Gia_ManPrintPathFormatNameRange( char * pBuffer, char * pNameBeg, char * pNameEnd, int nNameSize )
|
||||
{
|
||||
char * BaseBeg, * BaseEnd, * SuffixBeg, * SuffixEnd;
|
||||
int BitBeg, BitEnd;
|
||||
if ( !strcmp(pNameBeg, pNameEnd) )
|
||||
{
|
||||
sprintf( pBuffer, "%s", pNameBeg );
|
||||
return;
|
||||
}
|
||||
BaseBeg = ABC_ALLOC( char, nNameSize );
|
||||
BaseEnd = ABC_ALLOC( char, nNameSize );
|
||||
SuffixBeg = ABC_ALLOC( char, nNameSize );
|
||||
SuffixEnd = ABC_ALLOC( char, nNameSize );
|
||||
if ( Gia_ManPrintPathParseBit(pNameBeg, BaseBeg, &BitBeg, SuffixBeg) &&
|
||||
Gia_ManPrintPathParseBit(pNameEnd, BaseEnd, &BitEnd, SuffixEnd) &&
|
||||
!strcmp(BaseBeg, BaseEnd) && !strcmp(SuffixBeg, SuffixEnd) )
|
||||
sprintf( pBuffer, "%s[%d..%d]%s", BaseBeg, BitBeg, BitEnd, SuffixBeg );
|
||||
else
|
||||
sprintf( pBuffer, "%s..%s", pNameBeg, pNameEnd );
|
||||
ABC_FREE( BaseBeg );
|
||||
ABC_FREE( BaseEnd );
|
||||
ABC_FREE( SuffixBeg );
|
||||
ABC_FREE( SuffixEnd );
|
||||
}
|
||||
static int Gia_ManPrintPathCanGroup( Gia_Man_t * p, int Level0, int Source0, int Sink0, int Level1, int Source1, int Sink1, int nNameSize )
|
||||
{
|
||||
char * pStore, * Buffer0, * Buffer1, * Buffer2, * Buffer3, * Base0, * Base1, * Suffix0, * Suffix1;
|
||||
int Bit0, Bit1;
|
||||
int RetValue;
|
||||
if ( Level0 != Level1 || Source0 != Source1 )
|
||||
return 0;
|
||||
if ( (Sink0 < Gia_ManPoNum(p)) != (Sink1 < Gia_ManPoNum(p)) )
|
||||
return 0;
|
||||
if ( Gia_ManPrintPathTermIndex(p, 0, Sink1) != Gia_ManPrintPathTermIndex(p, 0, Sink0) + 1 )
|
||||
return 0;
|
||||
pStore = ABC_ALLOC( char, 8 * nNameSize );
|
||||
Buffer0 = pStore + 0 * nNameSize;
|
||||
Buffer1 = pStore + 1 * nNameSize;
|
||||
Buffer2 = pStore + 2 * nNameSize;
|
||||
Buffer3 = pStore + 3 * nNameSize;
|
||||
Base0 = pStore + 4 * nNameSize;
|
||||
Base1 = pStore + 5 * nNameSize;
|
||||
Suffix0 = pStore + 6 * nNameSize;
|
||||
Suffix1 = pStore + 7 * nNameSize;
|
||||
Gia_ManPrintPathName( p, 1, Source0, Buffer0, 0, 0 );
|
||||
Gia_ManPrintPathName( p, 1, Source1, Buffer1, 0, 0 );
|
||||
if ( strcmp(Buffer0, Buffer1) )
|
||||
{
|
||||
ABC_FREE( pStore );
|
||||
return 0;
|
||||
}
|
||||
Gia_ManPrintPathName( p, 1, Source0, Buffer0, 0, 1 );
|
||||
Gia_ManPrintPathName( p, 1, Source1, Buffer1, 0, 1 );
|
||||
if ( strcmp(Buffer0, Buffer1) )
|
||||
{
|
||||
ABC_FREE( pStore );
|
||||
return 0;
|
||||
}
|
||||
Gia_ManPrintPathName( p, 0, Sink0, Buffer2, 0, 0 );
|
||||
Gia_ManPrintPathName( p, 0, Sink1, Buffer3, 0, 0 );
|
||||
if ( !Gia_ManPrintPathParseBit(Buffer2, Base0, &Bit0, Suffix0) ||
|
||||
!Gia_ManPrintPathParseBit(Buffer3, Base1, &Bit1, Suffix1) )
|
||||
{
|
||||
ABC_FREE( pStore );
|
||||
return 0;
|
||||
}
|
||||
RetValue = !strcmp(Base0, Base1) && !strcmp(Suffix0, Suffix1) && Bit1 == Bit0 + 1;
|
||||
ABC_FREE( pStore );
|
||||
return RetValue;
|
||||
}
|
||||
static int Gia_ManPrintPathCandBetter( int Level0, int Source0, int Sink0, int Level1, int Source1, int Sink1 )
|
||||
{
|
||||
if ( Level0 != Level1 )
|
||||
return Level0 > Level1;
|
||||
if ( Source0 != Source1 )
|
||||
return Source0 < Source1;
|
||||
return Sink0 < Sink1;
|
||||
}
|
||||
static int Gia_ManPrintPathFaninBetter( int Level0, int Source0, int Level1, int Source1 )
|
||||
{
|
||||
if ( Source0 < 0 )
|
||||
return 0;
|
||||
if ( Source1 < 0 )
|
||||
return 1;
|
||||
if ( Level0 != Level1 )
|
||||
return Level0 > Level1;
|
||||
return Source0 < Source1;
|
||||
}
|
||||
static void Gia_ManPrintPathInsert( int * pLevels, int * pSources, int * pSinks, int * pDrivers, int * pnPaths, int nPathsMax, int Level, int Source, int Sink, int Driver )
|
||||
{
|
||||
int i, k, nPaths = *pnPaths;
|
||||
if ( Source < 0 )
|
||||
return;
|
||||
for ( i = 0; i < nPaths; i++ )
|
||||
if ( Gia_ManPrintPathCandBetter(Level, Source, Sink, pLevels[i], pSources[i], pSinks[i]) )
|
||||
break;
|
||||
if ( i == nPathsMax )
|
||||
return;
|
||||
if ( nPaths < nPathsMax )
|
||||
nPaths++;
|
||||
for ( k = nPaths - 1; k > i; k-- )
|
||||
{
|
||||
pLevels[k] = pLevels[k-1];
|
||||
pSources[k] = pSources[k-1];
|
||||
pSinks[k] = pSinks[k-1];
|
||||
pDrivers[k] = pDrivers[k-1];
|
||||
}
|
||||
pLevels[i] = Level;
|
||||
pSources[i] = Source;
|
||||
pSinks[i] = Sink;
|
||||
pDrivers[i] = Driver;
|
||||
*pnPaths = nPaths;
|
||||
}
|
||||
static void Gia_ManPrintPathOne( Gia_Man_t * p, Vec_Int_t * vPreds, int Source, int Sink, int Driver, int nNameSize )
|
||||
{
|
||||
Vec_Int_t * vPath = Vec_IntAlloc( 100 );
|
||||
char * pBuffer = ABC_ALLOC( char, 2 * nNameSize );
|
||||
char * pBuffer0 = pBuffer;
|
||||
char * pBuffer1 = pBuffer + nNameSize;
|
||||
int i, Id;
|
||||
for ( Id = Driver; Id > 0 && !Gia_ObjIsCi(Gia_ManObj(p, Id)); Id = Vec_IntEntry(vPreds, Id) )
|
||||
{
|
||||
Vec_IntPush( vPath, Id );
|
||||
if ( Vec_IntEntry(vPreds, Id) < 0 )
|
||||
break;
|
||||
}
|
||||
printf( " %s[%d] %s", Gia_ManPrintPathKind(p, 1, Source), Gia_ManPrintPathTermIndex(p, 1, Source), Gia_ManPrintPathName(p, 1, Source, pBuffer0, 1, 0) );
|
||||
Vec_IntForEachEntryReverse( vPath, Id, i )
|
||||
printf( " -> AND %d", Id );
|
||||
printf( " -> %s[%d] %s\n", Gia_ManPrintPathKind(p, 0, Sink), Gia_ManPrintPathTermIndex(p, 0, Sink), Gia_ManPrintPathName(p, 0, Sink, pBuffer1, 1, 0) );
|
||||
ABC_FREE( pBuffer );
|
||||
Vec_IntFree( vPath );
|
||||
}
|
||||
void Gia_ManPrintPath( Gia_Man_t * p, int nPathsMax, int fVerbose, int fSummary )
|
||||
{
|
||||
Vec_Int_t * vLevels, * vSources, * vPreds;
|
||||
Vec_Int_t * vGroupStarts, * vGroupEnds;
|
||||
Gia_Obj_t * pObj;
|
||||
int * pLevels, * pSources, * pSinks, * pDrivers;
|
||||
int nGroupsMax = nPathsMax;
|
||||
int nPathsAlloc, nNameSize, nLineSize, nSourceTermW, nSourceNameW, nSinkTermW;
|
||||
int nPaths = 0, Counts[4] = {0}, MaxLevels[4] = {0};
|
||||
int i, k, Id, FanId, Level, Source, Sink, Driver, Cost, LevelBest, SourceBest, FanBest, nGroups, iBeg, iEnd;
|
||||
char * Buffer0, * Buffer1, * Buffer2, * Buffer3, * Buffer4, * Buffer5, * Buffer6, * Buffer7, * Buffer8, * Buffer9, * Buffer10;
|
||||
if ( nPathsMax < 1 )
|
||||
nPathsMax = 1;
|
||||
nGroupsMax = nPathsMax;
|
||||
nPathsAlloc = Abc_MinInt( Gia_ManCoNum(p), Abc_MaxInt(32 * nGroupsMax, nGroupsMax) );
|
||||
nNameSize = Gia_ManPrintPathNameBufferSize( p );
|
||||
nLineSize = 4 * nNameSize + 100;
|
||||
Buffer0 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer1 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer2 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer3 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer4 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer5 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer6 = ABC_ALLOC( char, nNameSize );
|
||||
Buffer7 = ABC_ALLOC( char, nLineSize );
|
||||
Buffer8 = ABC_ALLOC( char, nLineSize );
|
||||
Buffer9 = ABC_ALLOC( char, nLineSize );
|
||||
Buffer10 = ABC_ALLOC( char, nLineSize );
|
||||
vGroupStarts = Vec_IntAlloc( nGroupsMax );
|
||||
vGroupEnds = Vec_IntAlloc( nGroupsMax );
|
||||
vLevels = Vec_IntStart( Gia_ManObjNum(p) );
|
||||
vSources = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
vPreds = Vec_IntStartFull( Gia_ManObjNum(p) );
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
Id = Gia_ObjId( p, pObj );
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
Vec_IntWriteEntry( vLevels, Id, 0 );
|
||||
Vec_IntWriteEntry( vSources, Id, Gia_ObjCioId(pObj) );
|
||||
continue;
|
||||
}
|
||||
if ( !Gia_ObjIsAnd(pObj) )
|
||||
continue;
|
||||
Cost = (!p->fGiaSimple && Gia_ObjIsBuf(pObj)) ? 0 : (Gia_ObjIsMux(p, pObj) || Gia_ObjIsXor(pObj) ? 2 : 1);
|
||||
LevelBest = SourceBest = FanBest = -1;
|
||||
for ( k = 0; k < Gia_ObjFaninNum(p, pObj); k++ )
|
||||
{
|
||||
FanId = k == 2 ? Gia_ObjFaninId2(p, Id) : Gia_ObjFaninId(pObj, Id, k);
|
||||
Level = Vec_IntEntry( vLevels, FanId );
|
||||
Source = Vec_IntEntry( vSources, FanId );
|
||||
if ( Gia_ManPrintPathFaninBetter(Level, Source, LevelBest, SourceBest) )
|
||||
LevelBest = Level, SourceBest = Source, FanBest = FanId;
|
||||
}
|
||||
Vec_IntWriteEntry( vLevels, Id, LevelBest + Cost );
|
||||
Vec_IntWriteEntry( vSources, Id, SourceBest );
|
||||
Vec_IntWriteEntry( vPreds, Id, FanBest );
|
||||
}
|
||||
pLevels = ABC_ALLOC( int, nPathsAlloc );
|
||||
pSources = ABC_ALLOC( int, nPathsAlloc );
|
||||
pSinks = ABC_ALLOC( int, nPathsAlloc );
|
||||
pDrivers = ABC_ALLOC( int, nPathsAlloc );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
{
|
||||
Driver = Gia_ObjFaninId0p( p, pObj );
|
||||
Level = Vec_IntEntry( vLevels, Driver );
|
||||
Source = Vec_IntEntry( vSources, Driver );
|
||||
Sink = Gia_ObjCioId( pObj );
|
||||
if ( Source >= 0 )
|
||||
{
|
||||
k = (Source >= Gia_ManPiNum(p) ? 2 : 0) + (Sink >= Gia_ManPoNum(p) ? 1 : 0);
|
||||
Counts[k]++;
|
||||
MaxLevels[k] = Abc_MaxInt( MaxLevels[k], Level );
|
||||
}
|
||||
Gia_ManPrintPathInsert( pLevels, pSources, pSinks, pDrivers, &nPaths, nPathsAlloc, Level, Source, Sink, Driver );
|
||||
}
|
||||
for ( i = 0, nGroups = 0; i < nPaths && nGroups < nGroupsMax; i = iEnd + 1, nGroups++ )
|
||||
{
|
||||
iBeg = iEnd = i;
|
||||
while ( iEnd + 1 < nPaths && Gia_ManPrintPathCanGroup(p, pLevels[iEnd], pSources[iEnd], pSinks[iEnd], pLevels[iEnd+1], pSources[iEnd+1], pSinks[iEnd+1], nNameSize) )
|
||||
iEnd++;
|
||||
Vec_IntPush( vGroupStarts, iBeg );
|
||||
Vec_IntPush( vGroupEnds, iEnd );
|
||||
}
|
||||
nSourceTermW = (int)strlen( "source" );
|
||||
nSourceNameW = 0;
|
||||
nSinkTermW = (int)strlen( "sink" );
|
||||
Vec_IntForEachEntry( vGroupStarts, iBeg, i )
|
||||
{
|
||||
char * pSourceName, * pSourceLeaf, * pSinkNameBeg, * pSinkNameEnd, * pSinkLeafBeg, * pSinkLeafEnd;
|
||||
iEnd = Vec_IntEntry( vGroupEnds, i );
|
||||
pSourceName = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer0, 0, 0);
|
||||
pSourceLeaf = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer1, 0, 1);
|
||||
pSinkNameBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer2, 0, 0);
|
||||
pSinkNameEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer3, 0, 0);
|
||||
pSinkLeafBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer4, 0, 1);
|
||||
pSinkLeafEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer5, 0, 1);
|
||||
Gia_ManPrintPathFormatTermRange( Buffer6, Gia_ManPrintPathKind(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]) );
|
||||
sprintf( Buffer7, "%s", pSourceName );
|
||||
if ( strcmp(pSourceName, pSourceLeaf) )
|
||||
sprintf( Buffer7 + strlen(Buffer7), "->%s", pSourceLeaf );
|
||||
Gia_ManPrintPathFormatTermRange( Buffer8, Gia_ManPrintPathKind(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iEnd]) );
|
||||
Gia_ManPrintPathFormatNameRange( Buffer9, pSinkNameBeg, pSinkNameEnd, nNameSize );
|
||||
if ( strcmp(pSinkLeafBeg, pSinkLeafEnd) )
|
||||
Gia_ManPrintPathFormatNameRange( Buffer10, pSinkLeafBeg, pSinkLeafEnd, nNameSize );
|
||||
else
|
||||
sprintf( Buffer10, "%s", pSinkLeafBeg );
|
||||
if ( strcmp(Buffer9, Buffer10) )
|
||||
sprintf( Buffer9 + strlen(Buffer9), "<-%s", Buffer10 );
|
||||
nSourceTermW = Abc_MaxInt( nSourceTermW, (int)strlen(Buffer6) );
|
||||
nSourceNameW = Abc_MaxInt( nSourceNameW, (int)strlen(Buffer7) );
|
||||
nSinkTermW = Abc_MaxInt( nSinkTermW, (int)strlen(Buffer8) );
|
||||
}
|
||||
printf( "Grouped critical combinational paths:\n" );
|
||||
printf( " rank paths lev %-*s %-*s %-*s %s\n", nSourceTermW, "source", nSourceNameW, "", nSinkTermW, "sink", "" );
|
||||
Vec_IntForEachEntry( vGroupStarts, iBeg, i )
|
||||
{
|
||||
char * pSourceName, * pSourceLeaf, * pSinkNameBeg, * pSinkNameEnd, * pSinkLeafBeg, * pSinkLeafEnd;
|
||||
iEnd = Vec_IntEntry( vGroupEnds, i );
|
||||
pSourceName = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer0, 0, 0);
|
||||
pSourceLeaf = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer1, 0, 1);
|
||||
pSinkNameBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer2, 0, 0);
|
||||
pSinkNameEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer3, 0, 0);
|
||||
pSinkLeafBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer4, 0, 1);
|
||||
pSinkLeafEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer5, 0, 1);
|
||||
Gia_ManPrintPathFormatTermRange( Buffer6, Gia_ManPrintPathKind(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]) );
|
||||
sprintf( Buffer7, "%s", pSourceName );
|
||||
if ( strcmp(pSourceName, pSourceLeaf) )
|
||||
sprintf( Buffer7 + strlen(Buffer7), "->%s", pSourceLeaf );
|
||||
Gia_ManPrintPathFormatTermRange( Buffer8, Gia_ManPrintPathKind(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iEnd]) );
|
||||
Gia_ManPrintPathFormatNameRange( Buffer9, pSinkNameBeg, pSinkNameEnd, nNameSize );
|
||||
if ( strcmp(pSinkLeafBeg, pSinkLeafEnd) )
|
||||
Gia_ManPrintPathFormatNameRange( Buffer10, pSinkLeafBeg, pSinkLeafEnd, nNameSize );
|
||||
else
|
||||
sprintf( Buffer10, "%s", pSinkLeafBeg );
|
||||
if ( strcmp(Buffer9, Buffer10) )
|
||||
sprintf( Buffer9 + strlen(Buffer9), "<-%s", Buffer10 );
|
||||
if ( iBeg == iEnd )
|
||||
sprintf( Buffer4, "%d", iBeg + 1 );
|
||||
else
|
||||
sprintf( Buffer4, "%d..%d", iBeg + 1, iEnd + 1 );
|
||||
printf( "%5d %-7s %3d %-*s %-*s %-*s %s\n", i + 1, Buffer4, pLevels[iBeg], nSourceTermW, Buffer6, nSourceNameW, Buffer7, nSinkTermW, Buffer8, Buffer9 );
|
||||
}
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "\nAIG paths:\n" );
|
||||
Vec_IntForEachEntry( vGroupStarts, iBeg, i )
|
||||
Gia_ManPrintPathOne( p, vPreds, pSources[iBeg], pSinks[iBeg], pDrivers[iBeg], nNameSize );
|
||||
}
|
||||
if ( fSummary )
|
||||
{
|
||||
printf( "\nEndpoint summary:\n" );
|
||||
printf( " PI->PO : paths = %7d max levels = %6d\n", Counts[0], MaxLevels[0] );
|
||||
printf( " PI->RI : paths = %7d max levels = %6d\n", Counts[1], MaxLevels[1] );
|
||||
printf( " RO->PO : paths = %7d max levels = %6d\n", Counts[2], MaxLevels[2] );
|
||||
printf( " RO->RI : paths = %7d max levels = %6d\n", Counts[3], MaxLevels[3] );
|
||||
}
|
||||
ABC_FREE( pLevels );
|
||||
ABC_FREE( pSources );
|
||||
ABC_FREE( pSinks );
|
||||
ABC_FREE( pDrivers );
|
||||
ABC_FREE( Buffer0 );
|
||||
ABC_FREE( Buffer1 );
|
||||
ABC_FREE( Buffer2 );
|
||||
ABC_FREE( Buffer3 );
|
||||
ABC_FREE( Buffer4 );
|
||||
ABC_FREE( Buffer5 );
|
||||
ABC_FREE( Buffer6 );
|
||||
ABC_FREE( Buffer7 );
|
||||
ABC_FREE( Buffer8 );
|
||||
ABC_FREE( Buffer9 );
|
||||
ABC_FREE( Buffer10 );
|
||||
Vec_IntFree( vLevels );
|
||||
Vec_IntFree( vSources );
|
||||
Vec_IntFree( vPreds );
|
||||
Vec_IntFreeP( &vGroupStarts );
|
||||
Vec_IntFreeP( &vGroupEnds );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaBalLut.c \
|
||||
src/aig/gia/giaBalMap.c \
|
||||
src/aig/gia/giaBidec.c \
|
||||
src/aig/gia/giaBsFind.c \
|
||||
src/aig/gia/giaCCof.c \
|
||||
src/aig/gia/giaCex.c \
|
||||
src/aig/gia/giaClp.c \
|
||||
|
|
@ -15,6 +16,7 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaCSat.c \
|
||||
src/aig/gia/giaCSat2.c \
|
||||
src/aig/gia/giaCSat3.c \
|
||||
src/aig/gia/giaCSatP.c \
|
||||
src/aig/gia/giaCTas.c \
|
||||
src/aig/gia/giaCut.c \
|
||||
src/aig/gia/giaDecs.c \
|
||||
|
|
@ -48,6 +50,7 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaJf.c \
|
||||
src/aig/gia/giaKf.c \
|
||||
src/aig/gia/giaLf.c \
|
||||
src/aig/gia/giaLutCas.c \
|
||||
src/aig/gia/giaMf.c \
|
||||
src/aig/gia/giaMan.c \
|
||||
src/aig/gia/giaMem.c \
|
||||
|
|
@ -55,6 +58,8 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaMini.c \
|
||||
src/aig/gia/giaMinLut.c \
|
||||
src/aig/gia/giaMinLut2.c \
|
||||
src/aig/gia/giaMulFind.c \
|
||||
src/aig/gia/giaMulFind3.c \
|
||||
src/aig/gia/giaMuxes.c \
|
||||
src/aig/gia/giaNf.c \
|
||||
src/aig/gia/giaOf.c \
|
||||
|
|
@ -68,13 +73,16 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaResub.c \
|
||||
src/aig/gia/giaResub2.c \
|
||||
src/aig/gia/giaResub3.c \
|
||||
src/aig/gia/giaResub6.c \
|
||||
src/aig/gia/giaRetime.c \
|
||||
src/aig/gia/giaRex.c \
|
||||
src/aig/gia/giaRrr.cpp \
|
||||
src/aig/gia/giaSatEdge.c \
|
||||
src/aig/gia/giaSatLE.c \
|
||||
src/aig/gia/giaSatLut.c \
|
||||
src/aig/gia/giaSatMap.c \
|
||||
src/aig/gia/giaSatoko.c \
|
||||
src/aig/gia/giaSatSyn.c \
|
||||
src/aig/gia/giaSat3.c \
|
||||
src/aig/gia/giaScl.c \
|
||||
src/aig/gia/giaScript.c \
|
||||
|
|
@ -82,6 +90,7 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaShrink.c \
|
||||
src/aig/gia/giaShrink6.c \
|
||||
src/aig/gia/giaShrink7.c \
|
||||
src/aig/gia/giaSif.c \
|
||||
src/aig/gia/giaSim.c \
|
||||
src/aig/gia/giaSim2.c \
|
||||
src/aig/gia/giaSimBase.c \
|
||||
|
|
@ -99,7 +108,12 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaSwitch.c \
|
||||
src/aig/gia/giaTim.c \
|
||||
src/aig/gia/giaTis.c \
|
||||
src/aig/gia/giaTransduction.cpp \
|
||||
src/aig/gia/giaTranStoch.c \
|
||||
src/aig/gia/giaTruth.c \
|
||||
src/aig/gia/giaTsim.c \
|
||||
src/aig/gia/giaTtopt.cpp \
|
||||
src/aig/gia/giaUnate.c \
|
||||
src/aig/gia/giaUtil.c
|
||||
src/aig/gia/giaUtil.c \
|
||||
src/aig/gia/giaBound.c \
|
||||
src/aig/gia/giaDecGraph.cpp
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ static inline Hop_Obj_t * Hop_ManFetchMemory( Hop_Man_t * p )
|
|||
if ( p->pListFree == NULL )
|
||||
Hop_ManAddMemory( p );
|
||||
pTemp = p->pListFree;
|
||||
p->pListFree = *((Hop_Obj_t **)pTemp);
|
||||
memcpy(&p->pListFree, pTemp, sizeof(Hop_Obj_t *));
|
||||
memset( pTemp, 0, sizeof(Hop_Obj_t) );
|
||||
if ( p->vObjs )
|
||||
{
|
||||
|
|
@ -245,8 +245,8 @@ static inline Hop_Obj_t * Hop_ManFetchMemory( Hop_Man_t * p )
|
|||
}
|
||||
static inline void Hop_ManRecycleMemory( Hop_Man_t * p, Hop_Obj_t * pEntry )
|
||||
{
|
||||
pEntry->Type = AIG_NONE; // distinquishes dead node from live node
|
||||
*((Hop_Obj_t **)pEntry) = p->pListFree;
|
||||
pEntry->Type = AIG_NONE; // distinguishes dead node from live node
|
||||
memcpy(pEntry, &p->pListFree, sizeof(Hop_Obj_t *));
|
||||
p->pListFree = pEntry;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,13 +88,15 @@ void Hop_ManStopMemory( Hop_Man_t * p )
|
|||
***********************************************************************/
|
||||
void Hop_ManAddMemory( Hop_Man_t * p )
|
||||
{
|
||||
char * pMemory;
|
||||
char * pMemory = 0;
|
||||
Hop_Obj_t * pEntry, * pNext;
|
||||
int i, nBytes;
|
||||
assert( sizeof(Hop_Obj_t) <= 64 );
|
||||
assert( p->pListFree == NULL );
|
||||
// assert( (Hop_ManObjNum(p) & IVY_PAGE_MASK) == 0 );
|
||||
// allocate new memory page
|
||||
nBytes = sizeof(Hop_Obj_t) * (1<<IVY_PAGE_SIZE) + 64;
|
||||
pMemory = pMemory + 64 - (((int)(ABC_PTRUINT_T)pMemory) & 63);
|
||||
pMemory = ABC_ALLOC( char, nBytes );
|
||||
Vec_PtrPush( p->vChunks, pMemory );
|
||||
// align memory at the 32-byte boundary
|
||||
|
|
@ -102,13 +104,16 @@ void Hop_ManAddMemory( Hop_Man_t * p )
|
|||
// remember the manager in the first entry
|
||||
Vec_PtrPush( p->vPages, pMemory );
|
||||
// break the memory down into nodes
|
||||
p->pListFree = (Hop_Obj_t *)pMemory;
|
||||
pEntry = (Hop_Obj_t *)pMemory;
|
||||
p->pListFree = pEntry;
|
||||
for ( i = 1; i <= IVY_PAGE_MASK; i++ )
|
||||
{
|
||||
*((char **)pMemory) = pMemory + sizeof(Hop_Obj_t);
|
||||
pMemory += sizeof(Hop_Obj_t);
|
||||
pNext = pEntry + 1;
|
||||
memcpy( pEntry, &pNext, sizeof(Hop_Obj_t *) );
|
||||
pEntry++;
|
||||
}
|
||||
*((char **)pMemory) = NULL;
|
||||
pNext = NULL;
|
||||
memcpy( pEntry, &pNext, sizeof(Hop_Obj_t *) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -438,7 +438,7 @@ Aig_Man_t * Ioa_ReadAiger( char * pFileName, int fCheck )
|
|||
// read the file into the buffer
|
||||
nFileSize = Ioa_FileSize( pFileName );
|
||||
pFile = fopen( pFileName, "rb" );
|
||||
pContents = ABC_ALLOC( char, nFileSize );
|
||||
pContents = ABC_CALLOC( char, nFileSize+1 );
|
||||
RetValue = fread( pContents, nFileSize, 1, pFile );
|
||||
fclose( pFile );
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ static void Ivy_WriteDotAig( Ivy_Man_t * pMan, char * pFileName, int fHaig, Vec_
|
|||
***********************************************************************/
|
||||
void Ivy_ManShow( Ivy_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold )
|
||||
{
|
||||
extern void Abc_ShowFile( char * FileNameDot );
|
||||
extern void Abc_ShowFile( char * FileNameDot, int fKeepDot );
|
||||
static int Counter = 0;
|
||||
char FileNameDot[200];
|
||||
FILE * pFile;
|
||||
|
|
@ -63,7 +63,7 @@ void Ivy_ManShow( Ivy_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold )
|
|||
// generate the file
|
||||
Ivy_WriteDotAig( pMan, FileNameDot, fHaig, vBold );
|
||||
// visualize the file
|
||||
Abc_ShowFile( FileNameDot );
|
||||
Abc_ShowFile( FileNameDot, 0 );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
|
|||
|
|
@ -226,6 +226,10 @@ static inline const char * Abc_OperName( int Type )
|
|||
if ( Type == ABC_OPER_ZEROPAD ) return "zPad";
|
||||
if ( Type == ABC_OPER_SIGNEXT ) return "sExt";
|
||||
|
||||
if ( Type == ABC_OPER_BIT_MUX ) return "mux";
|
||||
if ( Type == ABC_OPER_SEL_NMUX ) return "nmux";
|
||||
if ( Type == ABC_OPER_SEL_SEL ) return "pmux";
|
||||
|
||||
if ( Type == ABC_OPER_CONST ) return "const";
|
||||
if ( Type == ABC_OPER_TABLE ) return "table";
|
||||
if ( Type == ABC_OPER_LUT ) return "lut";
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef _VERIFIC_DATABASE_H_
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
|
|
@ -92,15 +94,21 @@ static void Mini_AigPush( Mini_Aig_t * p, int Lit0, int Lit1 )
|
|||
static int Mini_AigNodeFanin0( Mini_Aig_t * p, int Id )
|
||||
{
|
||||
assert( Id >= 0 && 2*Id < p->nSize );
|
||||
assert( p->pArray[2*Id] == 0x7FFFFFFF || p->pArray[2*Id] < 2*Id );
|
||||
assert( p->pArray[2*Id] == MINI_AIG_NULL || p->pArray[2*Id] < 2*Id );
|
||||
return p->pArray[2*Id];
|
||||
}
|
||||
static int Mini_AigNodeFanin1( Mini_Aig_t * p, int Id )
|
||||
{
|
||||
assert( Id >= 0 && 2*Id < p->nSize );
|
||||
assert( p->pArray[2*Id+1] == 0x7FFFFFFF || p->pArray[2*Id+1] < 2*Id );
|
||||
assert( p->pArray[2*Id+1] == MINI_AIG_NULL || p->pArray[2*Id+1] < 2*Id );
|
||||
return p->pArray[2*Id+1];
|
||||
}
|
||||
static void Mini_AigFlipLastPo( Mini_Aig_t * p )
|
||||
{
|
||||
assert( p->pArray[p->nSize-1] == MINI_AIG_NULL );
|
||||
assert( p->pArray[p->nSize-2] != MINI_AIG_NULL );
|
||||
p->pArray[p->nSize-2] ^= 1;
|
||||
}
|
||||
|
||||
// working with variables and literals
|
||||
static int Mini_AigVar2Lit( int Var, int fCompl ) { return Var + Var + fCompl; }
|
||||
|
|
@ -142,6 +150,46 @@ static Mini_Aig_t * Mini_AigStart()
|
|||
Mini_AigPush( p, MINI_AIG_NULL, MINI_AIG_NULL );
|
||||
return p;
|
||||
}
|
||||
static Mini_Aig_t * Mini_AigStartSupport( int nIns, int nObjsAlloc )
|
||||
{
|
||||
Mini_Aig_t * p; int i;
|
||||
assert( 1+nIns < nObjsAlloc );
|
||||
p = MINI_AIG_CALLOC( Mini_Aig_t, 1 );
|
||||
p->nCap = 2*nObjsAlloc;
|
||||
p->nSize = 2*(1+nIns);
|
||||
p->pArray = MINI_AIG_ALLOC( int, p->nCap );
|
||||
for ( i = 0; i < p->nSize; i++ )
|
||||
p->pArray[i] = MINI_AIG_NULL;
|
||||
return p;
|
||||
}
|
||||
static Mini_Aig_t * Mini_AigStartArray( int nIns, int n0InAnds, int * p0InAnds, int nOuts, int * pOuts )
|
||||
{
|
||||
Mini_Aig_t * p; int i;
|
||||
assert( 1+nIns <= n0InAnds );
|
||||
p = MINI_AIG_CALLOC( Mini_Aig_t, 1 );
|
||||
p->nCap = 2*(n0InAnds + nOuts);
|
||||
p->nSize = 2*(n0InAnds + nOuts);
|
||||
p->pArray = MINI_AIG_ALLOC( int, p->nCap );
|
||||
for ( i = 0; i < 2*(1 + nIns); i++ )
|
||||
p->pArray[i] = MINI_AIG_NULL;
|
||||
memcpy( p->pArray + 2*(1 + nIns), p0InAnds + 2*(1 + nIns), 2*(n0InAnds - 1 - nIns)*sizeof(int) );
|
||||
for ( i = 0; i < nOuts; i++ )
|
||||
{
|
||||
p->pArray[2*(n0InAnds + i)+0] = pOuts[i];
|
||||
p->pArray[2*(n0InAnds + i)+1] = MINI_AIG_NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
static Mini_Aig_t * Mini_AigDup( Mini_Aig_t * p )
|
||||
{
|
||||
Mini_Aig_t * pNew;
|
||||
pNew = MINI_AIG_CALLOC( Mini_Aig_t, 1 );
|
||||
pNew->nCap = p->nCap;
|
||||
pNew->nSize = p->nSize;
|
||||
pNew->pArray = MINI_AIG_ALLOC( int, p->nSize );
|
||||
memcpy( pNew->pArray, p->pArray, p->nSize * sizeof(int) );
|
||||
return pNew;
|
||||
}
|
||||
static void Mini_AigStop( Mini_Aig_t * p )
|
||||
{
|
||||
MINI_AIG_FREE( p->pArray );
|
||||
|
|
@ -168,9 +216,34 @@ static int Mini_AigAndNum( Mini_Aig_t * p )
|
|||
nNodes++;
|
||||
return nNodes;
|
||||
}
|
||||
static int Mini_AigXorNum( Mini_Aig_t * p )
|
||||
{
|
||||
int i, nNodes = 0;
|
||||
Mini_AigForEachAnd( p, i )
|
||||
nNodes += p->pArray[2*i] > p->pArray[2*i+1];
|
||||
return nNodes;
|
||||
}
|
||||
static int Mini_AigLevelNum( Mini_Aig_t * p )
|
||||
{
|
||||
int i, Level = 0;
|
||||
int * pLevels = MINI_AIG_CALLOC( int, Mini_AigNodeNum(p) );
|
||||
Mini_AigForEachAnd( p, i )
|
||||
{
|
||||
int Lel0 = pLevels[Mini_AigLit2Var(Mini_AigNodeFanin0(p, i))];
|
||||
int Lel1 = pLevels[Mini_AigLit2Var(Mini_AigNodeFanin1(p, i))];
|
||||
pLevels[i] = 1 + (Lel0 > Lel1 ? Lel0 : Lel1);
|
||||
}
|
||||
Mini_AigForEachPo( p, i )
|
||||
{
|
||||
int Lel0 = pLevels[Mini_AigLit2Var(Mini_AigNodeFanin0(p, i))];
|
||||
Level = Level > Lel0 ? Level : Lel0;
|
||||
}
|
||||
MINI_AIG_FREE( pLevels );
|
||||
return Level;
|
||||
}
|
||||
static void Mini_AigPrintStats( Mini_Aig_t * p )
|
||||
{
|
||||
printf( "PI = %d. PO = %d. Node = %d.\n", Mini_AigPiNum(p), Mini_AigPoNum(p), Mini_AigAndNum(p) );
|
||||
printf( "MiniAIG stats: PI = %d PO = %d FF = %d AND = %d\n", Mini_AigPiNum(p), Mini_AigPoNum(p), Mini_AigRegNum(p), Mini_AigAndNum(p) );
|
||||
}
|
||||
|
||||
// serialization
|
||||
|
|
@ -233,7 +306,10 @@ static int Mini_AigAnd( Mini_Aig_t * p, int Lit0, int Lit1 )
|
|||
int Lit = p->nSize;
|
||||
assert( Lit0 >= 0 && Lit0 < Lit );
|
||||
assert( Lit1 >= 0 && Lit1 < Lit );
|
||||
Mini_AigPush( p, Lit0, Lit1 );
|
||||
if ( Lit0 < Lit1 )
|
||||
Mini_AigPush( p, Lit0, Lit1 );
|
||||
else
|
||||
Mini_AigPush( p, Lit1, Lit0 );
|
||||
return Lit;
|
||||
}
|
||||
static int Mini_AigOr( Mini_Aig_t * p, int Lit0, int Lit1 )
|
||||
|
|
@ -250,6 +326,101 @@ static int Mini_AigXor( Mini_Aig_t * p, int Lit0, int Lit1 )
|
|||
{
|
||||
return Mini_AigMux( p, Lit0, Mini_AigLitNot(Lit1), Lit1 );
|
||||
}
|
||||
static int Mini_AigXorSpecial( Mini_Aig_t * p, int Lit0, int Lit1 )
|
||||
{
|
||||
int Lit = p->nSize;
|
||||
assert( Lit0 >= 0 && Lit0 < Lit );
|
||||
assert( Lit1 >= 0 && Lit1 < Lit );
|
||||
if ( Lit0 > Lit1 )
|
||||
Mini_AigPush( p, Lit0, Lit1 );
|
||||
else
|
||||
Mini_AigPush( p, Lit1, Lit0 );
|
||||
return Lit;
|
||||
}
|
||||
static int Mini_AigAndMulti( Mini_Aig_t * p, int * pLits, int nLits )
|
||||
{
|
||||
int i;
|
||||
assert( nLits > 0 );
|
||||
while ( nLits > 1 )
|
||||
{
|
||||
for ( i = 0; i < nLits/2; i++ )
|
||||
pLits[i] = Mini_AigAnd(p, pLits[2*i], pLits[2*i+1]);
|
||||
if ( nLits & 1 )
|
||||
pLits[i++] = pLits[nLits-1];
|
||||
nLits = i;
|
||||
}
|
||||
return pLits[0];
|
||||
}
|
||||
static int Mini_AigXorMulti( Mini_Aig_t * p, int * pLits, int nLits )
|
||||
{
|
||||
int i;
|
||||
assert( nLits > 0 );
|
||||
while ( nLits > 1 )
|
||||
{
|
||||
for ( i = 0; i < nLits/2; i++ )
|
||||
pLits[i] = Mini_AigXor(p, pLits[2*i], pLits[2*i+1]);
|
||||
if ( nLits & 1 )
|
||||
pLits[i++] = pLits[nLits-1];
|
||||
nLits = i;
|
||||
}
|
||||
return pLits[0];
|
||||
}
|
||||
static int Mini_AigMuxMulti( Mini_Aig_t * p, int * pCtrl, int nCtrl, int * pData, int nData )
|
||||
{
|
||||
int i, c;
|
||||
assert( nData > 0 );
|
||||
if ( nCtrl == 0 )
|
||||
return pData[0];
|
||||
assert( nData <= (1 << nCtrl) );
|
||||
for ( c = 0; c < nCtrl; c++ )
|
||||
{
|
||||
for ( i = 0; i < nData/2; i++ )
|
||||
pData[i] = Mini_AigMux( p, pCtrl[c], pData[2*i+1], pData[2*i] );
|
||||
if ( nData & 1 )
|
||||
pData[i++] = Mini_AigMux( p, pCtrl[c], 0, pData[nData-1] );
|
||||
nData = i;
|
||||
}
|
||||
assert( nData == 1 );
|
||||
return pData[0];
|
||||
}
|
||||
static int Mini_AigMuxMulti_rec( Mini_Aig_t * p, int * pCtrl, int * pData, int nData )
|
||||
{
|
||||
int Res0, Res1;
|
||||
assert( nData > 0 );
|
||||
if ( nData == 1 )
|
||||
return pData[0];
|
||||
assert( nData % 2 == 0 );
|
||||
Res0 = Mini_AigMuxMulti_rec( p, pCtrl+1, pData, nData/2 );
|
||||
Res1 = Mini_AigMuxMulti_rec( p, pCtrl+1, pData+nData/2, nData/2 );
|
||||
return Mini_AigMux( p, pCtrl[0], Res1, Res0 );
|
||||
}
|
||||
static Mini_Aig_t * Mini_AigTransformXor( Mini_Aig_t * p )
|
||||
{
|
||||
Mini_Aig_t * pNew = Mini_AigStart();
|
||||
int i, * pCopy = MINI_AIG_ALLOC( int, Mini_AigNodeNum(p) );
|
||||
Mini_AigForEachPi( p, i )
|
||||
pCopy[i] = Mini_AigCreatePi(pNew);
|
||||
Mini_AigForEachAnd( p, i )
|
||||
{
|
||||
int iLit0 = Mini_AigNodeFanin0(p, i);
|
||||
int iLit1 = Mini_AigNodeFanin1(p, i);
|
||||
iLit0 = Mini_AigLitNotCond( pCopy[Mini_AigLit2Var(iLit0)], Mini_AigLitIsCompl(iLit0) );
|
||||
iLit1 = Mini_AigLitNotCond( pCopy[Mini_AigLit2Var(iLit1)], Mini_AigLitIsCompl(iLit1) );
|
||||
if ( iLit0 <= iLit1 )
|
||||
pCopy[i] = Mini_AigAnd( pNew, iLit0, iLit1 );
|
||||
else
|
||||
pCopy[i] = Mini_AigXor( pNew, iLit0, iLit1 );
|
||||
}
|
||||
Mini_AigForEachPo( p, i )
|
||||
{
|
||||
int iLit0 = Mini_AigNodeFanin0( p, i );
|
||||
iLit0 = Mini_AigLitNotCond( pCopy[Mini_AigLit2Var(iLit0)], Mini_AigLitIsCompl(iLit0) );
|
||||
pCopy[i] = Mini_AigCreatePo( pNew, iLit0 );
|
||||
}
|
||||
MINI_AIG_FREE( pCopy );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
static unsigned s_MiniTruths5[5] = {
|
||||
0xAAAAAAAA,
|
||||
|
|
@ -308,6 +479,20 @@ static inline int Mini_AigTruth( Mini_Aig_t * p, int * pVarLits, int nVars, unsi
|
|||
Lit1 = Mini_AigTruth( p, pVarLits, Var, Mini_AigTt5Cofactor1(Truth, Var) );
|
||||
return Mini_AigMuxProp( p, pVarLits[Var], Lit1, Lit0 );
|
||||
}
|
||||
static char * Mini_AigPhase( Mini_Aig_t * p )
|
||||
{
|
||||
char * pRes = MINI_AIG_CALLOC( char, Mini_AigNodeNum(p) );
|
||||
int i;
|
||||
Mini_AigForEachAnd( p, i )
|
||||
{
|
||||
int iFaninLit0 = Mini_AigNodeFanin0( p, i );
|
||||
int iFaninLit1 = Mini_AigNodeFanin1( p, i );
|
||||
int Phase0 = pRes[Mini_AigLit2Var(iFaninLit0)] ^ Mini_AigLitIsCompl(iFaninLit0);
|
||||
int Phase1 = pRes[Mini_AigLit2Var(iFaninLit1)] ^ Mini_AigLitIsCompl(iFaninLit1);
|
||||
pRes[i] = Phase0 & Phase1;
|
||||
}
|
||||
return pRes;
|
||||
}
|
||||
|
||||
// procedure to check the topological order during AIG construction
|
||||
static int Mini_AigCheck( Mini_Aig_t * p )
|
||||
|
|
@ -340,11 +525,11 @@ static int Mini_AigCheck( Mini_Aig_t * p )
|
|||
static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_t * p )
|
||||
{
|
||||
int i, k, iFaninLit0, iFaninLit1, Length = strlen(pModuleName), nPos = Mini_AigPoNum(p);
|
||||
Vec_Bit_t * vObjIsPi = Vec_BitStart( Mini_AigNodeNum(p) );
|
||||
char * pObjIsPi = MINI_AIG_CALLOC( char, Mini_AigNodeNum(p) );
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL ) { printf( "Cannot open output file %s\n", pFileName ); return; }
|
||||
if ( pFile == NULL ) { printf( "Cannot open output file %s\n", pFileName ); MINI_AIG_FREE( pObjIsPi ); return; }
|
||||
// write interface
|
||||
fprintf( pFile, "// This MiniAIG dump was produced by ABC on %s\n\n", Extra_TimeStamp() );
|
||||
//fprintf( pFile, "// This MiniAIG dump was produced by ABC on %s\n\n", Extra_TimeStamp() );
|
||||
fprintf( pFile, "module %s (\n", pModuleName );
|
||||
if ( Mini_AigPiNum(p) > 0 )
|
||||
{
|
||||
|
|
@ -354,7 +539,7 @@ static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_
|
|||
{
|
||||
if ( k++ % 12 == 0 ) fprintf( pFile, "\n%*s", Length+10, "" );
|
||||
fprintf( pFile, "i%d, ", i );
|
||||
Vec_BitWriteEntry( vObjIsPi, i, 1 );
|
||||
pObjIsPi[i] = 1;
|
||||
}
|
||||
}
|
||||
fprintf( pFile, "\n%*soutput wire", Length+10, "" );
|
||||
|
|
@ -371,9 +556,9 @@ static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_
|
|||
iFaninLit0 = Mini_AigNodeFanin0( p, i );
|
||||
iFaninLit1 = Mini_AigNodeFanin1( p, i );
|
||||
fprintf( pFile, " assign n%d = ", i );
|
||||
fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", Vec_BitEntry(vObjIsPi, iFaninLit0 >> 1) ? 'i':'n', iFaninLit0 >> 1 );
|
||||
fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", pObjIsPi[iFaninLit0 >> 1] ? 'i':'n', iFaninLit0 >> 1 );
|
||||
fprintf( pFile, " & " );
|
||||
fprintf( pFile, "%s%c%d", (iFaninLit1 & 1) ? "~":"", Vec_BitEntry(vObjIsPi, iFaninLit1 >> 1) ? 'i':'n', iFaninLit1 >> 1 );
|
||||
fprintf( pFile, "%s%c%d", (iFaninLit1 & 1) ? "~":"", pObjIsPi[iFaninLit1 >> 1] ? 'i':'n', iFaninLit1 >> 1 );
|
||||
fprintf( pFile, ";\n" );
|
||||
}
|
||||
// write assigns
|
||||
|
|
@ -382,23 +567,297 @@ static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_
|
|||
{
|
||||
iFaninLit0 = Mini_AigNodeFanin0( p, i );
|
||||
fprintf( pFile, " assign o%d = ", i );
|
||||
fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", Vec_BitEntry(vObjIsPi, iFaninLit0 >> 1) ? 'i':'n', iFaninLit0 >> 1 );
|
||||
fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", pObjIsPi[iFaninLit0 >> 1] ? 'i':'n', iFaninLit0 >> 1 );
|
||||
fprintf( pFile, ";\n" );
|
||||
}
|
||||
fprintf( pFile, "\nendmodule // %s \n\n\n", pModuleName );
|
||||
Vec_BitFree( vObjIsPi );
|
||||
MINI_AIG_FREE( pObjIsPi );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
// procedure to dump MiniAIG into a BLIF file
|
||||
static void Mini_AigDumpBlif( char * pFileName, char * pModuleName, Mini_Aig_t * p, int fVerbose )
|
||||
{
|
||||
int i, k, iFaninLit0, iFaninLit1;
|
||||
char * pObjIsPi = MINI_AIG_FALLOC( char, Mini_AigNodeNum(p) );
|
||||
FILE * pFile = fopen( pFileName, "wb" );
|
||||
assert( Mini_AigPiNum(p) <= 26 );
|
||||
if ( pFile == NULL ) { printf( "Cannot open output file %s\n", pFileName ); MINI_AIG_FREE( pObjIsPi ); return; }
|
||||
// write interface
|
||||
//fprintf( pFile, "// This MiniAIG dump was produced by ABC on %s\n\n", Extra_TimeStamp() );
|
||||
fprintf( pFile, ".model %s\n", pModuleName );
|
||||
if ( Mini_AigPiNum(p) )
|
||||
{
|
||||
k = 0;
|
||||
fprintf( pFile, ".inputs" );
|
||||
Mini_AigForEachPi( p, i )
|
||||
{
|
||||
pObjIsPi[i] = k;
|
||||
fprintf( pFile, " %c", (char)('a'+k++) );
|
||||
}
|
||||
}
|
||||
k = 0;
|
||||
fprintf( pFile, "\n.outputs" );
|
||||
Mini_AigForEachPo( p, i )
|
||||
fprintf( pFile, " o%d", k++ );
|
||||
fprintf( pFile, "\n\n" );
|
||||
// write LUTs
|
||||
Mini_AigForEachAnd( p, i )
|
||||
{
|
||||
iFaninLit0 = Mini_AigNodeFanin0( p, i );
|
||||
iFaninLit1 = Mini_AigNodeFanin1( p, i );
|
||||
fprintf( pFile, ".names" );
|
||||
if ( pObjIsPi[iFaninLit0 >> 1] >= 0 )
|
||||
fprintf( pFile, " %c", (char)('a'+pObjIsPi[iFaninLit0 >> 1]) );
|
||||
else
|
||||
fprintf( pFile, " n%d", iFaninLit0 >> 1 );
|
||||
if ( pObjIsPi[iFaninLit1 >> 1] >= 0 )
|
||||
fprintf( pFile, " %c", (char)('a'+pObjIsPi[iFaninLit1 >> 1]) );
|
||||
else
|
||||
fprintf( pFile, " n%d", iFaninLit1 >> 1 );
|
||||
fprintf( pFile, " n%d\n", i );
|
||||
if ( iFaninLit0 < iFaninLit1 )
|
||||
fprintf( pFile, "%d%d 1\n", !(iFaninLit0 & 1), !(iFaninLit1 & 1) );
|
||||
else if ( !(iFaninLit0 & 1) == !(iFaninLit1 & 1) )
|
||||
fprintf( pFile, "10 1\n01 1\n" );
|
||||
else
|
||||
fprintf( pFile, "00 1\n11 1\n" );
|
||||
}
|
||||
// write assigns
|
||||
fprintf( pFile, "\n" );
|
||||
k = 0;
|
||||
Mini_AigForEachPo( p, i )
|
||||
{
|
||||
iFaninLit0 = Mini_AigNodeFanin0( p, i );
|
||||
fprintf( pFile, ".names" );
|
||||
if ( pObjIsPi[iFaninLit0 >> 1] >= 0 )
|
||||
fprintf( pFile, " %c", (char)('a'+pObjIsPi[iFaninLit0 >> 1]) );
|
||||
else
|
||||
fprintf( pFile, " n%d", iFaninLit0 >> 1 );
|
||||
fprintf( pFile, " o%d\n", k++ );
|
||||
fprintf( pFile, "%d 1\n", !(iFaninLit0 & 1) );
|
||||
}
|
||||
fprintf( pFile, ".end\n\n" );
|
||||
MINI_AIG_FREE( pObjIsPi );
|
||||
fclose( pFile );
|
||||
if ( fVerbose )
|
||||
printf( "Written MiniAIG into the BLIF file \"%s\".\n", pFileName );
|
||||
}
|
||||
|
||||
|
||||
// checks if MiniAIG is normalized (first inputs, then internal nodes, then outputs)
|
||||
static int Mini_AigIsNormalized( Mini_Aig_t * p )
|
||||
{
|
||||
int nCiNum = Mini_AigPiNum(p);
|
||||
int nCoNum = Mini_AigPoNum(p);
|
||||
int i, nOffset = 1;
|
||||
for ( i = 0; i < nCiNum; i++ )
|
||||
if ( !Mini_AigNodeIsPi( p, nOffset+i ) )
|
||||
return 0;
|
||||
nOffset = Mini_AigNodeNum(p) - nCoNum;
|
||||
for ( i = 0; i < nCoNum; i++ )
|
||||
if ( !Mini_AigNodeIsPo( p, nOffset+i ) )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MiniAIG reading from / write into AIGER ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static unsigned Mini_AigerReadUnsigned( FILE * pFile )
|
||||
{
|
||||
unsigned x = 0, i = 0;
|
||||
unsigned char ch;
|
||||
while ((ch = fgetc(pFile)) & 0x80)
|
||||
x |= (ch & 0x7f) << (7 * i++);
|
||||
return x | (ch << (7 * i));
|
||||
}
|
||||
static void Mini_AigerWriteUnsigned( FILE * pFile, unsigned x )
|
||||
{
|
||||
unsigned char ch;
|
||||
while (x & ~0x7f)
|
||||
{
|
||||
ch = (x & 0x7f) | 0x80;
|
||||
fputc( ch, pFile );
|
||||
x >>= 7;
|
||||
}
|
||||
ch = x;
|
||||
fputc( ch, pFile );
|
||||
}
|
||||
static int * Mini_AigerReadInt( char * pFileName, int * pnObjs, int * pnIns, int * pnLatches, int * pnOuts, int * pnAnds )
|
||||
{
|
||||
int i, Temp, nTotal, nObjs, nIns, nLatches, nOuts, nAnds, * pObjs;
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
fprintf( stdout, "Mini_AigerRead(): Cannot open the output file \"%s\".\n", pFileName );
|
||||
return NULL;
|
||||
}
|
||||
if ( fgetc(pFile) != 'a' || fgetc(pFile) != 'i' || fgetc(pFile) != 'g' )
|
||||
{
|
||||
fprintf( stdout, "Mini_AigerRead(): Can only read binary AIGER.\n" );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
if ( fscanf(pFile, "%d %d %d %d %d", &nTotal, &nIns, &nLatches, &nOuts, &nAnds) != 5 )
|
||||
{
|
||||
fprintf( stdout, "Mini_AigerRead(): Cannot read the header line.\n" );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
if ( nTotal != nIns + nLatches + nAnds )
|
||||
{
|
||||
fprintf( stdout, "The number of objects does not match.\n" );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
nObjs = 1 + nIns + 2*nLatches + nOuts + nAnds;
|
||||
pObjs = MINI_AIG_CALLOC( int, nObjs * 2 );
|
||||
for ( i = 0; i <= nIns + nLatches; i++ )
|
||||
pObjs[2*i] = pObjs[2*i+1] = MINI_AIG_NULL;
|
||||
// read flop input literals
|
||||
for ( i = 0; i < nLatches; i++ )
|
||||
{
|
||||
while ( fgetc(pFile) != '\n' );
|
||||
fscanf( pFile, "%d", &Temp );
|
||||
pObjs[2*(nObjs-nLatches+i)+0] = Temp;
|
||||
pObjs[2*(nObjs-nLatches+i)+1] = MINI_AIG_NULL;
|
||||
}
|
||||
// read output literals
|
||||
for ( i = 0; i < nOuts; i++ )
|
||||
{
|
||||
while ( fgetc(pFile) != '\n' );
|
||||
fscanf( pFile, "%d", &Temp );
|
||||
pObjs[2*(nObjs-nOuts-nLatches+i)+0] = Temp;
|
||||
pObjs[2*(nObjs-nOuts-nLatches+i)+1] = MINI_AIG_NULL;
|
||||
}
|
||||
// read the binary part
|
||||
while ( fgetc(pFile) != '\n' );
|
||||
for ( i = 0; i < nAnds; i++ )
|
||||
{
|
||||
int uLit = 2*(1+nIns+nLatches+i);
|
||||
int uLit1 = uLit - Mini_AigerReadUnsigned( pFile );
|
||||
int uLit0 = uLit1 - Mini_AigerReadUnsigned( pFile );
|
||||
pObjs[uLit+0] = uLit0;
|
||||
pObjs[uLit+1] = uLit1;
|
||||
}
|
||||
fclose( pFile );
|
||||
if ( pnObjs ) *pnObjs = nObjs;
|
||||
if ( pnIns ) *pnIns = nIns;
|
||||
if ( pnLatches ) *pnLatches = nLatches;
|
||||
if ( pnOuts ) *pnOuts = nOuts;
|
||||
if ( pnAnds ) *pnAnds = nAnds;
|
||||
return pObjs;
|
||||
}
|
||||
static Mini_Aig_t * Mini_AigerRead( char * pFileName, int fVerbose )
|
||||
{
|
||||
Mini_Aig_t * p;
|
||||
int nObjs, nIns, nLatches, nOuts, nAnds, * pObjs = Mini_AigerReadInt( pFileName, &nObjs, &nIns, &nLatches, &nOuts, &nAnds );
|
||||
if ( pObjs == NULL )
|
||||
return NULL;
|
||||
p = MINI_AIG_CALLOC( Mini_Aig_t, 1 );
|
||||
p->nCap = 2*nObjs;
|
||||
p->nSize = 2*nObjs;
|
||||
p->nRegs = nLatches;
|
||||
p->pArray = pObjs;
|
||||
if ( fVerbose )
|
||||
printf( "Loaded MiniAIG from the AIGER file \"%s\".\n", pFileName );
|
||||
return p;
|
||||
}
|
||||
|
||||
static void Mini_AigerWriteInt( char * pFileName, int * pObjs, int nObjs, int nIns, int nLatches, int nOuts, int nAnds )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" ); int i;
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
fprintf( stdout, "Mini_AigerWrite(): Cannot open the output file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
fprintf( pFile, "aig %d %d %d %d %d\n", nIns + nLatches + nAnds, nIns, nLatches, nOuts, nAnds );
|
||||
for ( i = 0; i < nLatches; i++ )
|
||||
fprintf( pFile, "%d\n", pObjs[2*(nObjs-nLatches+i)+0] );
|
||||
for ( i = 0; i < nOuts; i++ )
|
||||
fprintf( pFile, "%d\n", pObjs[2*(nObjs-nOuts-nLatches+i)+0] );
|
||||
for ( i = 0; i < nAnds; i++ )
|
||||
{
|
||||
int uLit = 2*(1+nIns+nLatches+i);
|
||||
int uLit0 = pObjs[uLit+0];
|
||||
int uLit1 = pObjs[uLit+1];
|
||||
Mini_AigerWriteUnsigned( pFile, uLit - uLit1 );
|
||||
Mini_AigerWriteUnsigned( pFile, uLit1 - uLit0 );
|
||||
}
|
||||
fprintf( pFile, "c\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
static void Mini_AigerWrite( char * pFileName, Mini_Aig_t * p, int fVerbose )
|
||||
{
|
||||
int i, nIns = 0, nOuts = 0, nAnds = 0;
|
||||
assert( Mini_AigIsNormalized(p) );
|
||||
for ( i = 1; i < Mini_AigNodeNum(p); i++ )
|
||||
{
|
||||
if ( Mini_AigNodeIsPi(p, i) )
|
||||
nIns++;
|
||||
else if ( Mini_AigNodeIsPo(p, i) )
|
||||
nOuts++;
|
||||
else
|
||||
nAnds++;
|
||||
}
|
||||
Mini_AigerWriteInt( pFileName, p->pArray, p->nSize/2, nIns - p->nRegs, p->nRegs, nOuts - p->nRegs, nAnds );
|
||||
if ( fVerbose )
|
||||
printf( "Written MiniAIG into the AIGER file \"%s\".\n", pFileName );
|
||||
}
|
||||
static void Mini_AigerTest( char * pFileNameIn, char * pFileNameOut )
|
||||
{
|
||||
Mini_Aig_t * p = Mini_AigerRead( pFileNameIn, 1 );
|
||||
if ( p == NULL )
|
||||
return;
|
||||
printf( "Finished reading input file \"%s\".\n", pFileNameIn );
|
||||
Mini_AigerWrite( pFileNameOut, p, 1 );
|
||||
printf( "Finished writing output file \"%s\".\n", pFileNameOut );
|
||||
Mini_AigStop( p );
|
||||
}
|
||||
|
||||
/*
|
||||
int main( int argc, char ** argv )
|
||||
{
|
||||
if ( argc != 3 )
|
||||
return 0;
|
||||
Mini_AigerTest( argv[1], argv[2] );
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
#include "aig/miniaig/miniaig.h"
|
||||
|
||||
// this procedure creates a MiniAIG for function F = a*b + ~c and writes it into a file "test.aig"
|
||||
void Mini_AigTest()
|
||||
{
|
||||
Mini_Aig_t * p = Mini_AigStart(); // create empty AIG manager (contains only const0 node)
|
||||
int litApos = Mini_AigCreatePi( p ); // create input A (returns pos lit of A)
|
||||
int litBpos = Mini_AigCreatePi( p ); // create input B (returns pos lit of B)
|
||||
int litCpos = Mini_AigCreatePi( p ); // create input C (returns pos lit of C)
|
||||
int litCneg = Mini_AigLitNot( litCpos ); // neg lit of C
|
||||
int litAnd = Mini_AigAnd( p, litApos, litBpos ); // lit for a*b
|
||||
int litOr = Mini_AigOr( p, litAnd, litCneg ); // lit for a*b + ~c
|
||||
Mini_AigCreatePo( p, litOr ); // create primary output
|
||||
Mini_AigerWrite( "test.aig", p, 1 ); // write the result into a file
|
||||
Mini_AigStop( p ); // deallocate MiniAIG
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _VERIFIC_DATABASE_H_
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
|||
|
|
@ -219,7 +219,8 @@ static inline void Ndr_DataPushString( Ndr_Data_t * p, int ObjType, int Type, ch
|
|||
{
|
||||
//word Truth = (word)pFunc;
|
||||
//Ndr_DataPushArray( p, Type, 2, (int *)&Truth );
|
||||
Ndr_DataPushArray( p, Type, 2, (int *)&pFunc );
|
||||
int nInts = (strlen(pFunc) + 1 + sizeof(int) - 1) / sizeof(int);
|
||||
Ndr_DataPushArray( p, Type, nInts, (int *)&pFunc );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -506,7 +507,7 @@ static inline void Ndr_WriteVerilogModule( FILE * pFile, void * pDesign, int Mod
|
|||
else if ( nArray == 3 && Type == ABC_OPER_ARI_ADD )
|
||||
fprintf( pFile, "%s + %s + %s;\n", pNames[pArray[0]], pNames[pArray[1]], pNames[pArray[2]] );
|
||||
else if ( Type == ABC_OPER_BIT_MUX )
|
||||
fprintf( pFile, "%s ? %s : %s;\n", pNames[pArray[0]], pNames[pArray[1]], pNames[pArray[2]] );
|
||||
fprintf( pFile, "%s ? %s : %s;\n", pNames[pArray[0]], pNames[pArray[2]], pNames[pArray[1]] );
|
||||
else
|
||||
fprintf( pFile, "<cannot write operation %s>;\n", Abc_OperName(Ndr_ObjReadBody(p, Obj, NDR_OPERTYPE)) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ extern Aig_Man_t * Saig_ManDupFoldConstrs( Aig_Man_t * pAig, Vec_Int_t * v
|
|||
extern int Saig_ManDetectConstrTest( Aig_Man_t * p );
|
||||
extern void Saig_ManDetectConstrFuncTest( Aig_Man_t * p, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose );
|
||||
/*=== saigConstr2.c ==========================================================*/
|
||||
extern Aig_Man_t * Saig_ManDupFoldConstrsFunc( Aig_Man_t * pAig, int fCompl, int fVerbose );
|
||||
extern Aig_Man_t * Saig_ManDupFoldConstrsFunc( Aig_Man_t * pAig, int fCompl, int fVerbose, int fSeqCleanup );
|
||||
extern Aig_Man_t * Saig_ManDupUnfoldConstrsFunc( Aig_Man_t * pAig, int nFrames, int nConfs, int nProps, int fOldAlgo, int fVerbose );
|
||||
// -- jlong -- begin
|
||||
extern Aig_Man_t * Saig_ManDupFoldConstrsFunc2( Aig_Man_t * pAig, int fCompl, int fVerbose, int typeII_cnt );
|
||||
|
|
|
|||
|
|
@ -939,7 +939,7 @@ Aig_Man_t * Saig_ManDupUnfoldConstrsFunc( Aig_Man_t * pAig, int nFrames, int nCo
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Saig_ManDupFoldConstrsFunc( Aig_Man_t * pAig, int fCompl, int fVerbose )
|
||||
Aig_Man_t * Saig_ManDupFoldConstrsFunc( Aig_Man_t * pAig, int fCompl, int fVerbose, int fSeqCleanup )
|
||||
{
|
||||
Aig_Man_t * pAigNew;
|
||||
Aig_Obj_t * pMiter, * pFlopOut, * pFlopIn, * pObj;
|
||||
|
|
@ -1000,7 +1000,8 @@ Aig_Man_t * Saig_ManDupFoldConstrsFunc( Aig_Man_t * pAig, int fCompl, int fVerbo
|
|||
|
||||
// perform cleanup
|
||||
Aig_ManCleanup( pAigNew );
|
||||
Aig_ManSeqCleanup( pAigNew );
|
||||
if ( fSeqCleanup )
|
||||
Aig_ManSeqCleanup( pAigNew );
|
||||
return pAigNew;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,17 +45,17 @@ ABC_NAMESPACE_IMPL_START
|
|||
***********************************************************************/
|
||||
char * Saig_ObjName( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
static char Buffer[16];
|
||||
static char Buffer[1000];
|
||||
if ( Aig_ObjIsNode(pObj) || Aig_ObjIsConst1(pObj) )
|
||||
sprintf( Buffer, "n%0*d", Abc_Base10Log(Aig_ManObjNumMax(p)), Aig_ObjId(pObj) );
|
||||
sprintf( Buffer, "n%0*d", (unsigned char)Abc_Base10Log(Aig_ManObjNumMax(p)), Aig_ObjId(pObj) );
|
||||
else if ( Saig_ObjIsPi(p, pObj) )
|
||||
sprintf( Buffer, "pi%0*d", Abc_Base10Log(Saig_ManPiNum(p)), Aig_ObjCioId(pObj) );
|
||||
sprintf( Buffer, "pi%0*d", (unsigned char)Abc_Base10Log(Saig_ManPiNum(p)), Aig_ObjCioId(pObj) );
|
||||
else if ( Saig_ObjIsPo(p, pObj) )
|
||||
sprintf( Buffer, "po%0*d", Abc_Base10Log(Saig_ManPoNum(p)), Aig_ObjCioId(pObj) );
|
||||
sprintf( Buffer, "po%0*d", (unsigned char)Abc_Base10Log(Saig_ManPoNum(p)), Aig_ObjCioId(pObj) );
|
||||
else if ( Saig_ObjIsLo(p, pObj) )
|
||||
sprintf( Buffer, "lo%0*d", Abc_Base10Log(Saig_ManRegNum(p)), Aig_ObjCioId(pObj) - Saig_ManPiNum(p) );
|
||||
sprintf( Buffer, "lo%0*d", (unsigned char)Abc_Base10Log(Saig_ManRegNum(p)), Aig_ObjCioId(pObj) - Saig_ManPiNum(p) );
|
||||
else if ( Saig_ObjIsLi(p, pObj) )
|
||||
sprintf( Buffer, "li%0*d", Abc_Base10Log(Saig_ManRegNum(p)), Aig_ObjCioId(pObj) - Saig_ManPoNum(p) );
|
||||
sprintf( Buffer, "li%0*d", (unsigned char)Abc_Base10Log(Saig_ManRegNum(p)), Aig_ObjCioId(pObj) - Saig_ManPoNum(p) );
|
||||
else
|
||||
assert( 0 );
|
||||
return Buffer;
|
||||
|
|
|
|||
|
|
@ -493,7 +493,7 @@ Aig_Man_t * Iso_ManFilterPos( Aig_Man_t * pAig, Vec_Ptr_t ** pvPosEquivs, int fV
|
|||
|
||||
// report the results
|
||||
// Vec_VecPrintInt( (Vec_Vec_t *)vClasses );
|
||||
// printf( "Devided %d outputs into %d cand equiv classes.\n", Saig_ManPoNum(pAig), Vec_PtrSize(vClasses) );
|
||||
// printf( "Divided %d outputs into %d cand equiv classes.\n", Saig_ManPoNum(pAig), Vec_PtrSize(vClasses) );
|
||||
/*
|
||||
if ( fVerbose )
|
||||
{
|
||||
|
|
@ -600,7 +600,7 @@ Aig_Man_t * Iso_ManTest888( Aig_Man_t * pAig1, int fVerbose )
|
|||
Vec_Int_t * vMap;
|
||||
|
||||
pNtk = Abc_NtkFromAigPhase( pAig1 );
|
||||
Abc_NtkPermute( pNtk, 1, 0, 1, NULL );
|
||||
Abc_NtkPermute( pNtk, 1, 0, 1, NULL, NULL, NULL );
|
||||
pAig2 = Abc_NtkToDar( pNtk, 0, 1 );
|
||||
Abc_NtkDelete( pNtk );
|
||||
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ Vec_Vec_t * Saig_IsoDetectFast( Aig_Man_t * pAig )
|
|||
|
||||
// report the results
|
||||
// Vec_VecPrintInt( (Vec_Vec_t *)vClasses );
|
||||
printf( "Devided %d outputs into %d cand equiv classes.\n", Saig_ManPoNum(pAig), Vec_PtrSize(vClasses) );
|
||||
printf( "Divided %d outputs into %d cand equiv classes.\n", Saig_ManPoNum(pAig), Vec_PtrSize(vClasses) );
|
||||
|
||||
Vec_PtrForEachEntry( Vec_Int_t *, vClasses, vLevel, i )
|
||||
if ( Vec_IntSize(vLevel) > 1 )
|
||||
|
|
|
|||
|
|
@ -946,7 +946,7 @@ int Saig_ManDemiter( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 )
|
|||
|
||||
if ( (pFlop0->fMarkA && pFlop0->fMarkB) || (pFlop1->fMarkA && pFlop1->fMarkB) ||
|
||||
(pFlop0->fMarkA && pFlop1->fMarkA) || (pFlop0->fMarkB && pFlop1->fMarkB) )
|
||||
printf( "Ouput pair %4d: Difficult case...\n", i/2 );
|
||||
printf( "Output pair %4d: Difficult case...\n", i/2 );
|
||||
|
||||
if ( pFlop0->fMarkB )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -903,14 +903,14 @@ ABC_PRT( "Constructing the problem", Abc_Clock() - clk );
|
|||
if ( f == nFramesSatur )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "Begining to saturate simulation after %d frames\n", f );
|
||||
printf( "Beginning to saturate simulation after %d frames\n", f );
|
||||
// find all flops that have at least one X value in the past and set them to X forever
|
||||
p->vXFlops = Saig_MvManFindXFlops( p );
|
||||
}
|
||||
if ( f == 2 * nFramesSatur )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "Agressively saturating simulation after %d frames\n", f );
|
||||
printf( "Aggressively saturating simulation after %d frames\n", f );
|
||||
Vec_IntFree( p->vXFlops );
|
||||
p->vXFlops = Saig_MvManCreateNextSkip( p );
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue