mirror of https://github.com/YosysHQ/abc.git
Compare commits
1632 Commits
yosys-0.10
...
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 | |
|
|
f6fa2ddcfc | |
|
|
e792072f8a | |
|
|
e289a8059e | |
|
|
d2d6bbd9f8 | |
|
|
9b245d9f69 | |
|
|
079a309a0d | |
|
|
621d6355f4 | |
|
|
5e4a78470b | |
|
|
18b4e8beef | |
|
|
a80a91e45f | |
|
|
d13e33cdd8 | |
|
|
348c74e0a6 | |
|
|
dbc5f8a3b6 | |
|
|
456e381a02 | |
|
|
d4f073bad7 | |
|
|
abc54a2d20 | |
|
|
f0236d5ac1 | |
|
|
d514029e34 | |
|
|
1afd156dbd | |
|
|
e56a767640 | |
|
|
227b0c775b | |
|
|
31f88974e2 | |
|
|
eb44a80bf2 | |
|
|
e76b7ba0cc | |
|
|
674bcbee37 | |
|
|
a8b5da820d | |
|
|
ba64e78608 | |
|
|
2ce1ce8bed | |
|
|
787dbb9433 | |
|
|
baf2a6508d | |
|
|
cc13d1fb47 | |
|
|
627c7d33fd | |
|
|
1e69e7e7d1 | |
|
|
a363256098 | |
|
|
e2f1548217 | |
|
|
6ca31c475f | |
|
|
997e1a2ddc | |
|
|
ecda331a2a | |
|
|
c557272241 | |
|
|
2f993e583d | |
|
|
d3d5644005 | |
|
|
bafd2a7820 | |
|
|
9d89faa82b | |
|
|
14dc389e62 | |
|
|
e7a029d73f | |
|
|
ed9c16d4f5 | |
|
|
a718318740 | |
|
|
388255e557 | |
|
|
85a94766a6 | |
|
|
67c47fa44a | |
|
|
625ccde611 | |
|
|
3b4a4481a1 | |
|
|
0fc13478b8 | |
|
|
77760dd8ac | |
|
|
b82a7f4677 | |
|
|
d55e8fab82 | |
|
|
ca710b3dda | |
|
|
4da6cc8904 | |
|
|
e9b487666d | |
|
|
0deb8bf632 | |
|
|
e8ac47641f | |
|
|
c312e41601 | |
|
|
99ab99bfa6 | |
|
|
ddc574a954 | |
|
|
ab29dad7f4 | |
|
|
ae98e57caf | |
|
|
dd87461ac9 | |
|
|
5f8d4e72d1 | |
|
|
03bb1e49bf | |
|
|
4cf906d2fc | |
|
|
e162a26197 | |
|
|
692dd76319 | |
|
|
d925e4802c | |
|
|
a162b1f47a | |
|
|
62180f3576 | |
|
|
6e5a797a6d | |
|
|
d9aeaade3b | |
|
|
3e67d167f5 | |
|
|
be14c39740 | |
|
|
9fac6c7a8b | |
|
|
fdc9e89d66 | |
|
|
4116e13b5e | |
|
|
96b9192c78 | |
|
|
5a135c8799 | |
|
|
4c90af0f10 | |
|
|
28ba2c5213 | |
|
|
b4f099c511 | |
|
|
db3f5b6d0b | |
|
|
7d18d6b7aa | |
|
|
84ec53fbf9 | |
|
|
7fcbffd2af | |
|
|
8889ccb18c | |
|
|
49078ffebf | |
|
|
d35b05859c | |
|
|
91a2eafc7a | |
|
|
93849685b3 | |
|
|
0ce11851bc | |
|
|
610a3d3fc2 | |
|
|
ed13c6d4d2 | |
|
|
e6a47c3e41 | |
|
|
aa9fe1f240 | |
|
|
76bed2055c | |
|
|
17476146ca | |
|
|
45acbef882 | |
|
|
13a0bb97b5 | |
|
|
174f27d981 | |
|
|
7d90895dcf | |
|
|
645752f7d6 | |
|
|
9b75906740 | |
|
|
5f8a8a596a | |
|
|
de71e5f610 | |
|
|
75981f7fee | |
|
|
796c29039a | |
|
|
9145a5c20d | |
|
|
18088bd7dc | |
|
|
35a4ce557c | |
|
|
6a03ece98d | |
|
|
66098723eb | |
|
|
b2ca837521 | |
|
|
f87c8b434a | |
|
|
e463930709 | |
|
|
cd8843c06c | |
|
|
bf96f0b31d | |
|
|
d0efef2fe9 | |
|
|
e44f409c1d | |
|
|
f06217e25a | |
|
|
73dcdab6d8 | |
|
|
8066fdbcb5 | |
|
|
06094ade87 | |
|
|
901560bb23 | |
|
|
5b8e56b2e5 | |
|
|
206527045e | |
|
|
925418d562 | |
|
|
6eee09c51c | |
|
|
fa87d16b97 | |
|
|
d4fb192575 | |
|
|
22f36299aa | |
|
|
2e92256fb7 | |
|
|
4757c7febc | |
|
|
0e5af861e0 | |
|
|
48f71adacd | |
|
|
c3699a2043 | |
|
|
36817328a5 | |
|
|
230b759d16 | |
|
|
d350b1a82f | |
|
|
ecafca53d8 | |
|
|
b28c4b5c17 | |
|
|
dd07ec57be | |
|
|
28ea3adedb | |
|
|
36e8567e77 | |
|
|
4c78f37a5a | |
|
|
581f2e5972 | |
|
|
f95476b45d | |
|
|
fef0c368bc | |
|
|
bab4c1ddfc | |
|
|
cc840d8bd8 | |
|
|
22388f901a | |
|
|
38d72c4343 | |
|
|
2f65566d43 | |
|
|
5415fe521f | |
|
|
fd41920a10 | |
|
|
b3d3f7dd3a | |
|
|
890aa684ab | |
|
|
83519c320c | |
|
|
c0bb4bb047 | |
|
|
3da87edbb4 | |
|
|
40bfe2fb88 | |
|
|
0b89fd387e | |
|
|
6e6cc08bec | |
|
|
ce95366e51 | |
|
|
3a7b3d27f1 | |
|
|
2325cd77e3 | |
|
|
f9af41ba1b | |
|
|
73f8b598ac | |
|
|
b2aa245eaa | |
|
|
ada073110e | |
|
|
f1eb933992 | |
|
|
947eeb9501 | |
|
|
41c937e4c8 | |
|
|
f21bafeb23 | |
|
|
55a67a115c | |
|
|
d953425275 | |
|
|
55f4751f75 | |
|
|
63fc01ccbd | |
|
|
083c1218e5 | |
|
|
fb769cf9ab | |
|
|
bab462d5cd | |
|
|
07bf95f480 | |
|
|
a2c3c21031 | |
|
|
d556ad65ff | |
|
|
fe968e9d79 | |
|
|
8ef4404542 | |
|
|
4b4646283f | |
|
|
26e03ef6a0 | |
|
|
850d39fec3 | |
|
|
b74b7dfc2d | |
|
|
5c8ee4a2c1 | |
|
|
aaeadb1438 | |
|
|
448f263443 | |
|
|
25538c23c5 | |
|
|
22d9b1d38b | |
|
|
ba063a1b55 | |
|
|
2ba092e4cc | |
|
|
0b734d10e0 | |
|
|
83f54185ef | |
|
|
322cea8234 | |
|
|
58e3a5caff | |
|
|
a3c6f33a87 | |
|
|
491e4ebfd1 | |
|
|
97c826a6e6 | |
|
|
0ae0744e73 | |
|
|
a8bd59bd68 | |
|
|
9bfccf76c1 | |
|
|
1c0ea1022f | |
|
|
a3ada00d86 | |
|
|
a7871d24cd | |
|
|
a918e2dab1 | |
|
|
372eb7bdef | |
|
|
f8b6d615bf | |
|
|
234b5d771b | |
|
|
f543d39ec8 | |
|
|
f026e65339 | |
|
|
e149cdcd77 | |
|
|
2b58a83ac0 | |
|
|
559f8f5b5e | |
|
|
3e150dd553 | |
|
|
d51f798956 |
|
|
@ -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/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
|
||||
|
|
|
|||
1593
abclib.dsp
1593
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++ )
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -297,6 +298,101 @@ void Gia_ManStructExperiment( Gia_Man_t * p )
|
|||
Vec_PtrFree( vGias );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_EnumFirstUnused( int * pUsed, int nVars )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
if ( pUsed[i] == 0 )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
void Gia_EnumPerms_rec( int * pUsed, int nVars, int * pPerm, int nPerm, int * pCount, FILE * pFile, int nLogVars )
|
||||
{
|
||||
int i, k, New;
|
||||
if ( nPerm == nVars )
|
||||
{
|
||||
if ( pFile )
|
||||
{
|
||||
for ( i = 0; i < nLogVars; i++ )
|
||||
fprintf( pFile, "%c", '0' + ((*pCount) >> (nLogVars-1-i) & 1) );
|
||||
fprintf( pFile, " " );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
for ( k = 0; k < nVars; k++ )
|
||||
fprintf( pFile, "%c", '0' + (pPerm[i] == k) );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( *pCount < 20 )
|
||||
{
|
||||
printf( "%5d : ", (*pCount) );
|
||||
for ( i = 0; i < nVars; i += 2 )
|
||||
printf( "%d %d ", pPerm[i], pPerm[i+1] );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
(*pCount)++;
|
||||
return;
|
||||
}
|
||||
New = Gia_EnumFirstUnused( pUsed, nVars );
|
||||
assert( New >= 0 );
|
||||
pPerm[nPerm] = New;
|
||||
assert( pUsed[New] == 0 );
|
||||
pUsed[New] = 1;
|
||||
// try remaining ones
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
{
|
||||
if ( pUsed[i] == 1 )
|
||||
continue;
|
||||
pPerm[nPerm+1] = i;
|
||||
assert( pUsed[i] == 0 );
|
||||
pUsed[i] = 1;
|
||||
Gia_EnumPerms_rec( pUsed, nVars, pPerm, nPerm+2, pCount, pFile, nLogVars );
|
||||
assert( pUsed[i] == 1 );
|
||||
pUsed[i] = 0;
|
||||
}
|
||||
assert( pUsed[New] == 1 );
|
||||
pUsed[New] = 0;
|
||||
}
|
||||
void Gia_EnumPerms( int nVars )
|
||||
{
|
||||
int nLogVars = 0, Count = 0;
|
||||
int * pUsed = ABC_CALLOC( int, nVars );
|
||||
int * pPerm = ABC_CALLOC( int, nVars );
|
||||
FILE * pFile = fopen( "pairset.pla", "wb" );
|
||||
assert( nVars % 2 == 0 );
|
||||
|
||||
printf( "Printing sets of pairs for %d objects:\n", nVars );
|
||||
Gia_EnumPerms_rec( pUsed, nVars, pPerm, 0, &Count, NULL, -1 );
|
||||
if ( Count > 20 )
|
||||
printf( "...\n" );
|
||||
printf( "Finished enumerating %d sets of pairs.\n", Count );
|
||||
|
||||
nLogVars = Abc_Base2Log( Count );
|
||||
printf( "Need %d variables to encode %d sets.\n", nLogVars, Count );
|
||||
Count = 0;
|
||||
fprintf( pFile, ".i %d\n", nLogVars );
|
||||
fprintf( pFile, ".o %d\n", nVars*nVars );
|
||||
Gia_EnumPerms_rec( pUsed, nVars, pPerm, 0, &Count, pFile, nLogVars );
|
||||
fprintf( pFile, ".e\n" );
|
||||
fclose( pFile );
|
||||
printf( "Finished dumping file \"%s\".\n", "pairset.pla" );
|
||||
|
||||
ABC_FREE( pUsed );
|
||||
ABC_FREE( pPerm );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -171,6 +172,7 @@ struct Gia_Man_t_
|
|||
Vec_Int_t * vCoReqs; // CO required times
|
||||
Vec_Int_t * vCoArrs; // CO arrival times
|
||||
Vec_Int_t * vCoAttrs; // CO attributes
|
||||
Vec_Int_t * vWeights; // object attributes
|
||||
int And2Delay; // delay of the AND gate
|
||||
float DefInArrs; // default PI arrival times
|
||||
float DefOutReqs; // default PO required times
|
||||
|
|
@ -179,6 +181,7 @@ struct Gia_Man_t_
|
|||
int nTravIdsAlloc; // the number of trav IDs allocated
|
||||
Vec_Ptr_t * vNamesIn; // the input names
|
||||
Vec_Ptr_t * vNamesOut; // the output names
|
||||
Vec_Ptr_t * vNamesNode; // the node names
|
||||
Vec_Int_t * vUserPiIds; // numbers assigned to PIs by the user
|
||||
Vec_Int_t * vUserPoIds; // numbers assigned to POs by the user
|
||||
Vec_Int_t * vUserFfIds; // numbers assigned to FFs by the user
|
||||
|
|
@ -186,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
|
||||
|
|
@ -214,6 +219,8 @@ struct Gia_Man_t_
|
|||
Vec_Wrd_t * vSimsPo;
|
||||
Vec_Int_t * vClassOld;
|
||||
Vec_Int_t * vClassNew;
|
||||
Vec_Int_t * vPats;
|
||||
Vec_Bit_t * vPolars;
|
||||
// incremental simulation
|
||||
int fIncrSim;
|
||||
int iNextPi;
|
||||
|
|
@ -235,7 +242,21 @@ struct Gia_Man_t_
|
|||
Vec_Wrd_t * vSuppWords; // support information
|
||||
Vec_Int_t vCopiesTwo; // intermediate copies
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -252,6 +273,7 @@ struct Gps_Par_t_
|
|||
int fSkipMap;
|
||||
int fSlacks;
|
||||
int fNoColor;
|
||||
int fMapOutStats;
|
||||
char * pDumpFile;
|
||||
};
|
||||
|
||||
|
|
@ -339,6 +361,7 @@ struct Jf_Par_t_
|
|||
int fCutMin;
|
||||
int fFuncDsd;
|
||||
int fGenCnf;
|
||||
int fGenLit;
|
||||
int fCnfObjIds;
|
||||
int fAddOrCla;
|
||||
int fCnfMapping;
|
||||
|
|
@ -353,6 +376,7 @@ struct Jf_Par_t_
|
|||
int nCutNumMax;
|
||||
int nProcNumMax;
|
||||
int nLutSizeMux;
|
||||
int nMaxMatches;
|
||||
word Delay;
|
||||
word Area;
|
||||
word Edge;
|
||||
|
|
@ -368,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)); }
|
||||
|
|
@ -477,6 +502,11 @@ static inline int Gia_ObjValue( Gia_Obj_t * pObj ) {
|
|||
static inline void Gia_ObjSetValue( Gia_Obj_t * pObj, int i ) { pObj->Value = i; }
|
||||
static inline int Gia_ObjPhase( Gia_Obj_t * pObj ) { return pObj->fPhase; }
|
||||
static inline int Gia_ObjPhaseReal( Gia_Obj_t * pObj ) { return Gia_Regular(pObj)->fPhase ^ Gia_IsComplement(pObj); }
|
||||
static inline int Gia_ObjPhaseDiff( Gia_Man_t * p, int i, int k ) { return Gia_ManObj(p, i)->fPhase ^ Gia_ManObj(p, k)->fPhase; }
|
||||
static inline char * Gia_ObjCiName( Gia_Man_t * p, int i ) { return p->vNamesIn ? (char*)Vec_PtrEntry(p->vNamesIn, i) : NULL; }
|
||||
static inline char * Gia_ObjCoName( Gia_Man_t * p, int i ) { return p->vNamesOut ? (char*)Vec_PtrEntry(p->vNamesOut, i) : NULL; }
|
||||
static inline char * Gia_ObjName( Gia_Man_t * p, int i ) { return p->vNamesNode ? (char*)Vec_PtrEntry(p->vNamesNode, i) : NULL; }
|
||||
static inline char * Gia_ObjNameObj( Gia_Man_t * p, Gia_Obj_t * pObj ) { return p->vNamesNode ? (char*)Vec_PtrEntry(p->vNamesNode, Gia_ObjId(p, pObj)) : NULL; }
|
||||
|
||||
static inline int Gia_ObjIsTerm( Gia_Obj_t * pObj ) { return pObj->fTerm; }
|
||||
static inline int Gia_ObjIsAndOrConst0( Gia_Obj_t * pObj ) { return!pObj->fTerm; }
|
||||
|
|
@ -516,28 +546,35 @@ 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; }
|
||||
|
||||
static inline int Gia_ManCoDriverId( Gia_Man_t * p, int iCoIndex ) { return Gia_ObjFaninId0p(p, Gia_ManCo(p, iCoIndex)); }
|
||||
static inline int Gia_ManPoIsConst( Gia_Man_t * p, int iPoIndex ) { return Gia_ObjFaninId0p(p, Gia_ManPo(p, iPoIndex)) == 0; }
|
||||
static inline int Gia_ManPoIsConst0( Gia_Man_t * p, int iPoIndex ) { return Gia_ManIsConst0Lit( Gia_ObjFaninLit0p(p, Gia_ManPo(p, iPoIndex)) ); }
|
||||
static inline int Gia_ManPoIsConst1( Gia_Man_t * p, int iPoIndex ) { return Gia_ManIsConst1Lit( Gia_ObjFaninLit0p(p, Gia_ManPo(p, iPoIndex)) ); }
|
||||
|
|
@ -570,6 +607,7 @@ static inline int Gia_ObjPhaseRealLit( Gia_Man_t * p, int iLit ) {
|
|||
|
||||
static inline int Gia_ObjLevelId( Gia_Man_t * p, int Id ) { return Vec_IntGetEntry(p->vLevels, Id); }
|
||||
static inline int Gia_ObjLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjLevelId( p, Gia_ObjId(p,pObj) ); }
|
||||
static inline void Gia_ObjUpdateLevelId( Gia_Man_t * p, int Id, int l ) { Vec_IntSetEntry(p->vLevels, Id, Abc_MaxInt(Vec_IntEntry(p->vLevels, Id), l)); }
|
||||
static inline void Gia_ObjSetLevelId( Gia_Man_t * p, int Id, int l ) { Vec_IntSetEntry(p->vLevels, Id, l); }
|
||||
static inline void Gia_ObjSetLevel( Gia_Man_t * p, Gia_Obj_t * pObj, int l ) { Gia_ObjSetLevelId( p, Gia_ObjId(p,pObj), l ); }
|
||||
static inline void Gia_ObjSetCoLevel( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); Gia_ObjSetLevel( p, pObj, Gia_ObjLevel(p,Gia_ObjFanin0(pObj)) ); }
|
||||
|
|
@ -610,10 +648,14 @@ static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * p
|
|||
static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; }
|
||||
static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); }
|
||||
static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); }
|
||||
static inline int Gia_ObjUpdateTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return 1; Gia_ObjSetTravIdCurrent(p, pObj); return 0; }
|
||||
static inline int Gia_ObjUpdateTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdPrevious(p, pObj) ) return 1; Gia_ObjSetTravIdPrevious(p, pObj); return 0; }
|
||||
static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; }
|
||||
static inline void Gia_ObjSetTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds - 1; }
|
||||
static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); }
|
||||
static inline int Gia_ObjIsTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds - 1); }
|
||||
static inline int Gia_ObjUpdateTravIdCurrentId( Gia_Man_t * p, int Id ) { if ( Gia_ObjIsTravIdCurrentId(p, Id) ) return 1; Gia_ObjSetTravIdCurrentId(p, Id); return 0; }
|
||||
static inline int Gia_ObjUpdateTravIdPreviousId( Gia_Man_t * p, int Id ) { if ( Gia_ObjIsTravIdPreviousId(p, Id) ) return 1; Gia_ObjSetTravIdPreviousId(p, Id); return 0; }
|
||||
|
||||
static inline void Gia_ManTimeClean( Gia_Man_t * p ) { int i; assert( p->vTiming != NULL ); Vec_FltFill(p->vTiming, 3*Gia_ManObjNum(p), 0); for ( i = 0; i < Gia_ManObjNum(p); i++ ) Vec_FltWriteEntry( p->vTiming, 3*i+1, (float)(ABC_INFINITY) ); }
|
||||
static inline void Gia_ManTimeStart( Gia_Man_t * p ) { assert( p->vTiming == NULL ); p->vTiming = Vec_FltAlloc(0); Gia_ManTimeClean( p ); }
|
||||
|
|
@ -1067,9 +1109,11 @@ static inline void Gia_ClassUndoPair( Gia_Man_t * p, int i ) { a
|
|||
#define Gia_ManForEachClassReverse( p, i ) \
|
||||
for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else
|
||||
#define Gia_ClassForEachObj( p, i, iObj ) \
|
||||
for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) )
|
||||
for ( assert(Gia_ObjIsHead(p, i) && i), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) )
|
||||
#define Gia_ClassForEachObj1( p, i, iObj ) \
|
||||
for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj > 0; iObj = Gia_ObjNext(p, iObj) )
|
||||
#define Gia_ClassForEachObjStart( p, i, iObj, Start ) \
|
||||
for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, Start); iObj > 0; iObj = Gia_ObjNext(p, iObj) )
|
||||
|
||||
|
||||
static inline int Gia_ObjFoffsetId( Gia_Man_t * p, int Id ) { return Vec_IntEntry( p->vFanout, Id ); }
|
||||
|
|
@ -1082,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; }
|
||||
|
|
@ -1118,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++ )
|
||||
|
||||
|
|
@ -1149,7 +1197,13 @@ static inline int Gia_ObjCellId( Gia_Man_t * p, int iLit ) { re
|
|||
for ( i = 1; (i < p->nObjs) && ((pObj) = Gia_ManObj(p, i)); i++ )
|
||||
#define Gia_ManForEachObjVec( vVec, p, pObj, i ) \
|
||||
for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
|
||||
#define Gia_ManForEachObjVecReverse( vVec, p, pObj, i ) \
|
||||
#define Gia_ManForEachObjVecStart( vVec, p, pObj, i, Start ) \
|
||||
for ( i = Start; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
|
||||
#define Gia_ManForEachObjVecStop( vVec, p, pObj, i, Stop ) \
|
||||
for ( i = 0; (i < Stop) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
|
||||
#define Gia_ManForEachObjVecStartStop( vVec, p, pObj, i, Start, Stop ) \
|
||||
for ( i = Start; (i < Stop) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
|
||||
#define Gia_ManForEachObjVecReverse( vVec, p, pObj, i ) \
|
||||
for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && ((pObj) = Gia_ManObj(p, Vec_IntEntry(vVec,i))); i-- )
|
||||
#define Gia_ManForEachObjVecLit( vVec, p, pObj, fCompl, i ) \
|
||||
for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Gia_ManObj(p, Abc_Lit2Var(Vec_IntEntry(vVec,i)))) && (((fCompl) = Abc_LitIsCompl(Vec_IntEntry(vVec,i))),1); i++ )
|
||||
|
|
@ -1205,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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1215,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 );
|
||||
|
|
@ -1245,16 +1311,25 @@ extern Cbs_Man_t * Cbs_ManAlloc( Gia_Man_t * pGia );
|
|||
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 fVerbose );
|
||||
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 );
|
||||
extern Gia_Man_t * Gia_ManDupCofAllInt( Gia_Man_t * p, Vec_Int_t * vSigs, int fVerbose );
|
||||
extern Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose );
|
||||
/*=== giaDecs.c ============================================================*/
|
||||
extern int Gia_ResubVarNum( Vec_Int_t * vResub );
|
||||
extern word Gia_ResubToTruth6( Vec_Int_t * vResub );
|
||||
extern int Gia_ManEvalSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int fVerbose );
|
||||
extern Vec_Int_t * Gia_ManDeriveSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int Type );
|
||||
/*=== giaDfs.c ============================================================*/
|
||||
extern void Gia_ManCollectCis( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vSupp );
|
||||
extern void Gia_ManCollectAnds_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vNodes );
|
||||
|
|
@ -1264,6 +1339,7 @@ extern Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes,
|
|||
extern int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes );
|
||||
extern int Gia_ManConeSize( Gia_Man_t * p, int * pNodes, int nNodes );
|
||||
extern Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p );
|
||||
extern Vec_Wec_t * Gia_ManLevelizeR( Gia_Man_t * p );
|
||||
extern Vec_Int_t * Gia_ManOrderReverse( Gia_Man_t * p );
|
||||
extern void Gia_ManCollectTfi( Gia_Man_t * p, Vec_Int_t * vRoots, Vec_Int_t * vNodes );
|
||||
extern void Gia_ManCollectTfo( Gia_Man_t * p, Vec_Int_t * vRoots, Vec_Int_t * vNodes );
|
||||
|
|
@ -1272,7 +1348,7 @@ extern void Gia_ManDupRemapLiterals( Vec_Int_t * vLits, Gia_Man_t
|
|||
extern void Gia_ManDupRemapEquiv( Gia_Man_t * pNew, Gia_Man_t * p );
|
||||
extern Gia_Man_t * Gia_ManDupOrderDfs( Gia_Man_t * p );
|
||||
extern Gia_Man_t * Gia_ManDupOrderDfsChoices( Gia_Man_t * p );
|
||||
extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p );
|
||||
extern Gia_Man_t * Gia_ManDupOrderDfsReverse( Gia_Man_t * p, int fRevFans, int fRevOuts );
|
||||
extern Gia_Man_t * Gia_ManDupOutputGroup( Gia_Man_t * p, int iOutStart, int iOutStop );
|
||||
extern Gia_Man_t * Gia_ManDupOutputVec( Gia_Man_t * p, Vec_Int_t * vOutPres );
|
||||
extern Gia_Man_t * Gia_ManDupSelectedOutputs( Gia_Man_t * p, Vec_Int_t * vOutsLeft );
|
||||
|
|
@ -1281,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 );
|
||||
|
|
@ -1288,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 );
|
||||
|
|
@ -1298,6 +1376,7 @@ extern Gia_Man_t * Gia_ManDupMarked( Gia_Man_t * p );
|
|||
extern Gia_Man_t * Gia_ManDupTimes( Gia_Man_t * p, int nTimes );
|
||||
extern Gia_Man_t * Gia_ManDupDfs( Gia_Man_t * p );
|
||||
extern Gia_Man_t * Gia_ManDupDfsOnePo( Gia_Man_t * p, int iPo );
|
||||
extern Gia_Man_t * Gia_ManDupDfsRehash( Gia_Man_t * p );
|
||||
extern Gia_Man_t * Gia_ManDupCofactorVar( Gia_Man_t * p, int iVar, int Value );
|
||||
extern Gia_Man_t * Gia_ManDupCofactorObj( Gia_Man_t * p, int iObj, int Value );
|
||||
extern Gia_Man_t * Gia_ManDupMux( int iVar, Gia_Man_t * pCof1, Gia_Man_t * pCof0 );
|
||||
|
|
@ -1319,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 );
|
||||
|
|
@ -1340,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 );
|
||||
|
|
@ -1365,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 );
|
||||
|
|
@ -1397,6 +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, Vec_Int_t ** pvIndex );
|
||||
/*=== giaForce.c =========================================================*/
|
||||
extern void For_ManExperiment( Gia_Man_t * pGia, int nIters, int fClustered, int fVerbose );
|
||||
/*=== giaFrames.c =========================================================*/
|
||||
|
|
@ -1434,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 );
|
||||
|
|
@ -1480,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 );
|
||||
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 );
|
||||
|
|
@ -1504,10 +1595,13 @@ extern void Mf_ManSetDefaultPars( Jf_Par_t * pPars );
|
|||
extern Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars );
|
||||
extern void * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose );
|
||||
/*=== giaMini.c ===========================================================*/
|
||||
extern Gia_Man_t * Gia_ManReadMiniAig( char * pFileName );
|
||||
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 );
|
||||
|
|
@ -1557,6 +1651,16 @@ extern void Gia_ManIncrSimStart( Gia_Man_t * p, int nWords, int n
|
|||
extern void Gia_ManIncrSimSet( Gia_Man_t * p, Vec_Int_t * vObjLits );
|
||||
extern int Gia_ManIncrSimCheckOver( Gia_Man_t * p, int iLit0, int iLit1 );
|
||||
extern int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 );
|
||||
/*=== giaSimBase.c ============================================================*/
|
||||
extern Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * p );
|
||||
extern Vec_Wrd_t * Gia_ManSimPatSimOut( Gia_Man_t * pGia, Vec_Wrd_t * vSimsPi, int fOuts );
|
||||
extern void Gia_ManSim2ArrayOne( Vec_Wrd_t * vSimsPi, Vec_Int_t * vRes );
|
||||
extern Vec_Wec_t * Gia_ManSim2Array( Vec_Ptr_t * vSims );
|
||||
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 );
|
||||
|
|
@ -1608,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 );
|
||||
|
|
@ -1630,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 );
|
||||
|
|
@ -1649,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 );
|
||||
|
|
@ -1668,12 +1775,14 @@ extern void Gia_ManSetPhase1( Gia_Man_t * p );
|
|||
extern void Gia_ManCleanPhase( Gia_Man_t * p );
|
||||
extern int Gia_ManCheckCoPhase( Gia_Man_t * p );
|
||||
extern int Gia_ManLevelNum( Gia_Man_t * p );
|
||||
extern int Gia_ManLevelRNum( Gia_Man_t * p );
|
||||
extern Vec_Int_t * Gia_ManGetCiLevels( Gia_Man_t * p );
|
||||
extern int Gia_ManSetLevels( Gia_Man_t * p, Vec_Int_t * vCiLevels );
|
||||
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 );
|
||||
|
|
@ -1682,7 +1791,9 @@ extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t **
|
|||
extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE );
|
||||
extern int Gia_ObjRecognizeMuxLits( Gia_Man_t * p, Gia_Obj_t * pNode, int * iLitT, int * iLitE );
|
||||
extern int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode );
|
||||
extern int Gia_NodeMffcSizeMark( Gia_Man_t * p, Gia_Obj_t * pNode );
|
||||
extern int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp );
|
||||
extern int Gia_NodeMffcMapping( Gia_Man_t * p );
|
||||
extern int Gia_ManHasDangling( Gia_Man_t * p );
|
||||
extern int Gia_ManMarkDangling( Gia_Man_t * p );
|
||||
extern Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p );
|
||||
|
|
@ -1704,6 +1815,18 @@ extern int Gia_ManCheckSuppOverlap( Gia_Man_t * p, int iNode1, i
|
|||
extern int Gia_ManCountPisWithFanout( Gia_Man_t * p );
|
||||
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;
|
||||
|
|
@ -1713,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
|
||||
|
||||
|
|
@ -1723,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
|
||||
|
||||
|
|
@ -100,6 +102,41 @@ Gia_Man_t * Gia_ManFromAig( Aig_Man_t * p )
|
|||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Checks integrity of choice nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManCheckChoices_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
|
||||
{
|
||||
if ( !pObj || !Gia_ObjIsAnd(pObj) || pObj->fPhase )
|
||||
return;
|
||||
pObj->fPhase = 1;
|
||||
Gia_ManCheckChoices_rec( p, Gia_ObjFanin0(pObj) );
|
||||
Gia_ManCheckChoices_rec( p, Gia_ObjFanin1(pObj) );
|
||||
Gia_ManCheckChoices_rec( p, Gia_ObjSiblObj(p, Gia_ObjId(p, pObj)) );
|
||||
}
|
||||
void Gia_ManCheckChoices( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int i, fFound = 0;
|
||||
Gia_ManCleanPhase( p );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Gia_ManCheckChoices_rec( p, Gia_ObjFanin0(pObj) );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( !pObj->fPhase )
|
||||
printf( "Object %d is dangling.\n", i ), fFound = 1;
|
||||
if ( !fFound )
|
||||
printf( "There are no dangling objects.\n" );
|
||||
Gia_ManCleanPhase( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Duplicates AIG in the DFS order.]
|
||||
|
|
@ -155,6 +192,9 @@ Gia_Man_t * Gia_ManFromAigChoices( Aig_Man_t * p )
|
|||
Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) );
|
||||
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
|
||||
//assert( Gia_ManObjNum(pNew) == Aig_ManObjNum(p) );
|
||||
//Gia_ManCheckChoices( pNew );
|
||||
if ( pNew->pSibls )
|
||||
Gia_ManDeriveReprsFromSibls( pNew );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
@ -575,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;
|
||||
|
|
@ -592,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
|
||||
|
||||
|
|
@ -176,6 +177,7 @@ Vec_Str_t * Gia_AigerWriteLiterals( Vec_Int_t * vLits )
|
|||
Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSimple, int fSkipStrash, int fCheck )
|
||||
{
|
||||
Gia_Man_t * pNew, * pTemp;
|
||||
Vec_Ptr_t * vNamesIn = NULL, * vNamesOut = NULL, * vNamesRegIn = NULL, * vNamesRegOut = NULL, * vNamesNode = NULL;
|
||||
Vec_Int_t * vLits = NULL, * vPoTypes = NULL;
|
||||
Vec_Int_t * vNodes, * vDrivers, * vInits = NULL;
|
||||
int iObj, iNode0, iNode1, fHieOnly = 0;
|
||||
|
|
@ -377,6 +379,98 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
pCur = pSymbols;
|
||||
if ( pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' )
|
||||
{
|
||||
int fReadNames = 1;
|
||||
if ( fReadNames )
|
||||
{
|
||||
int fError = 0;
|
||||
while ( !fError && pCur < (unsigned char *)pContents + nFileSize && *pCur != 'c' )
|
||||
{
|
||||
int iTerm;
|
||||
char * pType = (char *)pCur;
|
||||
char * pName = NULL;
|
||||
// check terminal type
|
||||
if ( *pCur != 'i' && *pCur != 'o' && *pCur != 'l' && *pCur != 'n' )
|
||||
{
|
||||
fError = 1;
|
||||
break;
|
||||
}
|
||||
// get terminal number
|
||||
iTerm = atoi( (char *)++pCur ); while ( *pCur++ != ' ' );
|
||||
// skip spaces
|
||||
while ( *pCur == ' ' )
|
||||
pCur++;
|
||||
// skip till the end of line
|
||||
for ( pName = (char *)pCur; *pCur && *pCur != '\n'; pCur++ );
|
||||
if ( *pCur == '\n' )
|
||||
*pCur = 0;
|
||||
// save the name
|
||||
if ( *pType == 'i' )
|
||||
{
|
||||
if ( vNamesIn == NULL )
|
||||
vNamesIn = Vec_PtrStart( nInputs );
|
||||
if ( Vec_PtrSize(vNamesIn) <= iTerm )
|
||||
{
|
||||
fError = 1;
|
||||
break;
|
||||
}
|
||||
Vec_PtrWriteEntry( vNamesIn, iTerm, Abc_UtilStrsav(pName) );
|
||||
}
|
||||
else if ( *pType == 'o' )
|
||||
{
|
||||
if ( vNamesOut == NULL )
|
||||
vNamesOut = Vec_PtrStart( nOutputs );
|
||||
if ( Vec_PtrSize(vNamesOut) <= iTerm )
|
||||
{
|
||||
fError = 1;
|
||||
break;
|
||||
}
|
||||
Vec_PtrWriteEntry( vNamesOut, iTerm, Abc_UtilStrsav(pName) );
|
||||
}
|
||||
else if ( *pType == 'l' )
|
||||
{
|
||||
if ( vNamesRegIn == NULL )
|
||||
vNamesRegIn = Vec_PtrStart( nLatches );
|
||||
if ( vNamesRegOut == NULL )
|
||||
vNamesRegOut = Vec_PtrStart( nLatches );
|
||||
if ( Vec_PtrSize(vNamesRegIn) <= iTerm )
|
||||
{
|
||||
fError = 1;
|
||||
break;
|
||||
}
|
||||
Vec_PtrWriteEntry( vNamesRegIn, iTerm, Abc_UtilStrsavTwo(pName, (char *)"_in") );
|
||||
Vec_PtrWriteEntry( vNamesRegOut, iTerm, Abc_UtilStrsav(pName) );
|
||||
}
|
||||
else if ( *pType == 'n' )
|
||||
{
|
||||
if ( Vec_IntSize(&pNew->vHTable) != 0 )
|
||||
{
|
||||
printf( "Structural hashing should be disabled to read internal nodes names.\n" );
|
||||
fError = 1;
|
||||
break;
|
||||
}
|
||||
if ( vNamesNode == NULL )
|
||||
vNamesNode = Vec_PtrStart( Gia_ManObjNum(pNew) );
|
||||
Vec_PtrWriteEntry( vNamesNode, iTerm, Abc_UtilStrsav(pName) );
|
||||
}
|
||||
else
|
||||
{
|
||||
fError = 1;
|
||||
break;
|
||||
}
|
||||
pCur++;
|
||||
}
|
||||
if ( fError )
|
||||
{
|
||||
printf( "Error occurred when reading signal names. Signal names ignored.\n" );
|
||||
if ( vNamesIn ) Vec_PtrFreeFree( vNamesIn ), vNamesIn = NULL;
|
||||
if ( vNamesOut ) Vec_PtrFreeFree( vNamesOut ), vNamesOut = NULL;
|
||||
if ( vNamesRegIn ) Vec_PtrFreeFree( vNamesRegIn ), vNamesRegIn = NULL;
|
||||
if ( vNamesRegOut ) Vec_PtrFreeFree( vNamesRegOut ), vNamesRegOut = NULL;
|
||||
if ( vNamesNode ) Vec_PtrFreeFree( vNamesNode ), vNamesNode = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int fBreakUsed = 0;
|
||||
unsigned char * pCurOld = pCur;
|
||||
pNew->vUserPiIds = Vec_IntStartFull( nInputs );
|
||||
|
|
@ -505,6 +599,7 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
}
|
||||
Vec_IntFree( vPoNames );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -551,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" );
|
||||
|
|
@ -559,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
|
||||
|
|
@ -636,6 +762,7 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
pCur++;
|
||||
if ( (*pCur >= 'a' && *pCur <= 'z') || (*pCur >= 'A' && *pCur <= 'Z') || (*pCur >= '0' && *pCur <= '9') )
|
||||
{
|
||||
ABC_FREE( pNew->pName );
|
||||
pNew->pName = Abc_UtilStrsav( (char *)pCur ); pCur += strlen(pNew->pName) + 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -702,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' )
|
||||
{
|
||||
|
|
@ -772,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -816,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 );
|
||||
|
|
@ -855,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 );
|
||||
|
|
@ -866,6 +1145,39 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
|
|||
Abc_Print( 0, "Structural hashing enabled while reading AIGER invalidated the mapping. Consider using \"&r -s\".\n" );
|
||||
Vec_IntFreeP( &pNew->vMapping );
|
||||
}
|
||||
if ( vNamesIn && Gia_ManPiNum(pNew) != Vec_PtrSize(vNamesIn) )
|
||||
Abc_Print( 0, "The number of inputs does not match the number of input names.\n" );
|
||||
else if ( vNamesOut && Gia_ManPoNum(pNew) != Vec_PtrSize(vNamesOut) )
|
||||
Abc_Print( 0, "The number of output does not match the number of output names.\n" );
|
||||
else if ( vNamesRegOut && Gia_ManRegNum(pNew) != Vec_PtrSize(vNamesRegOut) )
|
||||
Abc_Print( 0, "The number of inputs does not match the number of flop names.\n" );
|
||||
else if ( vNamesIn && vNamesOut )
|
||||
{
|
||||
pNew->vNamesIn = vNamesIn; vNamesIn = NULL;
|
||||
pNew->vNamesOut = vNamesOut; vNamesOut = NULL;
|
||||
if ( vNamesRegOut )
|
||||
{
|
||||
Vec_PtrAppend( pNew->vNamesIn, vNamesRegOut );
|
||||
Vec_PtrClear( vNamesRegOut );
|
||||
Vec_PtrFree( vNamesRegOut );
|
||||
vNamesRegOut = NULL;
|
||||
}
|
||||
if ( vNamesRegIn )
|
||||
{
|
||||
Vec_PtrAppend( pNew->vNamesOut, vNamesRegIn );
|
||||
Vec_PtrClear( vNamesRegIn );
|
||||
Vec_PtrFree( vNamesRegIn );
|
||||
vNamesRegIn = NULL;
|
||||
}
|
||||
}
|
||||
if ( vNamesNode && Gia_ManObjNum(pNew) != Vec_PtrSize(vNamesNode) )
|
||||
Abc_Print( 0, "The size of the node name array does not match the number of objects. Names are not entered.\n" );
|
||||
else if ( vNamesNode )
|
||||
pNew->vNamesNode = vNamesNode, vNamesNode = NULL;
|
||||
if ( vNamesIn ) Vec_PtrFreeFree( vNamesIn );
|
||||
if ( vNamesOut ) Vec_PtrFreeFree( vNamesOut );
|
||||
if ( vNamesRegIn ) Vec_PtrFreeFree( vNamesRegIn );
|
||||
if ( vNamesRegOut ) Vec_PtrFreeFree( vNamesRegOut );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
@ -982,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;
|
||||
}
|
||||
|
||||
|
|
@ -1083,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;
|
||||
|
|
@ -1197,6 +1509,14 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
|
|||
Gia_ManForEachPo( p, pObj, i )
|
||||
fprintf( pFile, "o%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesOut, i) );
|
||||
}
|
||||
if ( p->vNamesNode && Vec_PtrSize(p->vNamesNode) != Gia_ManObjNum(p) )
|
||||
Abc_Print( 0, "The size of the node name array does not match the number of objects. Names are not written.\n" );
|
||||
else if ( p->vNamesNode )
|
||||
{
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( Vec_PtrEntry(p->vNamesNode, i) )
|
||||
fprintf( pFile, "n%d %s\n", i, (char *)Vec_PtrEntry(p->vNamesNode, i) );
|
||||
}
|
||||
|
||||
// write the comment
|
||||
if ( fWriteNewLine )
|
||||
|
|
@ -1231,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 )
|
||||
|
|
@ -1322,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 )
|
||||
{
|
||||
|
|
@ -1338,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 )
|
||||
|
|
@ -1360,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) )
|
||||
{
|
||||
|
|
@ -1404,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 )
|
||||
{
|
||||
|
|
@ -1415,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 )
|
||||
{
|
||||
|
|
@ -1425,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.]
|
||||
|
|
@ -1477,10 +1933,151 @@ void Gia_AigerWriteSimple( Gia_Man_t * pInit, char * pFileName )
|
|||
fclose( pFile );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Simple AIGER reader/writer.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline unsigned Aiger_ReadUnsigned( 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 inline void Aiger_WriteUnsigned( FILE * pFile, unsigned x )
|
||||
{
|
||||
unsigned char ch;
|
||||
while (x & ~0x7f)
|
||||
{
|
||||
ch = (x & 0x7f) | 0x80;
|
||||
fputc( ch, pFile );
|
||||
x >>= 7;
|
||||
}
|
||||
ch = x;
|
||||
fputc( ch, pFile );
|
||||
}
|
||||
int * Aiger_Read( char * pFileName, int * pnObjs, int * pnIns, int * pnLats, int * pnOuts, int * pnAnds )
|
||||
{
|
||||
int i, Temp, Value = 0, nTotal, nObjs, nIns, nLats, nOuts, nAnds, * pObjs;
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
fprintf( stdout, "Aiger_Read(): Cannot open the output file \"%s\".\n", pFileName );
|
||||
return NULL;
|
||||
}
|
||||
if ( fgetc(pFile) != 'a' || fgetc(pFile) != 'i' || fgetc(pFile) != 'g' )
|
||||
{
|
||||
fprintf( stdout, "Aiger_Read(): Can only read binary AIGER.\n" );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
if ( fscanf(pFile, "%d %d %d %d %d", &nTotal, &nIns, &nLats, &nOuts, &nAnds) != 5 )
|
||||
{
|
||||
fprintf( stdout, "Aiger_Read(): Cannot read the header line.\n" );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
if ( nTotal != nIns + nLats + nAnds )
|
||||
{
|
||||
fprintf( stdout, "The number of objects does not match.\n" );
|
||||
fclose( pFile );
|
||||
return NULL;
|
||||
}
|
||||
nObjs = 1 + nIns + 2*nLats + nOuts + nAnds;
|
||||
pObjs = ABC_CALLOC( int, nObjs * 2 );
|
||||
// read flop input literals
|
||||
for ( i = 0; i < nLats; i++ )
|
||||
{
|
||||
while ( fgetc(pFile) != '\n' );
|
||||
Value += fscanf( pFile, "%d", &Temp );
|
||||
pObjs[2*(nObjs-nLats+i)+0] = Temp;
|
||||
pObjs[2*(nObjs-nLats+i)+1] = Temp;
|
||||
}
|
||||
// read output literals
|
||||
for ( i = 0; i < nOuts; i++ )
|
||||
{
|
||||
while ( fgetc(pFile) != '\n' );
|
||||
Value += fscanf( pFile, "%d", &Temp );
|
||||
pObjs[2*(nObjs-nOuts-nLats+i)+0] = Temp;
|
||||
pObjs[2*(nObjs-nOuts-nLats+i)+1] = Temp;
|
||||
}
|
||||
assert( Value == nLats + nOuts );
|
||||
// read the binary part
|
||||
while ( fgetc(pFile) != '\n' );
|
||||
for ( i = 0; i < nAnds; i++ )
|
||||
{
|
||||
int uLit = 2*(1 + nIns + nLats + i);
|
||||
int uLit1 = uLit - Aiger_ReadUnsigned( pFile );
|
||||
int uLit0 = uLit1 - Aiger_ReadUnsigned( pFile );
|
||||
pObjs[2*(1+nIns+nLats+i)+0] = uLit0;
|
||||
pObjs[2*(1+nIns+nLats+i)+1] = uLit1;
|
||||
}
|
||||
fclose( pFile );
|
||||
if ( pnObjs ) *pnObjs = nObjs;
|
||||
if ( pnIns ) *pnIns = nIns;
|
||||
if ( pnLats ) *pnLats = nLats;
|
||||
if ( pnOuts ) *pnOuts = nOuts;
|
||||
if ( pnAnds ) *pnAnds = nAnds;
|
||||
return pObjs;
|
||||
}
|
||||
void Aiger_Write( char * pFileName, int * pObjs, int nObjs, int nIns, int nLats, int nOuts, int nAnds )
|
||||
{
|
||||
FILE * pFile = fopen( pFileName, "wb" ); int i;
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
fprintf( stdout, "Aiger_Write(): Cannot open the output file \"%s\".\n", pFileName );
|
||||
return;
|
||||
}
|
||||
fprintf( pFile, "aig %d %d %d %d %d\n", nIns + nLats + nAnds, nIns, nLats, nOuts, nAnds );
|
||||
for ( i = 0; i < nLats; i++ )
|
||||
fprintf( pFile, "%d\n", pObjs[2*(nObjs-nLats+i)+0] );
|
||||
for ( i = 0; i < nOuts; i++ )
|
||||
fprintf( pFile, "%d\n", pObjs[2*(nObjs-nOuts-nLats+i)+0] );
|
||||
for ( i = 0; i < nAnds; i++ )
|
||||
{
|
||||
int uLit = 2*(1 + nIns + nLats + i);
|
||||
int uLit0 = pObjs[2*(1+nIns+nLats+i)+0];
|
||||
int uLit1 = pObjs[2*(1+nIns+nLats+i)+1];
|
||||
Aiger_WriteUnsigned( pFile, uLit - uLit1 );
|
||||
Aiger_WriteUnsigned( pFile, uLit1 - uLit0 );
|
||||
}
|
||||
fprintf( pFile, "c\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
void Aiger_Test( char * pFileNameIn, char * pFileNameOut )
|
||||
{
|
||||
int nObjs, nIns, nLats, nOuts, nAnds, * pObjs = Aiger_Read( pFileNameIn, &nObjs, &nIns, &nLats, &nOuts, &nAnds );
|
||||
if ( pObjs == NULL )
|
||||
return;
|
||||
printf( "Read input file \"%s\".\n", pFileNameIn );
|
||||
Aiger_Write( pFileNameOut, pObjs, nObjs, nIns, nLats, nOuts, nAnds );
|
||||
printf( "Written output file \"%s\".\n", pFileNameOut );
|
||||
ABC_FREE( pObjs );
|
||||
}
|
||||
|
||||
/*
|
||||
int main( int argc, char ** argv )
|
||||
{
|
||||
if ( argc != 3 )
|
||||
return 0;
|
||||
Aiger_Test( argv[1], argv[2] );
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
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 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 )
|
||||
|
|
@ -1105,6 +1147,8 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
|
|||
}
|
||||
if ( status == 1 )
|
||||
{
|
||||
if ( f0Proved )
|
||||
Gia_ManPatchCoDriver( pAig, i, 0 );
|
||||
p->nSatUnsat++;
|
||||
p->nConfUnsat += p->Pars.nBTThis;
|
||||
p->timeSatUnsat += Abc_Clock() - clk;
|
||||
|
|
@ -1124,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,
|
||||
|
|
@ -1131,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 ///
|
||||
|
|
@ -1138,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
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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,350 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaDecs.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Calling various decomposition engines.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaDecs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "aig/gia/gia.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "misc/extra/extra.h"
|
||||
#include "bool/bdc/bdc.h"
|
||||
#include "bool/kit/kit.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut );
|
||||
extern Vec_Int_t * Gia_ManResubOne( Vec_Ptr_t * vDivs, int nWords, int nLimit, int nDivsMax, int iChoice, int fUseXor, int fDebug, int fVerbose, word * pFunc, int Depth );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ResubVarNum( Vec_Int_t * vResub )
|
||||
{
|
||||
if ( Vec_IntSize(vResub) == 1 )
|
||||
return Vec_IntEntryLast(vResub) >= 2;
|
||||
return Vec_IntEntryLast(vResub)/2 - Vec_IntSize(vResub)/2 - 1;
|
||||
}
|
||||
word Gia_ResubToTruth6_rec( Vec_Int_t * vResub, int iNode, int nVars )
|
||||
{
|
||||
assert( iNode >= 0 && nVars <= 6 );
|
||||
if ( iNode < nVars )
|
||||
return s_Truths6[iNode];
|
||||
else
|
||||
{
|
||||
int iLit0 = Vec_IntEntry( vResub, Abc_Var2Lit(iNode-nVars, 0) );
|
||||
int iLit1 = Vec_IntEntry( vResub, Abc_Var2Lit(iNode-nVars, 1) );
|
||||
word Res0 = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iLit0)-2, nVars );
|
||||
word Res1 = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iLit1)-2, nVars );
|
||||
Res0 = Abc_LitIsCompl(iLit0) ? ~Res0 : Res0;
|
||||
Res1 = Abc_LitIsCompl(iLit1) ? ~Res1 : Res1;
|
||||
return iLit0 > iLit1 ? Res0 ^ Res1 : Res0 & Res1;
|
||||
}
|
||||
}
|
||||
word Gia_ResubToTruth6( Vec_Int_t * vResub )
|
||||
{
|
||||
word Res;
|
||||
int iRoot = Vec_IntEntryLast(vResub);
|
||||
if ( iRoot < 2 )
|
||||
return iRoot ? ~(word)0 : 0;
|
||||
assert( iRoot != 2 && iRoot != 3 );
|
||||
Res = Gia_ResubToTruth6_rec( vResub, Abc_Lit2Var(iRoot)-2, Gia_ResubVarNum(vResub) );
|
||||
return Abc_LitIsCompl(iRoot) ? ~Res : Res;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Wrd_t * Gia_ManDeriveTruths( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords )
|
||||
{
|
||||
int nTtWords = Abc_Truth6WordNum(Vec_IntSize(vSet));
|
||||
int nFuncs = Vec_WrdSize(vIsfs) / 2 / nWords;
|
||||
Vec_Wrd_t * vRes = Vec_WrdStart( 2 * nFuncs * nTtWords );
|
||||
Vec_Wrd_t * vIn = Vec_WrdStart( 64*nWords ), * vOut;
|
||||
int i, f, m, iObj; word Func;
|
||||
assert( Vec_IntSize(vSet) <= 64 );
|
||||
Vec_IntForEachEntry( vSet, iObj, i )
|
||||
Abc_TtCopy( Vec_WrdEntryP(vIn, i*nWords), Vec_WrdEntryP(vSims, Vec_IntEntry(vCands, iObj)*nWords), nWords, 0 );
|
||||
vOut = Vec_WrdStart( Vec_WrdSize(vIn) );
|
||||
Extra_BitMatrixTransposeP( vIn, nWords, vOut, 1 );
|
||||
for ( f = 0; f < nFuncs; f++ )
|
||||
{
|
||||
word * pIsf[2] = { Vec_WrdEntryP(vIsfs, (2*f+0)*nWords),
|
||||
Vec_WrdEntryP(vIsfs, (2*f+1)*nWords) };
|
||||
word * pTruth[2] = { Vec_WrdEntryP(vRes, (2*f+0)*nTtWords),
|
||||
Vec_WrdEntryP(vRes, (2*f+1)*nTtWords) };
|
||||
for ( m = 0; m < 64*nWords; m++ )
|
||||
{
|
||||
int iMint = (int)Vec_WrdEntry(vOut, m);
|
||||
int Value0 = Abc_TtGetBit( pIsf[0], m );
|
||||
int Value1 = Abc_TtGetBit( pIsf[1], m );
|
||||
if ( !Value0 && !Value1 )
|
||||
continue;
|
||||
if ( Value0 && Value1 )
|
||||
printf( "Internal error: Onset and Offset overlap.\n" );
|
||||
assert( !Value0 || !Value1 );
|
||||
Abc_TtSetBit( pTruth[Value1], iMint );
|
||||
}
|
||||
if ( Abc_TtCountOnesVecMask(pTruth[0], pTruth[1], nTtWords, 0) )
|
||||
printf( "Verification for function %d failed for %d minterm pairs.\n", f,
|
||||
Abc_TtCountOnesVecMask(pTruth[0], pTruth[1], nTtWords, 0) );
|
||||
}
|
||||
if ( Vec_IntSize(vSet) < 6 )
|
||||
Vec_WrdForEachEntry( vRes, Func, i )
|
||||
Vec_WrdWriteEntry( vRes, i, Abc_Tt6Stretch(Func, Vec_IntSize(vSet)) );
|
||||
Vec_WrdFree( vIn );
|
||||
Vec_WrdFree( vOut );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManCountResub( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vResub; int nNodes;
|
||||
int nTtWords = Abc_Truth6WordNum(nVars);
|
||||
int v, nFuncs = Vec_WrdSize(vTruths) / 2 / nTtWords;
|
||||
Vec_Wrd_t * vElems = Vec_WrdStartTruthTables( nVars );
|
||||
Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2 + nVars );
|
||||
assert( Vec_WrdSize(vElems) == nTtWords * nVars );
|
||||
assert( nFuncs == 1 );
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+0)*nTtWords) );
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+1)*nTtWords) );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(vElems, v*nTtWords) );
|
||||
vResub = Gia_ManResubOne( vDivs, nTtWords, 30, 100, 0, 0, 0, fVerbose, NULL, 0 );
|
||||
Vec_PtrFree( vDivs );
|
||||
Vec_WrdFree( vElems );
|
||||
nNodes = Vec_IntSize(vResub) ? Vec_IntSize(vResub)/2 : 999;
|
||||
Vec_IntFree( vResub );
|
||||
return nNodes;
|
||||
}
|
||||
Vec_Int_t * Gia_ManDeriveResub( Vec_Wrd_t * vTruths, int nVars )
|
||||
{
|
||||
Vec_Int_t * vResub;
|
||||
int nTtWords = Abc_Truth6WordNum(nVars);
|
||||
int v, nFuncs = Vec_WrdSize(vTruths) / 2 / nTtWords;
|
||||
Vec_Wrd_t * vElems = Vec_WrdStartTruthTables( nVars );
|
||||
Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2 + nVars );
|
||||
assert( Vec_WrdSize(vElems) == nTtWords * nVars );
|
||||
assert( nFuncs == 1 );
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+0)*nTtWords) );
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(vTruths, (2*0+1)*nTtWords) );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
Vec_PtrPush( vDivs, Vec_WrdEntryP(vElems, v*nTtWords) );
|
||||
vResub = Gia_ManResubOne( vDivs, nTtWords, 30, 100, 0, 0, 0, 0, NULL, 0 );
|
||||
Vec_PtrFree( vDivs );
|
||||
Vec_WrdFree( vElems );
|
||||
return vResub;
|
||||
}
|
||||
|
||||
int Gia_ManCountBidec( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
|
||||
{
|
||||
int nNodes, nTtWords = Abc_Truth6WordNum(nVars);
|
||||
word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
|
||||
Vec_WrdEntryP(vTruths, 1*nTtWords) };
|
||||
Abc_TtOr( pTruth[0], pTruth[0], pTruth[1], nTtWords );
|
||||
nNodes = Bdc_ManBidecNodeNum( pTruth[1], pTruth[0], nVars, fVerbose );
|
||||
Abc_TtSharp( pTruth[0], pTruth[0], pTruth[1], nTtWords );
|
||||
return nNodes;
|
||||
}
|
||||
Vec_Int_t * Gia_ManDeriveBidec( Vec_Wrd_t * vTruths, int nVars )
|
||||
{
|
||||
Vec_Int_t * vRes = NULL;
|
||||
int nTtWords = Abc_Truth6WordNum(nVars);
|
||||
word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
|
||||
Vec_WrdEntryP(vTruths, 1*nTtWords) };
|
||||
Abc_TtOr( pTruth[0], pTruth[0], pTruth[1], nTtWords );
|
||||
vRes = Bdc_ManBidecResub( pTruth[1], pTruth[0], nVars );
|
||||
Abc_TtSharp( pTruth[0], pTruth[0], pTruth[1], nTtWords );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
int Gia_ManCountIsop( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
|
||||
{
|
||||
int nTtWords = Abc_Truth6WordNum(nVars);
|
||||
word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
|
||||
Vec_WrdEntryP(vTruths, 1*nTtWords) };
|
||||
int nNodes = Kit_IsopNodeNum( (unsigned *)pTruth[0], (unsigned *)pTruth[1], nVars, NULL );
|
||||
return nNodes;
|
||||
}
|
||||
Vec_Int_t * Gia_ManDeriveIsop( Vec_Wrd_t * vTruths, int nVars )
|
||||
{
|
||||
Vec_Int_t * vRes = NULL;
|
||||
int nTtWords = Abc_Truth6WordNum(nVars);
|
||||
word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
|
||||
Vec_WrdEntryP(vTruths, 1*nTtWords) };
|
||||
vRes = Kit_IsopResub( (unsigned *)pTruth[0], (unsigned *)pTruth[1], nVars, NULL );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
int Gia_ManCountBdd( Vec_Wrd_t * vTruths, int nVars, int fVerbose )
|
||||
{
|
||||
extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
|
||||
int nTtWords = Abc_Truth6WordNum(nVars);
|
||||
word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
|
||||
Vec_WrdEntryP(vTruths, 1*nTtWords) };
|
||||
Gia_Man_t * pGia; int nNodes;
|
||||
|
||||
Abc_TtOr( pTruth[1], pTruth[1], pTruth[0], nTtWords );
|
||||
Abc_TtNot( pTruth[0], nTtWords );
|
||||
pGia = Gia_TryPermOptNew( pTruth[0], nVars, 1, nTtWords, 50, 0 );
|
||||
Abc_TtNot( pTruth[0], nTtWords );
|
||||
Abc_TtSharp( pTruth[1], pTruth[1], pTruth[0], nTtWords );
|
||||
|
||||
nNodes = Gia_ManAndNum(pGia);
|
||||
Gia_ManStop( pGia );
|
||||
return nNodes;
|
||||
}
|
||||
Vec_Int_t * Gia_ManDeriveBdd( Vec_Wrd_t * vTruths, int nVars )
|
||||
{
|
||||
extern Vec_Int_t * Gia_ManToGates( Gia_Man_t * p );
|
||||
Vec_Int_t * vRes = NULL;
|
||||
extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
|
||||
int nTtWords = Abc_Truth6WordNum(nVars);
|
||||
word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
|
||||
Vec_WrdEntryP(vTruths, 1*nTtWords) };
|
||||
Gia_Man_t * pGia;
|
||||
|
||||
Abc_TtOr( pTruth[1], pTruth[1], pTruth[0], nTtWords );
|
||||
Abc_TtNot( pTruth[0], nTtWords );
|
||||
pGia = Gia_TryPermOptNew( pTruth[0], nVars, 1, nTtWords, 50, 0 );
|
||||
Abc_TtNot( pTruth[0], nTtWords );
|
||||
Abc_TtSharp( pTruth[1], pTruth[1], pTruth[0], nTtWords );
|
||||
|
||||
vRes = Gia_ManToGates( pGia );
|
||||
Gia_ManStop( pGia );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManEvalSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int fVerbose )
|
||||
{
|
||||
Vec_Wrd_t * vTruths = Gia_ManDeriveTruths( p, vSims, vIsfs, vCands, vSet, nWords );
|
||||
int nTtWords = Vec_WrdSize(vTruths)/2, nVars = Vec_IntSize(vSet);
|
||||
word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
|
||||
Vec_WrdEntryP(vTruths, 1*nTtWords) };
|
||||
int nNodesResub = Gia_ManCountResub( vTruths, nVars, 0 );
|
||||
int nNodesBidec = nVars > 2 ? Gia_ManCountBidec( vTruths, nVars, 0 ) : 999;
|
||||
int nNodesIsop = nVars > 2 ? Gia_ManCountIsop( vTruths, nVars, 0 ) : 999;
|
||||
int nNodesBdd = nVars > 2 ? Gia_ManCountBdd( vTruths, nVars, 0 ) : 999;
|
||||
int nNodesMin = Abc_MinInt( Abc_MinInt(nNodesResub, nNodesBidec), Abc_MinInt(nNodesIsop, nNodesBdd) );
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Size = %2d ", nVars );
|
||||
printf( "Resub =%3d ", nNodesResub );
|
||||
printf( "Bidec =%3d ", nNodesBidec );
|
||||
printf( "Isop =%3d ", nNodesIsop );
|
||||
printf( "Bdd =%3d ", nNodesBdd );
|
||||
Abc_TtIsfPrint( pTruth[0], pTruth[1], nTtWords );
|
||||
if ( nVars <= 6 )
|
||||
{
|
||||
printf( " " );
|
||||
Extra_PrintHex( stdout, (unsigned*)pTruth[0], nVars );
|
||||
printf( " " );
|
||||
Extra_PrintHex( stdout, (unsigned*)pTruth[1], nVars );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
Vec_WrdFree( vTruths );
|
||||
if ( nNodesMin > 500 )
|
||||
return -1;
|
||||
if ( nNodesMin == nNodesResub )
|
||||
return (nNodesMin << 2) | 0;
|
||||
if ( nNodesMin == nNodesBidec )
|
||||
return (nNodesMin << 2) | 1;
|
||||
if ( nNodesMin == nNodesIsop )
|
||||
return (nNodesMin << 2) | 2;
|
||||
if ( nNodesMin == nNodesBdd )
|
||||
return (nNodesMin << 2) | 3;
|
||||
return -1;
|
||||
}
|
||||
Vec_Int_t * Gia_ManDeriveSolutionOne( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * vSet, int nWords, int Type )
|
||||
{
|
||||
Vec_Int_t * vRes = NULL;
|
||||
Vec_Wrd_t * vTruths = Gia_ManDeriveTruths( p, vSims, vIsfs, vCands, vSet, nWords );
|
||||
int nTtWords = Vec_WrdSize(vTruths)/2, nVars = Vec_IntSize(vSet);
|
||||
word * pTruth[2] = { Vec_WrdEntryP(vTruths, 0*nTtWords),
|
||||
Vec_WrdEntryP(vTruths, 1*nTtWords) };
|
||||
if ( Type == 0 )
|
||||
vRes = Gia_ManDeriveResub( vTruths, nVars );
|
||||
else if ( Type == 1 )
|
||||
vRes = Gia_ManDeriveBidec( vTruths, nVars );
|
||||
else if ( Type == 2 )
|
||||
vRes = Gia_ManDeriveIsop( vTruths, nVars );
|
||||
else if ( Type == 3 )
|
||||
vRes = Gia_ManDeriveBdd( vTruths, nVars );
|
||||
if ( vRes && Gia_ResubVarNum(vRes) <= 6 )
|
||||
{
|
||||
word Func = Gia_ResubToTruth6( vRes );
|
||||
assert( !(Func & pTruth[0][0]) );
|
||||
assert( !(pTruth[1][0] & ~Func) );
|
||||
}
|
||||
Vec_WrdFree( vTruths );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -19,14 +19,14 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
#include "base/main/main.h"
|
||||
#include "base/cmd/cmd.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -43,9 +43,515 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int TimeOut, int nAnds, int Seed, int fVerbose )
|
||||
Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose, Vec_Ptr_t * vGias )
|
||||
{
|
||||
return NULL;
|
||||
abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
|
||||
abctime clkStart = Abc_Clock();
|
||||
int s, i, IterMax = 100000, nAndsMin = -1, iIterLast = -1;
|
||||
Gia_Man_t * pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
|
||||
Gia_Man_t * pNew = Gia_ManDup( pTemp );
|
||||
Abc_Random(1);
|
||||
for ( s = 0; s < 10+Seed; s++ )
|
||||
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;
|
||||
int fCom = (Rand >> 1) & 1;
|
||||
int fFx = (Rand >> 2) & 1;
|
||||
int KLut = fUseTwo ? 2 + (i % 5) : 3 + (i % 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 );
|
||||
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());
|
||||
if ( Gia_ManAndNum(pNew) > Gia_ManAndNum(pTemp) )
|
||||
{
|
||||
Gia_ManStop( pNew );
|
||||
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) )
|
||||
{
|
||||
//printf( "Updating\n" );
|
||||
//Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pNew) );
|
||||
}
|
||||
if ( fChange && fVerbose )
|
||||
{
|
||||
printf( "Iter %6d : ", i );
|
||||
printf( "Time %8.2f sec : ", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||
printf( "And = %6d ", Gia_ManAndNum(pNew) );
|
||||
printf( "Lev = %3d ", Gia_ManLevelNum(pNew) );
|
||||
if ( fChange )
|
||||
printf( "<== best : " );
|
||||
else if ( fVerbose )
|
||||
printf( " " );
|
||||
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;
|
||||
}
|
||||
if ( i - iIterLast > nNoImpr )
|
||||
{
|
||||
printf( "Completed %d iterations without improvement in %.2f seconds.\n",
|
||||
nNoImpr, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( i == IterMax )
|
||||
printf( "Iteration limit (%d iters) is reached after %.2f seconds.\n", IterMax, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
|
||||
else if ( nAnds && nAndsMin <= nAnds )
|
||||
printf( "Quality goal (%d nodes <= %d nodes) is achieved after %d iterations and %.2f seconds.\n",
|
||||
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 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, vGias );
|
||||
if ( Gia_ManAndNum(pBest) > Gia_ManAndNum(pThis) )
|
||||
{
|
||||
Gia_ManStop( pBest );
|
||||
pBest = pThis;
|
||||
}
|
||||
else
|
||||
Gia_ManStop( pThis );
|
||||
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -54,4 +560,3 @@ Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int TimeOut, int nAnds, int Seed,
|
|||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
|
|||
|
|
@ -416,6 +416,34 @@ Vec_Vec_t * Gia_ManLevelize( Gia_Man_t * p )
|
|||
return vLevels;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Levelizes the nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Wec_t * Gia_ManLevelizeR( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
Vec_Wec_t * vLevels;
|
||||
int nLevels, Level, i;
|
||||
nLevels = Gia_ManLevelRNum( p );
|
||||
vLevels = Vec_WecStart( nLevels + 1 );
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( i == 0 || (!Gia_ObjIsCo(pObj) && !Gia_ObjLevel(p, pObj)) )
|
||||
continue;
|
||||
Level = Gia_ObjLevel( p, pObj );
|
||||
assert( Level <= nLevels );
|
||||
Vec_WecPush( vLevels, Level, i );
|
||||
}
|
||||
return vLevels;
|
||||
}
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes reverse topological order.]
|
||||
|
|
|
|||
2679
src/aig/gia/giaDup.c
2679
src/aig/gia/giaDup.c
File diff suppressed because it is too large
Load Diff
|
|
@ -32,7 +32,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
http://www.emis.de/journals/JGAA/accepted/2004/HarelKoren2004.8.2.pdf
|
||||
|
||||
Iterative refinement is described in the paper: F. A. Aloul, I. L. Markov, and K. A. Sakallah.
|
||||
"FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI’03.
|
||||
"FORCE: A Fast and Easy-To-Implement Variable-Ordering Heuristic", Proc. GLSVLSI 03.
|
||||
http://www.eecs.umich.edu/~imarkov/pubs/conf/glsvlsi03-force.pdf
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ int * Gia_ManDeriveNexts( Gia_Man_t * p )
|
|||
pTails[i] = i;
|
||||
for ( i = 0; i < Gia_ManObjNum(p); i++ )
|
||||
{
|
||||
//if ( p->pReprs[i].iRepr == GIA_VOID )
|
||||
if ( !p->pReprs[i].iRepr || p->pReprs[i].iRepr == GIA_VOID )
|
||||
continue;
|
||||
pNexts[ pTails[p->pReprs[i].iRepr] ] = i;
|
||||
|
|
@ -309,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 []
|
||||
|
|
@ -480,8 +514,10 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem )
|
|||
}
|
||||
CounterX -= Gia_ManCoNum(p);
|
||||
nLits = Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX;
|
||||
Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d mem =%5.2f MB\n",
|
||||
Counter0, Counter, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem );
|
||||
// Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d mem =%5.2f MB\n",
|
||||
// Counter0, Counter, nLits, CounterX, Proved, (Mem == 0.0) ? 8.0*Gia_ManObjNum(p)/(1<<20) : Mem );
|
||||
Abc_Print( 1, "cst =%8d cls =%7d lit =%8d unused =%8d proof =%6d\n",
|
||||
Counter0, Counter, nLits, CounterX, Proved );
|
||||
assert( Gia_ManEquivCheckLits( p, nLits ) );
|
||||
if ( fVerbose )
|
||||
{
|
||||
|
|
@ -525,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);
|
||||
|
|
@ -712,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.]
|
||||
|
|
@ -732,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 )
|
||||
{
|
||||
|
|
@ -748,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) );
|
||||
|
|
@ -786,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 );
|
||||
|
|
@ -802,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;
|
||||
}
|
||||
|
||||
|
|
@ -1866,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) )
|
||||
{
|
||||
|
|
@ -1985,7 +2046,7 @@ Gia_Man_t * Gia_ManEquivToChoices( Gia_Man_t * p, int nSnapshots )
|
|||
pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
|
||||
pNew->pNexts = ABC_CALLOC( int, Gia_ManObjNum(p) );
|
||||
for ( i = 0; i < Gia_ManObjNum(p); i++ )
|
||||
Gia_ObjSetRepr( pNew, i, GIA_VOID );
|
||||
pNew->pReprs[i].iRepr = GIA_VOID;
|
||||
Gia_ManFillValue( p );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
|
|
@ -2587,6 +2648,346 @@ void Gia_ManFilterEquivsUsingLatches( Gia_Man_t * pGia, int fFlopsOnly, int fFlo
|
|||
Abc_Print( 1, "The number of literals: Before = %d. After = %d.\n", iLitsOld, iLitsNew );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Changing node order.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManChangeOrder_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
|
||||
{
|
||||
if ( ~pObj->Value )
|
||||
return pObj->Value;
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
return pObj->Value = Gia_ManAppendCi(pNew);
|
||||
Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin0(pObj) );
|
||||
if ( Gia_ObjIsCo(pObj) )
|
||||
return pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin1(pObj) );
|
||||
return pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
}
|
||||
Gia_Man_t * Gia_ManChangeOrder( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
Gia_Obj_t * pObj;
|
||||
int i, k;
|
||||
Gia_ManFillValue( p );
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
Gia_ManForEachClass( p, i )
|
||||
Gia_ClassForEachObj( p, i, k )
|
||||
Gia_ManChangeOrder_rec( pNew, p, Gia_ManObj(p, k) );
|
||||
Gia_ManForEachConst( p, k )
|
||||
Gia_ManChangeOrder_rec( pNew, p, Gia_ManObj(p, k) );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Gia_ManChangeOrder_rec( pNew, p, Gia_ObjFanin0(pObj) );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
assert( Gia_ManObjNum(pNew) == Gia_ManObjNum(p) );
|
||||
return pNew;
|
||||
}
|
||||
void Gia_ManTransferEquivs( Gia_Man_t * p, Gia_Man_t * pNew )
|
||||
{
|
||||
Vec_Int_t * vClass;
|
||||
int i, k, iNode, iRepr;
|
||||
assert( Gia_ManObjNum(p) == Gia_ManObjNum(pNew) );
|
||||
assert( p->pReprs != NULL );
|
||||
assert( p->pNexts != NULL );
|
||||
assert( pNew->pReprs == NULL );
|
||||
assert( pNew->pNexts == NULL );
|
||||
// start representatives
|
||||
pNew->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pNew) );
|
||||
for ( i = 0; i < Gia_ManObjNum(pNew); i++ )
|
||||
Gia_ObjSetRepr( pNew, i, GIA_VOID );
|
||||
// iterate over constant candidates
|
||||
Gia_ManForEachConst( p, i )
|
||||
Gia_ObjSetRepr( pNew, 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 )
|
||||
Vec_IntPushUnique( vClass, Abc_Lit2Var(Gia_ManObj(p, k)->Value) );
|
||||
assert( Vec_IntSize( vClass ) > 1 );
|
||||
Vec_IntSort( vClass, 0 );
|
||||
iRepr = Vec_IntEntry( vClass, 0 );
|
||||
Vec_IntForEachEntryStart( vClass, iNode, k, 1 )
|
||||
Gia_ObjSetRepr( pNew, iNode, iRepr );
|
||||
}
|
||||
Vec_IntFree( vClass );
|
||||
pNew->pNexts = Gia_ManDeriveNexts( pNew );
|
||||
}
|
||||
void Gia_ManTransferTest( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Gia_Rpr_t * pReprs = p->pReprs; // representatives (for CIs and ANDs)
|
||||
int * pNexts = p->pNexts; // next nodes in the equivalence classes
|
||||
Gia_Man_t * pNew = Gia_ManChangeOrder(p);
|
||||
//Gia_ManEquivPrintClasses( p, 1, 0 );
|
||||
assert( Gia_ManObjNum(p) == Gia_ManObjNum(pNew) );
|
||||
Gia_ManTransferEquivs( p, pNew );
|
||||
p->pReprs = NULL;
|
||||
p->pNexts = NULL;
|
||||
// make new point to old
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
assert( !Abc_LitIsCompl(pObj->Value) );
|
||||
Gia_ManObj(pNew, Abc_Lit2Var(pObj->Value))->Value = Abc_Var2Lit(i, 0);
|
||||
}
|
||||
Gia_ManTransferEquivs( pNew, p );
|
||||
//Gia_ManEquivPrintClasses( p, 1, 0 );
|
||||
for ( i = 0; i < Gia_ManObjNum(p); i++ )
|
||||
pReprs[i].fProved = 0;
|
||||
//printf( "%5d : %5d %5d %5d %5d\n", i, *(int*)&p->pReprs[i], *(int*)&pReprs[i], (int)p->pNexts[i], (int)pNexts[i] );
|
||||
if ( memcmp(p->pReprs, pReprs, sizeof(int)*Gia_ManObjNum(p)) )
|
||||
printf( "Verification of reprs failed.\n" );
|
||||
else
|
||||
printf( "Verification of reprs succeeded.\n" );
|
||||
if ( memcmp(p->pNexts, pNexts, sizeof(int)*Gia_ManObjNum(p)) )
|
||||
printf( "Verification of nexts failed.\n" );
|
||||
else
|
||||
printf( "Verification of nexts succeeded.\n" );
|
||||
ABC_FREE( pNew->pReprs );
|
||||
ABC_FREE( pNew->pNexts );
|
||||
ABC_FREE( pReprs );
|
||||
ABC_FREE( pNexts );
|
||||
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*************************************************************
|
||||
|
||||
Synopsis [Converting AIG after SAT sweeping into AIG with choices.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Cec4_ManMarkIndependentClasses_rec( Gia_Man_t * p, int iObj )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
assert( iObj > 0 );
|
||||
if ( Gia_ObjIsTravIdPreviousId(p, iObj) ) // failed
|
||||
return 0;
|
||||
if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) // passed
|
||||
return 1;
|
||||
Gia_ObjSetTravIdCurrentId(p, iObj);
|
||||
pObj = Gia_ManObj( p, iObj );
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
return 1;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
if ( Cec4_ManMarkIndependentClasses_rec( p, Gia_ObjFaninId0(pObj, iObj) ) &&
|
||||
Cec4_ManMarkIndependentClasses_rec( p, Gia_ObjFaninId1(pObj, iObj) ) )
|
||||
return 1;
|
||||
Gia_ObjSetTravIdPreviousId(p, iObj);
|
||||
return 0;
|
||||
}
|
||||
int Cec4_ManMarkIndependentClasses( Gia_Man_t * p, Gia_Man_t * pNew )
|
||||
{
|
||||
int iObjNew, iRepr, iObj, Res, fHaveChoices = 0;
|
||||
Gia_ManCleanMark01(p);
|
||||
Gia_ManForEachClass( p, iRepr )
|
||||
{
|
||||
Gia_ManIncrementTravId( pNew );
|
||||
Gia_ManIncrementTravId( pNew );
|
||||
iObjNew = Abc_Lit2Var( Gia_ManObj(p, iRepr)->Value );
|
||||
Res = Cec4_ManMarkIndependentClasses_rec( pNew, iObjNew );
|
||||
assert( Res == 1 );
|
||||
Gia_ObjSetTravIdPreviousId( pNew, iObjNew );
|
||||
p->pReprs[iRepr].fColorA = 1;
|
||||
Gia_ClassForEachObj1( p, iRepr, iObj )
|
||||
{
|
||||
assert( p->pReprs[iObj].iRepr == (unsigned)iRepr );
|
||||
iObjNew = Abc_Lit2Var( Gia_ManObj(p, iObj)->Value );
|
||||
if ( Cec4_ManMarkIndependentClasses_rec( pNew, iObjNew ) )
|
||||
{
|
||||
p->pReprs[iObj].fColorA = 1;
|
||||
fHaveChoices = 1;
|
||||
}
|
||||
Gia_ObjSetTravIdPreviousId( pNew, iObjNew );
|
||||
}
|
||||
}
|
||||
return fHaveChoices;
|
||||
}
|
||||
int Cec4_ManSatSolverAnd_rec( Gia_Man_t * pCho, Gia_Man_t * p, Gia_Man_t * pNew, int iObj )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int Cec4_ManSatSolverChoices_rec( Gia_Man_t * pCho, Gia_Man_t * p, Gia_Man_t * pNew, int iObj )
|
||||
{
|
||||
if ( !Gia_ObjIsClass(p, iObj) )
|
||||
return Cec4_ManSatSolverAnd_rec( pCho, p, pNew, iObj );
|
||||
else
|
||||
{
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( 100 );
|
||||
int i, iHead, iNext, iRepr = Gia_ObjIsHead(p, iObj) ? iObj : Gia_ObjRepr(p, iObj);
|
||||
Gia_ClassForEachObj( p, iRepr, iObj )
|
||||
if ( p->pReprs[iObj].fColorA )
|
||||
Vec_IntPush( vLits, Cec4_ManSatSolverAnd_rec( pCho, p, pNew, iObj ) );
|
||||
Vec_IntSort( vLits, 1 );
|
||||
iHead = Abc_Lit2Var( Vec_IntEntry(vLits, 0) );
|
||||
if ( Vec_IntSize(vLits) > 1 )
|
||||
{
|
||||
Vec_IntForEachEntryStart( vLits, iNext, i, 1 )
|
||||
{
|
||||
pCho->pSibls[iHead] = Abc_Lit2Var(iNext);
|
||||
iHead = Abc_Lit2Var(iNext);
|
||||
}
|
||||
}
|
||||
return Abc_LitNotCond( Vec_IntEntry(vLits, 0), Gia_ManObj(p, iHead)->fPhase );
|
||||
}
|
||||
}
|
||||
Gia_Man_t * Cec4_ManSatSolverChoices( Gia_Man_t * p, Gia_Man_t * pNew )
|
||||
{
|
||||
Gia_Man_t * pCho;
|
||||
Gia_Obj_t * pObj;
|
||||
int i, DriverId;
|
||||
// mark topologically dependent equivalent nodes
|
||||
if ( !Cec4_ManMarkIndependentClasses( p, pNew ) )
|
||||
return Gia_ManDup( pNew );
|
||||
// rebuild AIG in a different order with choices
|
||||
pCho = Gia_ManStart( Gia_ManObjNum(pNew) );
|
||||
pCho->pName = Abc_UtilStrsav( p->pName );
|
||||
pCho->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
pCho->pSibls = ABC_CALLOC( int, Gia_ManObjNum(pNew) );
|
||||
Gia_ManFillValue(pNew);
|
||||
Gia_ManConst0(pNew)->Value = 0;
|
||||
for ( i = 0; i < Gia_ManCiNum(pNew); i++ )
|
||||
Gia_ManCi(pNew, i)->Value = Gia_ManAppendCi( pCho );
|
||||
Gia_ManForEachCoDriverId( p, DriverId, i )
|
||||
Cec4_ManSatSolverChoices_rec( pCho, p, pNew, DriverId );
|
||||
Gia_ManForEachCo( pNew, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pCho, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManSetRegNum( pCho, Gia_ManRegNum(p) );
|
||||
return pCho;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converting AIG after SAT sweeping into AIG with choices.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManCombSpecReduce( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj, * pRepr; int i, iLit;
|
||||
Vec_Int_t * vXors = Vec_IntAlloc( 100 );
|
||||
Gia_Man_t * pTemp, * pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
assert( p->pReprs && p->pNexts );
|
||||
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||
Gia_ManLevelNum(p);
|
||||
Gia_ManSetPhase(p);
|
||||
Gia_ManFillValue(p);
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi( pNew );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
pRepr = Gia_ObjReprObj( p, i );
|
||||
if ( pRepr && Abc_Lit2Var(pObj->Value) != Abc_Lit2Var(pRepr->Value) )
|
||||
{
|
||||
//if ( Gia_ObjLevel(p, pRepr) > Gia_ObjLevel(p, pObj) + 50 )
|
||||
//printf( "%d %d ", Gia_ObjLevel(p, pRepr), Gia_ObjLevel(p, pObj) );
|
||||
iLit = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase );
|
||||
Vec_IntPush( vXors, Gia_ManHashXor( pNew, pObj->Value, iLit ) );
|
||||
pObj->Value = iLit;
|
||||
}
|
||||
}
|
||||
Gia_ManHashStop( pNew );
|
||||
if ( Vec_IntSize(vXors) == 0 )
|
||||
Vec_IntPush( vXors, 0 );
|
||||
Vec_IntForEachEntry( vXors, iLit, i )
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
Vec_IntFree( vXors );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
pNew = Gia_ManCleanup( pTemp = pNew );
|
||||
Gia_ManStop( pTemp );
|
||||
return pNew;
|
||||
}
|
||||
void Gia_ManCombSpecReduceTest( Gia_Man_t * p, char * pFileName )
|
||||
{
|
||||
Gia_Man_t * pSrm = Gia_ManCombSpecReduce( p );
|
||||
if ( pFileName == NULL )
|
||||
pFileName = "test.aig";
|
||||
Gia_AigerWrite( pSrm, pFileName, 0, 0, 0 );
|
||||
Abc_Print( 1, "Speculatively reduced model was written into file \"%s\".\n", pFileName );
|
||||
Gia_ManStop( pSrm );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -283,6 +283,102 @@ void Gia_ManStaticFanoutStart( Gia_Man_t * p )
|
|||
Vec_IntFree( vCounts );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute the map of all edges.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManStartMappingFanoutMap( Gia_Man_t * p, Vec_Int_t * vFanoutNums )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int i, iOffset = Gia_ManObjNum(p);
|
||||
Vec_Int_t * vEdgeMap = Vec_IntAlloc( 2 * iOffset );
|
||||
Vec_IntFill( vEdgeMap, iOffset, 0 );
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( Vec_IntEntry(vFanoutNums, i) == 0 )
|
||||
continue;
|
||||
Vec_IntWriteEntry( vEdgeMap, i, iOffset );
|
||||
iOffset += Vec_IntEntry( vFanoutNums, i );
|
||||
Vec_IntFillExtra( vEdgeMap, iOffset, 0 );
|
||||
}
|
||||
//printf( "Fanout map is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vEdgeMap)/Gia_ManObjNum(p) );
|
||||
return vEdgeMap;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates static fanout.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
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, Index;
|
||||
assert( p->vFanoutNums == NULL );
|
||||
assert( p->vFanout == NULL );
|
||||
// recompute reference counters
|
||||
pRefsOld = p->pLutRefs; p->pLutRefs = NULL;
|
||||
Gia_ManSetLutRefs(p);
|
||||
p->vFanoutNums = Vec_IntAllocArray( p->pLutRefs, Gia_ManObjNum(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_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 )
|
||||
{
|
||||
iFan = Gia_ObjFaninId0p(p, pObj);
|
||||
pFanin = Gia_ManObj( p, iFan );
|
||||
iFanout = Vec_IntEntry( vCounts, iFan );
|
||||
Gia_ObjSetFanout( p, pFanin, iFanout, pObj );
|
||||
Vec_IntAddToEntry( vCounts, iFan, 1 );
|
||||
}
|
||||
// double-check the current number of fanouts added
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
assert( Vec_IntEntry(vCounts, i) == Gia_ObjFanoutNum(p, pObj) );
|
||||
Vec_IntFree( vCounts );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Deallocates static fanout.]
|
||||
|
|
|
|||
|
|
@ -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) );
|
||||
|
|
@ -460,7 +469,11 @@ Gia_Man_t * Gia_ManPerformFx( Gia_Man_t * p, int nNewNodesMax, int LitCountMax,
|
|||
Vec_Wec_t * vCubes;
|
||||
Vec_Str_t * vCompl;
|
||||
if ( Gia_ManAndNum(p) == 0 )
|
||||
return Gia_ManDup(p);
|
||||
{
|
||||
pNew = Gia_ManDup(p);
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
return pNew;
|
||||
}
|
||||
// abctime clk;
|
||||
assert( Gia_ManHasMapping(p) );
|
||||
// collect information
|
||||
|
|
|
|||
1110
src/aig/gia/giaGen.c
1110
src/aig/gia/giaGen.c
File diff suppressed because it is too large
Load Diff
|
|
@ -814,6 +814,328 @@ int Gia_ManHashDualMiter( Gia_Man_t * p, Vec_Int_t * vOuts )
|
|||
return iRes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create multi-input tree.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int * Gia_ManCollectLiterals( int nVars )
|
||||
{
|
||||
int i, * pRes = ABC_CALLOC( int, nVars );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
pRes[i] = Abc_Var2Lit( i+1, 0 );
|
||||
return pRes;
|
||||
}
|
||||
int * Gia_ManGenZero( int nBits )
|
||||
{
|
||||
return ABC_CALLOC( int, nBits );
|
||||
}
|
||||
int * Gia_ManGenPerm( int nBits )
|
||||
{
|
||||
int i, * pRes = ABC_CALLOC( int, nBits );
|
||||
srand( time(NULL) );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
pRes[i] = i;
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
{
|
||||
int iPerm = rand() % nBits;
|
||||
ABC_SWAP( int, pRes[i], pRes[iPerm] );
|
||||
}
|
||||
return pRes;
|
||||
}
|
||||
int * Gia_ManGenPerm2( int nBits )
|
||||
{
|
||||
int i, * pRes = ABC_CALLOC( int, nBits );
|
||||
srand( time(NULL) );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
pRes[i] = rand() % nBits;
|
||||
return pRes;
|
||||
}
|
||||
int Gia_ManMultiCheck( int * pPerm, int nPerm )
|
||||
{
|
||||
int i;
|
||||
for ( i = 1; i < nPerm; i++ )
|
||||
if ( pPerm[i-1] <= pPerm[i] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
int Gia_ManMultiInputPerm( Gia_Man_t * pNew, int * pVars, int nVars, int * pPerm, int fOr, int fXor )
|
||||
{
|
||||
int fPrint = 1;
|
||||
int i, iLit;
|
||||
if ( fPrint )
|
||||
{
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
printf( "%d ", pPerm[i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
while ( 1 )
|
||||
{
|
||||
for ( i = 1; i < nVars; i++ )
|
||||
if ( pPerm[i-1] >= pPerm[i] )
|
||||
break;
|
||||
if ( i == nVars )
|
||||
break;
|
||||
assert( pPerm[i-1] >= pPerm[i] );
|
||||
if ( pPerm[i-1] > pPerm[i] )
|
||||
{
|
||||
ABC_SWAP( int, pPerm[i-1], pPerm[i] );
|
||||
ABC_SWAP( int, pVars[i-1], pVars[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( pPerm[i-1] == pPerm[i] );
|
||||
pPerm[i-1]++;
|
||||
if ( fXor )
|
||||
pVars[i-1] = Gia_ManHashXor( pNew, pVars[i-1], pVars[i] );
|
||||
else if ( fOr )
|
||||
pVars[i-1] = Gia_ManHashOr( pNew, pVars[i-1], pVars[i] );
|
||||
else
|
||||
pVars[i-1] = Gia_ManHashAnd( pNew, pVars[i-1], pVars[i] );
|
||||
for ( i = i+1; i < nVars; i++ )
|
||||
{
|
||||
pPerm[i-1] = pPerm[i];
|
||||
pVars[i-1] = pVars[i];
|
||||
}
|
||||
nVars--;
|
||||
}
|
||||
if ( fPrint )
|
||||
{
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
printf( "%d ", pPerm[i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
iLit = pVars[0];
|
||||
for ( i = 1; i < nVars; i++ )
|
||||
if ( fXor )
|
||||
iLit = Gia_ManHashXor( pNew, iLit, pVars[i] );
|
||||
else if ( fOr )
|
||||
iLit = Gia_ManHashOr( pNew, iLit, pVars[i] );
|
||||
else
|
||||
iLit = Gia_ManHashAnd( pNew, iLit, pVars[i] );
|
||||
return iLit;
|
||||
}
|
||||
Gia_Man_t * Gia_ManMultiInputTest( int nBits )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
int i, iRes, * pPerm;
|
||||
int * pMulti = Gia_ManCollectLiterals( nBits );
|
||||
pNew = Gia_ManStart( 1000 );
|
||||
pNew->pName = Abc_UtilStrsav( "multi" );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
Gia_ManAppendCi( pNew );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
pPerm = Gia_ManGenPerm2( nBits );
|
||||
//pPerm = Gia_ManGenZero( nBits );
|
||||
iRes = Gia_ManMultiInputPerm( pNew, pMulti, nBits, pPerm, 0, 0 );
|
||||
Gia_ManAppendCo( pNew, iRes );
|
||||
ABC_FREE( pPerm );
|
||||
ABC_FREE( pMulti );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Create MUX tree.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManCube( Gia_Man_t * pNew, int Vars, int nVars, int * pLits )
|
||||
{
|
||||
int i, iLit = 1;
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
iLit = Gia_ManHashAnd( pNew, iLit, Abc_LitNotCond(pLits[i], !((Vars >> i) & 1)) );
|
||||
return iLit;
|
||||
}
|
||||
int Gia_ManMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, int * pData )
|
||||
{
|
||||
int iLit0, iLit1;
|
||||
if ( nCtrl == 0 )
|
||||
return pData[0];
|
||||
iLit0 = Gia_ManMuxTree_rec( pNew, pCtrl, nCtrl-1, pData );
|
||||
iLit1 = Gia_ManMuxTree_rec( pNew, pCtrl, nCtrl-1, pData + (1<<(nCtrl-1)) );
|
||||
return Gia_ManHashMux( pNew, pCtrl[nCtrl-1], iLit1, iLit0 );
|
||||
}
|
||||
void Gia_ManUsePerm( int * pTree, int nBits, int * pPerm )
|
||||
{
|
||||
int fPrint = 0;
|
||||
int i, k, m, nVars = nBits + (1 << nBits);
|
||||
if ( fPrint )
|
||||
{
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
printf( "%d ", pPerm[i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
{
|
||||
for ( k = i+1; k < nBits; k++ )
|
||||
if ( pPerm[i] > pPerm[k] )
|
||||
break;
|
||||
if ( k == nBits )
|
||||
break;
|
||||
assert( pPerm[i] > pPerm[k] );
|
||||
ABC_SWAP( int, pPerm[i], pPerm[k] );
|
||||
ABC_SWAP( int, pTree[i], pTree[k] );
|
||||
for ( m = 0; m < (1 << nBits); m++ )
|
||||
if ( ((m >> i) & 1) && !((m >> k) & 1) )
|
||||
{
|
||||
ABC_SWAP( int, pTree[nBits+m], pTree[nBits+(m^(1<<i)^(1<<k))] );
|
||||
ABC_SWAP( int, pPerm[nBits+m], pPerm[nBits+(m^(1<<i)^(1<<k))] );
|
||||
}
|
||||
}
|
||||
if ( fPrint )
|
||||
{
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
printf( "%d ", pPerm[i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
int Gia_ManFindCond( int * pLits, int nBits, int iLate1, int iLate2 )
|
||||
{
|
||||
int i;
|
||||
assert( iLate1 != iLate2 );
|
||||
for ( i = 0; i < nBits; i++ )
|
||||
if ( (((iLate1 ^ iLate2) >> i) & 1) )
|
||||
return Abc_LitNotCond( pLits[i], (iLate1 >> i) & 1 );
|
||||
return -1;
|
||||
}
|
||||
int Gia_ManLatest( int * pPerm, int nVars, int iPrev1, int iPrev2, int iPrev3 )
|
||||
{
|
||||
int i, Value = -1, iLate = -1;
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
if ( Value < pPerm[i] && i != iPrev1 && i != iPrev2 && i != iPrev3 )
|
||||
{
|
||||
Value = pPerm[i];
|
||||
iLate = i;
|
||||
}
|
||||
return iLate;
|
||||
}
|
||||
int Gia_ManEarliest( int * pPerm, int nVars )
|
||||
{
|
||||
int i, Value = ABC_INFINITY, iLate = -1;
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
if ( Value > pPerm[i] )
|
||||
{
|
||||
Value = pPerm[i];
|
||||
iLate = i;
|
||||
}
|
||||
return iLate;
|
||||
}
|
||||
int Gia_ManDecompOne( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm, int iLate )
|
||||
{
|
||||
int iRes, iData;
|
||||
assert( iLate >= 0 && iLate < (1<<nBits) );
|
||||
iData = pTree[nBits+iLate];
|
||||
pTree[nBits+iLate] = pTree[nBits+(iLate^1)];
|
||||
iRes = Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
|
||||
return Gia_ManHashMux( pNew, Gia_ManCube(pNew, iLate, nBits, pTree), iData, iRes );
|
||||
}
|
||||
int Gia_ManDecompTwo( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm, int iLate1, int iLate2 )
|
||||
{
|
||||
int iRes, iData1, iData2, iData, iCond, iCond2;
|
||||
assert( iLate1 != iLate2 );
|
||||
assert( iLate1 >= 0 && iLate1 < (1<<nBits) );
|
||||
assert( iLate2 >= 0 && iLate2 < (1<<nBits) );
|
||||
iData1 = pTree[nBits+iLate1];
|
||||
iData2 = pTree[nBits+iLate2];
|
||||
pTree[nBits+iLate1] = pTree[nBits+(iLate1^1)];
|
||||
pTree[nBits+iLate2] = pTree[nBits+(iLate2^1)];
|
||||
iRes = Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
|
||||
iCond = Gia_ManHashOr( pNew, Gia_ManCube(pNew, iLate1, nBits, pTree), Gia_ManCube(pNew, iLate2, nBits, pTree) );
|
||||
iCond2 = Gia_ManFindCond( pTree, nBits, iLate1, iLate2 );
|
||||
iData = Gia_ManHashMux( pNew, iCond2, iData2, iData1 );
|
||||
return Gia_ManHashMux( pNew, iCond, iData, iRes );
|
||||
}
|
||||
int Gia_ManDecompThree( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm, int iLate1, int iLate2, int iLate3 )
|
||||
{
|
||||
int iRes, iData1, iData2, iData3, iCube1, iCube2, iCube3, iCtrl0, iCtrl1, iMux10, iMux11;
|
||||
assert( iLate1 != iLate2 );
|
||||
assert( iLate1 != iLate3 );
|
||||
assert( iLate2 != iLate3 );
|
||||
assert( iLate1 >= 0 && iLate1 < (1<<nBits) );
|
||||
assert( iLate2 >= 0 && iLate2 < (1<<nBits) );
|
||||
assert( iLate3 >= 0 && iLate3 < (1<<nBits) );
|
||||
iData1 = pTree[nBits+iLate1];
|
||||
iData2 = pTree[nBits+iLate2];
|
||||
iData3 = pTree[nBits+iLate3];
|
||||
pTree[nBits+iLate1] = pTree[nBits+(iLate1^1)];
|
||||
pTree[nBits+iLate2] = pTree[nBits+(iLate2^1)];
|
||||
pTree[nBits+iLate3] = pTree[nBits+(iLate3^1)];
|
||||
iRes = Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
|
||||
iCube1 = Gia_ManCube( pNew, iLate1, nBits, pTree );
|
||||
iCube2 = Gia_ManCube( pNew, iLate2, nBits, pTree );
|
||||
iCube3 = Gia_ManCube( pNew, iLate3, nBits, pTree );
|
||||
iCtrl0 = Gia_ManHashOr( pNew, iCube1, iCube3 );
|
||||
iCtrl1 = Gia_ManHashOr( pNew, iCube2, iCube3 );
|
||||
iMux10 = Gia_ManHashMux( pNew, iCtrl0, iData1, iRes );
|
||||
iMux11 = Gia_ManHashMux( pNew, iCtrl0, iData3, iData2 );
|
||||
return Gia_ManHashMux( pNew, iCtrl1, iMux11, iMux10 );
|
||||
}
|
||||
int Gia_ManDecomp( Gia_Man_t * pNew, int * pTree, int nBits, int * pPerm )
|
||||
{
|
||||
if ( nBits == 2 )
|
||||
return Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
|
||||
else
|
||||
{
|
||||
int iBase = Gia_ManEarliest( pPerm+nBits, 1<<nBits ), BaseValue = pPerm[nBits+iBase];
|
||||
int iLate1 = Gia_ManLatest( pPerm+nBits, 1<<nBits, -1, -1, -1 );
|
||||
int iLate2 = Gia_ManLatest( pPerm+nBits, 1<<nBits, iLate1, -1, -1 );
|
||||
int iLate3 = Gia_ManLatest( pPerm+nBits, 1<<nBits, iLate1, iLate2, -1 );
|
||||
int iLate4 = Gia_ManLatest( pPerm+nBits, 1<<nBits, iLate1, iLate2, iLate3 );
|
||||
if ( 0 )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < (1<<nBits); i++ )
|
||||
printf( "%d ", pPerm[nBits+i] );
|
||||
printf( "\n" );
|
||||
}
|
||||
if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] > BaseValue && pPerm[nBits+iLate3] > BaseValue && pPerm[nBits+iLate4] == BaseValue )
|
||||
return Gia_ManDecompThree( pNew, pTree, nBits, pPerm, iLate1, iLate2, iLate3 );
|
||||
if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] > BaseValue && pPerm[nBits+iLate3] == BaseValue )
|
||||
return Gia_ManDecompTwo( pNew, pTree, nBits, pPerm, iLate1, iLate2 );
|
||||
if ( pPerm[nBits+iLate1] > BaseValue && pPerm[nBits+iLate2] == BaseValue )
|
||||
return Gia_ManDecompOne( pNew, pTree, nBits, pPerm, iLate1 );
|
||||
return Gia_ManMuxTree_rec( pNew, pTree, nBits, pTree+nBits );
|
||||
}
|
||||
}
|
||||
Gia_Man_t * Gia_ManMuxTreeTest( int nBits )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
int i, iLit, nVars = nBits + (1 << nBits);
|
||||
int * pPerm, * pTree = Gia_ManCollectLiterals( nVars );
|
||||
pNew = Gia_ManStart( 1000 );
|
||||
pNew->pName = Abc_UtilStrsav( "mux_tree" );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
Gia_ManAppendCi( pNew );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
pPerm = Gia_ManGenPerm( nVars );
|
||||
//pPerm = Gia_ManGenZero( nVars );
|
||||
pPerm[nBits+1] = 100;
|
||||
pPerm[nBits+5] = 100;
|
||||
pPerm[nBits+4] = 100;
|
||||
Gia_ManUsePerm( pTree, nBits, pPerm );
|
||||
iLit = Gia_ManDecomp( pNew, pTree, nBits, pPerm );
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
ABC_FREE( pPerm );
|
||||
ABC_FREE( pTree );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -894,7 +894,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn
|
|||
Vec_PtrClear( vTemp );
|
||||
Gia_ManForEachPi( p, pObj, i )
|
||||
Vec_PtrPush( vTemp, pObj );
|
||||
Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue );
|
||||
Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue );
|
||||
// create the result
|
||||
Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i )
|
||||
Vec_IntPush( vCis, Gia_ObjId(p, pObj) );
|
||||
|
|
@ -917,7 +917,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn
|
|||
pObj->Value = Abc_Var2Lit( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) );
|
||||
Vec_PtrPush( vTemp, pObj );
|
||||
}
|
||||
Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue );
|
||||
Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue );
|
||||
Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i )
|
||||
Vec_IntPush( vCos, Gia_ObjId(p, pObj) );
|
||||
}
|
||||
|
|
@ -926,7 +926,7 @@ void Gia_ManFindCaninicalOrder( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAn
|
|||
Vec_PtrClear( vTemp );
|
||||
Gia_ManForEachRo( p, pObj, i )
|
||||
Vec_PtrPush( vTemp, pObj );
|
||||
Vec_PtrSort( vTemp, (int (*)(void))Gia_ObjCompareByValue );
|
||||
Vec_PtrSort( vTemp, (int (*)(const void *, const void *))Gia_ObjCompareByValue );
|
||||
// create the result
|
||||
Vec_PtrForEachEntry( Gia_Obj_t *, vTemp, pObj, i )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ int Gia_Iso2ManUniqify( Gia_Iso2Man_t * p )
|
|||
}
|
||||
Vec_IntShrink( p->vTied, k );
|
||||
// sort singletons
|
||||
Vec_PtrSort( p->vSingles, (int (*)(void))Gia_ObjCompareByValue2 );
|
||||
Vec_PtrSort( p->vSingles, (int (*)(const void *, const void *))Gia_ObjCompareByValue2 );
|
||||
// add them to unique and increment signature
|
||||
Vec_PtrForEachEntry( Gia_Obj_t *, p->vSingles, pObj, i )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -158,6 +158,97 @@ void Gia_Iso3Test( Gia_Man_t * p )
|
|||
Vec_IntFreeP( &vSign );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Wec_t * Gia_Iso4Gia( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Wec_t * vLevs = Gia_ManLevelizeR( p );
|
||||
Vec_Int_t * vLevel; int l;
|
||||
Abc_Random( 1 );
|
||||
Vec_WecForEachLevel( vLevs, vLevel, l )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
unsigned RandC[2] = { Abc_Random(0), Abc_Random(0) };
|
||||
if ( l == 0 )
|
||||
{
|
||||
Gia_ManForEachObjVec( vLevel, p, pObj, i )
|
||||
{
|
||||
assert( Gia_ObjIsCo(pObj) );
|
||||
pObj->Value = Abc_Random(0);
|
||||
Gia_ObjFanin0(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC0(pObj)];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Gia_ManForEachObjVec( vLevel, p, pObj, i ) if ( Gia_ObjIsAnd(pObj) )
|
||||
{
|
||||
Gia_ObjFanin0(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC0(pObj)];
|
||||
Gia_ObjFanin1(pObj)->Value += pObj->Value + RandC[Gia_ObjFaninC1(pObj)];
|
||||
}
|
||||
}
|
||||
}
|
||||
return vLevs;
|
||||
}
|
||||
void Gia_Iso4Test( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Wec_t * vLevs = Gia_Iso4Gia( p );
|
||||
Vec_Int_t * vLevel; int l;
|
||||
Vec_WecForEachLevel( vLevs, vLevel, l )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
printf( "Level %d\n", l );
|
||||
Gia_ManForEachObjVec( vLevel, p, pObj, i )
|
||||
printf( "Obj = %5d. Value = %08x.\n", Gia_ObjId(p, pObj), pObj->Value );
|
||||
}
|
||||
Vec_WecFree( vLevs );
|
||||
}
|
||||
Vec_Int_t * Gia_IsoCollectData( Gia_Man_t * p, Vec_Int_t * vObjs )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
Vec_Int_t * vData = Vec_IntAlloc( Vec_IntSize(vObjs) );
|
||||
Gia_ManForEachObjVec( vObjs, p, pObj, i )
|
||||
Vec_IntPush( vData, pObj->Value );
|
||||
return vData;
|
||||
}
|
||||
void Gia_IsoCompareVecs( Gia_Man_t * pGia0, Vec_Wec_t * vLevs0, Gia_Man_t * pGia1, Vec_Wec_t * vLevs1 )
|
||||
{
|
||||
int i, Common, nLevels = Abc_MinInt( Vec_WecSize(vLevs0), Vec_WecSize(vLevs1) );
|
||||
Gia_ManPrintStats( pGia0, NULL );
|
||||
Gia_ManPrintStats( pGia1, NULL );
|
||||
printf( "Printing %d shared levels:\n", nLevels );
|
||||
for ( i = 0; i < nLevels; i++ )
|
||||
{
|
||||
Vec_Int_t * vLev0 = Vec_WecEntry(vLevs0, i);
|
||||
Vec_Int_t * vLev1 = Vec_WecEntry(vLevs1, i);
|
||||
Vec_Int_t * vData0 = Gia_IsoCollectData( pGia0, vLev0 );
|
||||
Vec_Int_t * vData1 = Gia_IsoCollectData( pGia1, vLev1 );
|
||||
Vec_IntSort( vData0, 0 );
|
||||
Vec_IntSort( vData1, 0 );
|
||||
Common = Vec_IntTwoCountCommon( vData0, vData1 );
|
||||
printf( "Level = %3d. One = %6d. Two = %6d. Common = %6d.\n",
|
||||
i, Vec_IntSize(vData0)-Common, Vec_IntSize(vData1)-Common, Common );
|
||||
Vec_IntFree( vData0 );
|
||||
Vec_IntFree( vData1 );
|
||||
}
|
||||
}
|
||||
void Gia_Iso4TestTwo( Gia_Man_t * pGia0, Gia_Man_t * pGia1 )
|
||||
{
|
||||
Vec_Wec_t * vLevs0 = Gia_Iso4Gia( pGia0 );
|
||||
Vec_Wec_t * vLevs1 = Gia_Iso4Gia( pGia1 );
|
||||
Gia_IsoCompareVecs( pGia0, vLevs0, pGia1, vLevs1 );
|
||||
Vec_WecFree( vLevs0 );
|
||||
Vec_WecFree( vLevs1 );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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
|
||||
1217
src/aig/gia/giaMan.c
1217
src/aig/gia/giaMan.c
File diff suppressed because it is too large
Load Diff
|
|
@ -24,6 +24,7 @@
|
|||
#include "misc/extra/extra.h"
|
||||
#include "sat/cnf/cnf.h"
|
||||
#include "opt/dau/dau.h"
|
||||
#include "bool/kit/kit.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -557,8 +558,8 @@ static inline int Mf_CutComputeTruth6( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_t
|
|||
assert( (int)(t & 1) == 0 );
|
||||
truthId = Vec_MemHashInsert(p->vTtMem, &t);
|
||||
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
|
||||
if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) )
|
||||
Vec_IntPush( &p->vCnfSizes, Abc_Tt6CnfSize(t, pCutR->nLeaves) );
|
||||
if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) )
|
||||
Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt6CnfSize(t, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)&t, pCutR->nLeaves, &p->vCnfMem) );
|
||||
// p->nCutMux += Mf_ManTtIsMux( t );
|
||||
assert( (int)pCutR->nLeaves <= nOldSupp );
|
||||
// Mf_ManTruthCanonicize( &t, pCutR->nLeaves );
|
||||
|
|
@ -588,8 +589,8 @@ static inline int Mf_CutComputeTruth( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_t *
|
|||
//Kit_DsdPrintFromTruth( uTruth, pCutR->nLeaves ), printf("\n" ), printf("\n" );
|
||||
truthId = Vec_MemHashInsert(p->vTtMem, uTruth);
|
||||
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
|
||||
if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
|
||||
Vec_IntPush( &p->vCnfSizes, Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) );
|
||||
if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
|
||||
Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)uTruth, pCutR->nLeaves, &p->vCnfMem) );
|
||||
assert( (int)pCutR->nLeaves <= nOldSupp );
|
||||
return (int)pCutR->nLeaves < nOldSupp;
|
||||
}
|
||||
|
|
@ -612,8 +613,8 @@ static inline int Mf_CutComputeTruthMux6( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut
|
|||
assert( (int)(t & 1) == 0 );
|
||||
truthId = Vec_MemHashInsert(p->vTtMem, &t);
|
||||
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
|
||||
if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) )
|
||||
Vec_IntPush( &p->vCnfSizes, Abc_Tt6CnfSize(t, pCutR->nLeaves) );
|
||||
if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) )
|
||||
Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt6CnfSize(t, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)&t, pCutR->nLeaves, &p->vCnfMem) );
|
||||
assert( (int)pCutR->nLeaves <= nOldSupp );
|
||||
return (int)pCutR->nLeaves < nOldSupp;
|
||||
}
|
||||
|
|
@ -642,8 +643,8 @@ static inline int Mf_CutComputeTruthMux( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_
|
|||
assert( (uTruth[0] & 1) == 0 );
|
||||
truthId = Vec_MemHashInsert(p->vTtMem, uTruth);
|
||||
pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
|
||||
if ( p->pPars->fGenCnf && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
|
||||
Vec_IntPush( &p->vCnfSizes, Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) );
|
||||
if ( (p->pPars->fGenCnf || p->pPars->fGenLit) && truthId == Vec_IntSize(&p->vCnfSizes) && LutSize <= 8 )
|
||||
Vec_IntPush( &p->vCnfSizes, p->pPars->fGenCnf ? Abc_Tt8CnfSize(uTruth, pCutR->nLeaves) : Kit_TruthLitNum((unsigned *)uTruth, pCutR->nLeaves, &p->vCnfMem) );
|
||||
assert( (int)pCutR->nLeaves <= nOldSupp );
|
||||
return (int)pCutR->nLeaves < nOldSupp;
|
||||
}
|
||||
|
|
@ -699,6 +700,8 @@ static inline void Mf_CutPrint( Mf_Man_t * p, Mf_Cut_t * pCut )
|
|||
{
|
||||
if ( p->pPars->fGenCnf )
|
||||
printf( "CNF = %2d ", Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(pCut->iFunc)) );
|
||||
if ( p->pPars->fGenLit )
|
||||
printf( "Lit = %2d ", Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(pCut->iFunc)) );
|
||||
Dau_DsdPrintFromTruth( Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)), pCut->nLeaves );
|
||||
}
|
||||
else
|
||||
|
|
@ -998,7 +1001,7 @@ static inline int Mf_CutArea( Mf_Man_t * p, int nLeaves, int iFunc )
|
|||
{
|
||||
if ( nLeaves < 2 )
|
||||
return 0;
|
||||
if ( p->pPars->fGenCnf )
|
||||
if ( p->pPars->fGenCnf || p->pPars->fGenLit )
|
||||
return Vec_IntEntry(&p->vCnfSizes, Abc_Lit2Var(iFunc));
|
||||
if ( p->pPars->fOptEdge )
|
||||
return nLeaves + p->pPars->nAreaTuner;
|
||||
|
|
@ -1202,7 +1205,7 @@ int Mf_ManSetMapRefs( Mf_Man_t * p )
|
|||
Mf_ObjMapRefInc( p, pCut[k] );
|
||||
p->pPars->Edge += Mf_CutSize(pCut);
|
||||
p->pPars->Area++;
|
||||
if ( p->pPars->fGenCnf )
|
||||
if ( p->pPars->fGenCnf || p->pPars->fGenLit )
|
||||
p->pPars->Clause += Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
|
||||
}
|
||||
// blend references
|
||||
|
|
@ -1394,7 +1397,7 @@ Mf_Man_t * Mf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
p->pLfObjs = ABC_CALLOC( Mf_Obj_t, Gia_ManObjNum(pGia) );
|
||||
p->iCur = 2;
|
||||
Vec_PtrGrow( &p->vPages, 256 );
|
||||
if ( pPars->fGenCnf )
|
||||
if ( pPars->fGenCnf || pPars->fGenLit )
|
||||
{
|
||||
Vec_IntGrow( &p->vCnfSizes, 10000 );
|
||||
Vec_IntPush( &p->vCnfSizes, 1 );
|
||||
|
|
@ -1410,7 +1413,7 @@ Mf_Man_t * Mf_ManAlloc( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
}
|
||||
void Mf_ManFree( Mf_Man_t * p )
|
||||
{
|
||||
assert( !p->pPars->fGenCnf || Vec_IntSize(&p->vCnfSizes) == Vec_MemEntryNum(p->vTtMem) );
|
||||
assert( !p->pPars->fGenCnf || !p->pPars->fGenLit || Vec_IntSize(&p->vCnfSizes) == Vec_MemEntryNum(p->vTtMem) );
|
||||
if ( p->pPars->fCutMin )
|
||||
Vec_MemHashFree( p->vTtMem );
|
||||
if ( p->pPars->fCutMin )
|
||||
|
|
@ -1453,6 +1456,7 @@ void Mf_ManSetDefaultPars( Jf_Par_t * pPars )
|
|||
pPars->fCoarsen = 1;
|
||||
pPars->fCutMin = 0;
|
||||
pPars->fGenCnf = 0;
|
||||
pPars->fGenLit = 0;
|
||||
pPars->fPureAig = 0;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fVeryVerbose = 0;
|
||||
|
|
@ -1469,6 +1473,8 @@ void Mf_ManPrintStats( Mf_Man_t * p, char * pTitle )
|
|||
printf( "Edge =%9lu ", (long)p->pPars->Edge );
|
||||
if ( p->pPars->fGenCnf )
|
||||
printf( "CNF =%9lu ", (long)p->pPars->Clause );
|
||||
if ( p->pPars->fGenLit )
|
||||
printf( "FFL =%9lu ", (long)p->pPars->Clause );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
|
||||
fflush( stdout );
|
||||
}
|
||||
|
|
@ -1483,6 +1489,7 @@ void Mf_ManPrintInit( Mf_Man_t * p )
|
|||
printf( "CutMin = %d ", p->pPars->fCutMin );
|
||||
printf( "Coarse = %d ", p->pPars->fCoarsen );
|
||||
printf( "CNF = %d ", p->pPars->fGenCnf );
|
||||
printf( "FFL = %d ", p->pPars->fGenLit );
|
||||
printf( "\n" );
|
||||
printf( "Computing cuts...\r" );
|
||||
fflush( stdout );
|
||||
|
|
@ -1541,28 +1548,6 @@ void Mf_ManComputeCuts( Mf_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Mf_CutRef2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit )
|
||||
{
|
||||
int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
|
||||
if ( Limit == 0 ) return Count;
|
||||
for ( i = 1; i <= Mf_CutSize(pCut); i++ )
|
||||
{
|
||||
Vec_IntPush( vTemp, pCut[i] );
|
||||
if ( !Mf_ObjMapRefInc(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
|
||||
Count += Mf_CutRef2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 );
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
static inline int Mf_CutAreaDerefed2( Mf_Man_t * p, int * pCut )
|
||||
{
|
||||
int Ela1, iObj, i;
|
||||
Vec_IntClear( &p->vTemp );
|
||||
Ela1 = Mf_CutRef2_rec( p, pCut, &p->vTemp, 8 );
|
||||
Vec_IntForEachEntry( &p->vTemp, iObj, i )
|
||||
Mf_ObjMapRefDec( p, iObj );
|
||||
return Ela1;
|
||||
}
|
||||
|
||||
int Mf_CutRef_rec( Mf_Man_t * p, int * pCut )
|
||||
{
|
||||
int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
|
||||
|
|
@ -1579,6 +1564,13 @@ int Mf_CutDeref_rec( Mf_Man_t * p, int * pCut )
|
|||
Count += Mf_CutDeref_rec( p, Mf_ObjCutBest(p, pCut[i]) );
|
||||
return Count;
|
||||
}
|
||||
static inline int Mf_CutAreaRefed( Mf_Man_t * p, int * pCut )
|
||||
{
|
||||
int Ela1 = Mf_CutDeref_rec( p, pCut );
|
||||
int Ela2 = Mf_CutRef_rec( p, pCut );
|
||||
assert( Ela1 == Ela2 );
|
||||
return Ela1;
|
||||
}
|
||||
static inline int Mf_CutAreaDerefed( Mf_Man_t * p, int * pCut )
|
||||
{
|
||||
int Ela1 = Mf_CutRef_rec( p, pCut );
|
||||
|
|
@ -1586,6 +1578,67 @@ static inline int Mf_CutAreaDerefed( Mf_Man_t * p, int * pCut )
|
|||
assert( Ela1 == Ela2 );
|
||||
return Ela1;
|
||||
}
|
||||
static inline int Mf_CutAreaMffc( Mf_Man_t * p, int iObj )
|
||||
{
|
||||
return Mf_ObjMapRefNum(p, iObj) ?
|
||||
Mf_CutAreaRefed (p, Mf_ObjCutBest(p, iObj)) :
|
||||
Mf_CutAreaDerefed(p, Mf_ObjCutBest(p, iObj));
|
||||
}
|
||||
|
||||
int Mf_CutRef2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit )
|
||||
{
|
||||
int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
|
||||
if ( Limit == 0 ) return Count;
|
||||
for ( i = 1; i <= Mf_CutSize(pCut); i++ )
|
||||
{
|
||||
Vec_IntPush( vTemp, pCut[i] );
|
||||
if ( !Mf_ObjMapRefInc(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
|
||||
Count += Mf_CutRef2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 );
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
int Mf_CutDeref2_rec( Mf_Man_t * p, int * pCut, Vec_Int_t * vTemp, int Limit )
|
||||
{
|
||||
int i, Count = Mf_CutArea(p, Mf_CutSize(pCut), Mf_CutFunc(pCut));
|
||||
if ( Limit == 0 ) return Count;
|
||||
for ( i = 1; i <= Mf_CutSize(pCut); i++ )
|
||||
{
|
||||
Vec_IntPush( vTemp, pCut[i] );
|
||||
if ( !Mf_ObjMapRefDec(p, pCut[i]) && Mf_ManObj(p, pCut[i])->iCutSet )
|
||||
Count += Mf_CutDeref2_rec( p, Mf_ObjCutBest(p, pCut[i]), vTemp, Limit-1 );
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
static inline int Mf_CutAreaRefed2( Mf_Man_t * p, int * pCut )
|
||||
{
|
||||
int Ela1, iObj, i;
|
||||
Vec_IntClear( &p->vTemp );
|
||||
Ela1 = Mf_CutDeref2_rec( p, pCut, &p->vTemp, 8 );
|
||||
Vec_IntForEachEntry( &p->vTemp, iObj, i )
|
||||
Mf_ObjMapRefInc( p, iObj );
|
||||
return Ela1;
|
||||
}
|
||||
static inline int Mf_CutAreaDerefed2( Mf_Man_t * p, int * pCut )
|
||||
{
|
||||
int Ela1, iObj, i;
|
||||
Vec_IntClear( &p->vTemp );
|
||||
Ela1 = Mf_CutRef2_rec( p, pCut, &p->vTemp, 8 );
|
||||
Vec_IntForEachEntry( &p->vTemp, iObj, i )
|
||||
Mf_ObjMapRefDec( p, iObj );
|
||||
return Ela1;
|
||||
}
|
||||
static inline int Mf_CutAreaRefed2Multi( Mf_Man_t * p, int iObj, int ** ppCuts, int nCuts )
|
||||
{
|
||||
int Ela1 = 0, iTemp, i;
|
||||
Vec_IntClear( &p->vTemp );
|
||||
for ( i = 0; i < nCuts; i++ )
|
||||
Ela1 += Mf_CutDeref2_rec( p, ppCuts[i], &p->vTemp, ABC_INFINITY );
|
||||
assert( Mf_ObjMapRefNum(p, iObj) == 0 );
|
||||
Vec_IntForEachEntry( &p->vTemp, iTemp, i )
|
||||
Mf_ObjMapRefInc( p, iTemp );
|
||||
return Ela1;
|
||||
}
|
||||
|
||||
static inline float Mf_CutFlow( Mf_Man_t * p, int * pCut, int * pTime )
|
||||
{
|
||||
Mf_Obj_t * pObj;
|
||||
|
|
@ -1633,6 +1686,120 @@ static inline void Mf_ObjComputeBestCut( Mf_Man_t * p, int iObj )
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Mf_ManMappingFromMapping( Mf_Man_t * p )
|
||||
{
|
||||
Gia_Man_t * pGia = p->pGia0;
|
||||
Gia_Obj_t * pObj;
|
||||
int i, iObj, Count = 0;
|
||||
Vec_Int_t * vMapping = Vec_IntAlloc( 3 * Gia_ManObjNum(pGia) );
|
||||
Vec_IntFill( vMapping, Gia_ManObjNum(pGia), 0 );
|
||||
Gia_ManForEachAnd( pGia, pObj, iObj )
|
||||
if ( Mf_ObjMapRefNum(p, iObj) )
|
||||
{
|
||||
int * pCut = Mf_ObjCutBest(p, iObj);
|
||||
Vec_IntWriteEntry( vMapping, iObj, Vec_IntSize(vMapping) );
|
||||
Vec_IntPush( vMapping, Mf_CutSize(pCut) );
|
||||
for ( i = 1; i <= Mf_CutSize(pCut); i++ )
|
||||
Vec_IntPush( vMapping, pCut[i] );
|
||||
Vec_IntPush( vMapping, iObj );
|
||||
Count++;
|
||||
}
|
||||
assert( pGia->vMapping == NULL );
|
||||
pGia->vMapping = vMapping;
|
||||
printf( "Mapping is %.2fx larger than AIG manager.\n", 1.0*Vec_IntSize(vMapping)/Gia_ManObjNum(pGia) );
|
||||
return Count;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Mf_ManPrintFanoutProfile( Mf_Man_t * p, Vec_Int_t * vFanCounts )
|
||||
{
|
||||
Gia_Man_t * pGia = p->pGia0;
|
||||
int i, Count, nMax = Vec_IntFindMax( vFanCounts );
|
||||
Vec_Int_t * vCounts = Vec_IntStart( nMax + 1 );
|
||||
Vec_IntForEachEntry( vFanCounts, Count, i )
|
||||
if ( Count && Gia_ObjIsAnd(Gia_ManObj(pGia, i)) )
|
||||
Vec_IntAddToEntry( vCounts, Count, 1 );
|
||||
printf( "\nFanout distribution for internal nodes:\n" );
|
||||
Vec_IntForEachEntry( vCounts, Count, i )
|
||||
if ( Count ) printf( "Fanout = %5d : Nodes = %5d.\n", i, Count );
|
||||
printf( "Total nodes with fanout = %d. Max fanout = %d.\n\n", Vec_IntCountPositive(vCounts), nMax );
|
||||
Vec_IntFree( vCounts );
|
||||
}
|
||||
int Mf_ManPrintMfccStats( Mf_Man_t * p, int iObj )
|
||||
{
|
||||
Gia_Man_t * pGia = p->pGia0;
|
||||
int Area;
|
||||
printf( "%5d : Level = %5d Refs = %5d Mffc = %5d\n",
|
||||
iObj, Gia_ObjLevelId(pGia, iObj), Mf_ObjMapRefNum(p, iObj), (Area = Mf_CutAreaMffc(p, iObj)) );
|
||||
return Area;
|
||||
}
|
||||
void Mf_ManOptimizationOne( Mf_Man_t * p, int iObj )
|
||||
{
|
||||
Gia_Man_t * pGia = p->pGia0;
|
||||
int * ppCuts[32], nCuts = 0;
|
||||
int iFanout, i, nAreaSum = 0, nAreaBest = 0;
|
||||
// skip pivots whose MFFC fanouts are pointed to by COs
|
||||
Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
|
||||
if ( Gia_ObjIsCo(Gia_ManObj(pGia, iFanout)) )
|
||||
return;
|
||||
// the pivot is used in the mapping as well as all of its fanouts
|
||||
assert( Mf_ObjMapRefNum(p, iObj) > 1 );
|
||||
Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
|
||||
assert( Mf_ObjMapRefNum(p, iFanout) > 0 );
|
||||
// print this pivot and its fanouts
|
||||
printf( "\nPivot node = %d\n", iObj );
|
||||
printf( "Pivot " ), Mf_ManPrintMfccStats( p, iObj );
|
||||
Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
|
||||
printf( "Node " ), nAreaSum += Mf_ManPrintMfccStats( p, iFanout );
|
||||
// calculate the shared MFFC
|
||||
Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
|
||||
Mf_ObjMapRefInc( p, iFanout );
|
||||
Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
|
||||
ppCuts[nCuts++] = Mf_ObjCutBest( p, iFanout );
|
||||
nAreaBest = Mf_CutAreaRefed2Multi( p, iObj, ppCuts, nCuts );
|
||||
Gia_ObjForEachFanoutStaticId( pGia, iObj, iFanout, i )
|
||||
Mf_ObjMapRefDec( p, iFanout );
|
||||
printf( "Sum of MFFC sizes = %d\n", nAreaSum );
|
||||
printf( "Shared MFFC size = %d\n", nAreaBest );
|
||||
}
|
||||
void Mf_ManOptimization( Mf_Man_t * p )
|
||||
{
|
||||
int nOutMax = 3;
|
||||
Gia_Man_t * pGia = p->pGia0;
|
||||
int i, Count, nNodes = Mf_ManMappingFromMapping( p );
|
||||
Gia_ManLevelNum( 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 )
|
||||
if ( Count >= 2 && Count <= nOutMax && Gia_ObjIsAnd(Gia_ManObj(pGia, i)) )
|
||||
Mf_ManOptimizationOne( p, i );
|
||||
printf( "\nFinished printing individual logic cones.\n" );
|
||||
Gia_ManStaticFanoutStop( pGia );
|
||||
Vec_IntFreeP( &pGia->vMapping );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Technology mappping.]
|
||||
|
|
@ -1656,7 +1823,7 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
{
|
||||
Mf_Man_t * p;
|
||||
Gia_Man_t * pNew, * pCls;
|
||||
if ( pPars->fGenCnf )
|
||||
if ( pPars->fGenCnf || pPars->fGenLit )
|
||||
pPars->fCutMin = 1;
|
||||
if ( Gia_ManHasChoices(pGia) )
|
||||
pPars->fCutMin = 1, pPars->fCoarsen = 0;
|
||||
|
|
@ -1675,6 +1842,7 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
p->fUseEla = 1;
|
||||
for ( ; p->Iter < p->pPars->nRounds + pPars->nRoundsEla; p->Iter++ )
|
||||
Mf_ManComputeMapping( p );
|
||||
//Mf_ManOptimization( p );
|
||||
if ( pPars->fVeryVerbose && pPars->fCutMin )
|
||||
Vec_MemDumpTruthTables( p->vTtMem, Gia_ManName(p->pGia), pPars->nLutSize );
|
||||
if ( pPars->fCutMin )
|
||||
|
|
@ -1685,8 +1853,8 @@ Gia_Man_t * Mf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
|
|||
pNew = Mf_ManDeriveMapping( p );
|
||||
if ( p->pPars->fGenCnf )
|
||||
pGia->pData = Mf_ManDeriveCnf( p, p->pPars->fCnfObjIds, p->pPars->fAddOrCla );
|
||||
// if ( p->pPars->fGenCnf )
|
||||
// Mf_ManProfileTruths( p );
|
||||
//if ( p->pPars->fGenCnf || p->pPars->fGenLit )
|
||||
// Mf_ManProfileTruths( p );
|
||||
Gia_ManMappingVerify( pNew );
|
||||
Mf_ManPrintQuit( p, pNew );
|
||||
Mf_ManFree( p );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -32,6 +32,8 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -57,7 +59,7 @@ int Gia_ObjFromMiniFanin1Copy( Gia_Man_t * pGia, Vec_Int_t * vCopies, Mini_Aig_t
|
|||
int Lit = Mini_AigNodeFanin1( p, Id );
|
||||
return Abc_LitNotCond( Vec_IntEntry(vCopies, Abc_Lit2Var(Lit)), Abc_LitIsCompl(Lit) );
|
||||
}
|
||||
Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies )
|
||||
Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies, int fGiaSimple )
|
||||
{
|
||||
Gia_Man_t * pGia, * pTemp;
|
||||
Vec_Int_t * vCopies;
|
||||
|
|
@ -71,7 +73,10 @@ Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies )
|
|||
vCopies = Vec_IntAlloc( nNodes );
|
||||
Vec_IntPush( vCopies, 0 );
|
||||
// iterate through the objects
|
||||
Gia_ManHashAlloc( pGia );
|
||||
if ( fGiaSimple )
|
||||
pGia->fGiaSimple = fGiaSimple;
|
||||
else
|
||||
Gia_ManHashAlloc( pGia );
|
||||
for ( i = 1; i < nNodes; i++ )
|
||||
{
|
||||
if ( Mini_AigNodeIsPi( p, i ) )
|
||||
|
|
@ -83,17 +88,19 @@ Gia_Man_t * Gia_ManFromMiniAig( Mini_Aig_t * p, Vec_Int_t ** pvCopies )
|
|||
else assert( 0 );
|
||||
Vec_IntPush( vCopies, iGiaLit );
|
||||
}
|
||||
Gia_ManHashStop( pGia );
|
||||
assert( Vec_IntSize(vCopies) == nNodes );
|
||||
if ( pvCopies )
|
||||
*pvCopies = vCopies;
|
||||
else
|
||||
Vec_IntFree( vCopies );
|
||||
Gia_ManSetRegNum( pGia, Mini_AigRegNum(p) );
|
||||
pGia = Gia_ManCleanup( pTemp = pGia );
|
||||
if ( pvCopies )
|
||||
Gia_ManDupRemapLiterals( *pvCopies, pTemp );
|
||||
Gia_ManStop( pTemp );
|
||||
if ( !fGiaSimple )
|
||||
{
|
||||
pGia = Gia_ManCleanup( pTemp = pGia );
|
||||
if ( pvCopies )
|
||||
Gia_ManDupRemapLiterals( *pvCopies, pTemp );
|
||||
Gia_ManStop( pTemp );
|
||||
}
|
||||
return pGia;
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +155,7 @@ void Abc_FrameGiaInputMiniAig( Abc_Frame_t * pAbc, void * p )
|
|||
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
|
||||
Gia_ManStopP( &pAbc->pGiaMiniAig );
|
||||
Vec_IntFreeP( &pAbc->vCopyMiniAig );
|
||||
pGia = Gia_ManFromMiniAig( (Mini_Aig_t *)p, &pAbc->vCopyMiniAig );
|
||||
pGia = Gia_ManFromMiniAig( (Mini_Aig_t *)p, &pAbc->vCopyMiniAig, 0 );
|
||||
Abc_FrameUpdateGia( pAbc, pGia );
|
||||
pAbc->pGiaMiniAig = Gia_ManDup( pGia );
|
||||
// Gia_ManDelete( pGia );
|
||||
|
|
@ -175,13 +182,56 @@ void * Abc_FrameGiaOutputMiniAig( Abc_Frame_t * pAbc )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManReadMiniAig( char * pFileName )
|
||||
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 );
|
||||
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 )
|
||||
|
|
@ -260,6 +310,65 @@ Gia_Man_t * Gia_ManFromMiniLut( Mini_Lut_t * p, Vec_Int_t ** pvCopies )
|
|||
return pGia;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Converts MiniLUT into GIA.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManFromMiniLut2( Mini_Lut_t * p, Vec_Int_t ** pvCopies )
|
||||
{
|
||||
Gia_Man_t * pGia;
|
||||
Vec_Int_t * vCopies;
|
||||
Vec_Int_t * vCover = Vec_IntAlloc( 1000 );
|
||||
Vec_Int_t * vLits = Vec_IntAlloc( 100 );
|
||||
int i, k, Fan, iGiaLit, nNodes;
|
||||
// get the number of nodes
|
||||
nNodes = Mini_LutNodeNum(p);
|
||||
// create ABC network
|
||||
pGia = Gia_ManStart( 3 * nNodes );
|
||||
pGia->pName = Abc_UtilStrsav( "MiniLut" );
|
||||
// create mapping from MiniLUT objects into ABC objects
|
||||
vCopies = Vec_IntAlloc( nNodes );
|
||||
Vec_IntPush( vCopies, 0 );
|
||||
Vec_IntPush( vCopies, 1 );
|
||||
// iterate through the objects
|
||||
pGia->fGiaSimple = 1;
|
||||
for ( i = 2; i < nNodes; i++ )
|
||||
{
|
||||
if ( Mini_LutNodeIsPi( p, i ) )
|
||||
iGiaLit = Gia_ManAppendCi(pGia);
|
||||
else if ( Mini_LutNodeIsPo( p, i ) )
|
||||
iGiaLit = Gia_ManAppendCo(pGia, Vec_IntEntry(vCopies, Mini_LutNodeFanin(p, i, 0)));
|
||||
else if ( Mini_LutNodeIsNode( p, i ) )
|
||||
{
|
||||
unsigned * puTruth = Mini_LutNodeTruth( p, i );
|
||||
Vec_IntClear( vLits );
|
||||
Mini_LutForEachFanin( p, i, Fan, k )
|
||||
Vec_IntPush( vLits, Vec_IntEntry(vCopies, Fan) );
|
||||
iGiaLit = Kit_TruthToGia( pGia, puTruth, Vec_IntSize(vLits), vCover, vLits, 0 );
|
||||
}
|
||||
else assert( 0 );
|
||||
Vec_IntPush( vCopies, iGiaLit );
|
||||
}
|
||||
Vec_IntFree( vCover );
|
||||
Vec_IntFree( vLits );
|
||||
assert( Vec_IntSize(vCopies) == nNodes );
|
||||
if ( pvCopies )
|
||||
*pvCopies = vCopies;
|
||||
else
|
||||
Vec_IntFree( vCopies );
|
||||
Gia_ManSetRegNum( pGia, Mini_LutRegNum(p) );
|
||||
return pGia;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Marks LUTs that should be complemented.]
|
||||
|
|
@ -412,6 +521,15 @@ void Abc_FrameGiaInputMiniLut( Abc_Frame_t * pAbc, void * p )
|
|||
Abc_FrameUpdateGia( pAbc, pGia );
|
||||
// Gia_ManDelete( pGia );
|
||||
}
|
||||
void Abc_FrameGiaInputMiniLut2( Abc_Frame_t * pAbc, void * p )
|
||||
{
|
||||
if ( pAbc == NULL )
|
||||
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
|
||||
Vec_IntFreeP( &pAbc->vCopyMiniLut );
|
||||
Gia_ManStopP( &pAbc->pGiaMiniLut );
|
||||
pAbc->pGiaMiniLut = Gia_ManFromMiniLut2( (Mini_Lut_t *)p, &pAbc->vCopyMiniLut );
|
||||
// Abc_FrameUpdateGia( pAbc, pGia );
|
||||
}
|
||||
void * Abc_FrameGiaOutputMiniLut( Abc_Frame_t * pAbc )
|
||||
{
|
||||
Mini_Lut_t * pRes = NULL;
|
||||
|
|
@ -437,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*************************************************************
|
||||
|
||||
|
|
@ -589,6 +725,56 @@ int * Abc_FrameReadMiniLutNameMapping( Abc_Frame_t * pAbc )
|
|||
Gia_ManStop( pGia );
|
||||
return pRes;
|
||||
}
|
||||
int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc )
|
||||
{
|
||||
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_ManComputeSwitchProbs( pAbc->pGiaMiniLut, 48, 16, 0 );
|
||||
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_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;
|
||||
int i, iObj, * pRes = NULL;
|
||||
if ( pAbc->pGiaMiniAig == NULL )
|
||||
{
|
||||
printf( "GIA derived from MiniAIG is not available.\n" );
|
||||
return NULL;
|
||||
}
|
||||
vSwitching = Gia_ManComputeSwitchProbs( pAbc->pGiaMiniAig, 48, 16, 0 );
|
||||
pRes = ABC_CALLOC( int, Gia_ManCoNum(pAbc->pGiaMiniAig) );
|
||||
Gia_ManForEachCoDriverId( pAbc->pGiaMiniAig, iObj, i )
|
||||
pRes[i] = (int)(10000*Vec_FltEntry( (Vec_Flt_t *)vSwitching, iObj ));
|
||||
Vec_IntFree( vSwitching );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -618,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 )
|
||||
|
|
@ -656,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
|
||||
|
|
@ -797,6 +995,395 @@ void Gia_MiniAigVerify( Abc_Frame_t * pAbc, char * pFileName )
|
|||
Mini_AigStop( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collects supergate for the outputs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_MiniAigSuperGates_rec( Mini_Aig_t * p, int iObj, Vec_Int_t * vRes, Vec_Int_t * vMap )
|
||||
{
|
||||
int iFan0, iFan1;
|
||||
if ( Mini_AigNodeIsPi(p, iObj) )
|
||||
{
|
||||
assert( Vec_IntEntry(vMap, iObj) >= 0 );
|
||||
Vec_IntPush( vRes, Vec_IntEntry(vMap, iObj) );
|
||||
return;
|
||||
}
|
||||
iFan0 = Mini_AigNodeFanin0( p, iObj );
|
||||
iFan1 = Mini_AigNodeFanin1( p, iObj );
|
||||
assert( !Abc_LitIsCompl(iFan0) );
|
||||
assert( !Abc_LitIsCompl(iFan1) );
|
||||
Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan0), vRes, vMap );
|
||||
Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan1), vRes, vMap );
|
||||
}
|
||||
Vec_Wec_t * Gia_MiniAigSuperGates( Mini_Aig_t * p )
|
||||
{
|
||||
Vec_Wec_t * vRes = Vec_WecStart( Mini_AigPoNum(p) );
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( Mini_AigNodeNum(p) );
|
||||
int i, Index = 0;
|
||||
Mini_AigForEachPi( p, i )
|
||||
Vec_IntWriteEntry( vMap, i, Index++ );
|
||||
assert( Index == Mini_AigPiNum(p) );
|
||||
Index = 0;
|
||||
Mini_AigForEachPo( p, i )
|
||||
{
|
||||
int iFan0 = Mini_AigNodeFanin0( p, i );
|
||||
assert( !Abc_LitIsCompl(iFan0) );
|
||||
Gia_MiniAigSuperGates_rec( p, Abc_Lit2Var(iFan0), Vec_WecEntry(vRes, Index++), vMap );
|
||||
}
|
||||
assert( Index == Mini_AigPoNum(p) );
|
||||
Vec_IntFree( vMap );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Transform.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_MiniAigSuperPrintDouble( Vec_Int_t * p, int nPis )
|
||||
{
|
||||
int i, Entry;
|
||||
printf( "\n" );
|
||||
Vec_IntForEachEntry( p, Entry, i )
|
||||
printf( "%d(%d) ", Entry%nPis, Entry/nPis );
|
||||
printf( " Total = %d\n", Vec_IntSize(p) );
|
||||
}
|
||||
int Gia_MiniAigSuperMerge( Vec_Int_t * p, int nPis )
|
||||
{
|
||||
int i, k = 0, This, Prev = -1, fChange = 0;
|
||||
Vec_IntForEachEntry( p, This, i )
|
||||
{
|
||||
if ( Prev == This )
|
||||
{
|
||||
Vec_IntWriteEntry( p, k++, (This/nPis+1)*nPis + This%nPis );
|
||||
Prev = -1;
|
||||
fChange = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Prev != -1 )
|
||||
Vec_IntWriteEntry( p, k++, Prev );
|
||||
Prev = This;
|
||||
}
|
||||
}
|
||||
if ( Prev != -1 )
|
||||
Vec_IntWriteEntry( p, k++, Prev );
|
||||
Vec_IntShrink( p, k );
|
||||
return fChange;
|
||||
}
|
||||
int Gia_MiniAigSuperPreprocess( Mini_Aig_t * p, Vec_Wec_t * vSuper, int nPis, int fVerbose )
|
||||
{
|
||||
Vec_Int_t * vRes;
|
||||
int i, nIters, Multi = 1;
|
||||
Vec_WecForEachLevel( vSuper, vRes, i )
|
||||
{
|
||||
Vec_IntSort( vRes, 0 );
|
||||
if ( fVerbose )
|
||||
printf( "\nOutput %d\n", i );
|
||||
if ( fVerbose )
|
||||
Gia_MiniAigSuperPrintDouble( vRes, nPis );
|
||||
for ( nIters = 1; Gia_MiniAigSuperMerge(vRes, nPis); nIters++ )
|
||||
{
|
||||
if ( fVerbose )
|
||||
Gia_MiniAigSuperPrintDouble( vRes, nPis );
|
||||
}
|
||||
Multi = Abc_MaxInt( Multi, nIters );
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "Multi = %d.\n", Multi );
|
||||
return Multi;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derive AIG.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_MiniAigSuperDeriveGia( Vec_Wec_t * p, int nPis, int Multi )
|
||||
{
|
||||
Gia_Man_t * pNew;
|
||||
Vec_Int_t * vTemp, * vLits = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vDrivers = Vec_IntAlloc(100);
|
||||
int i, k, iObj, iLit, nInputs = nPis*Multi;
|
||||
pNew = Gia_ManStart( 1000 );
|
||||
pNew->pName = Abc_UtilStrsav( "tree" );
|
||||
for ( i = 0; i < nInputs; i++ )
|
||||
Gia_ManAppendCi( pNew );
|
||||
Gia_ManHashAlloc( pNew );
|
||||
Vec_WecForEachLevel( p, vTemp, i )
|
||||
{
|
||||
Vec_IntClear( vLits );
|
||||
Vec_IntForEachEntry( vTemp, iObj, k )
|
||||
{
|
||||
assert( iObj < nInputs );
|
||||
Vec_IntPush( vLits, 2+2*((iObj%nPis)*Multi+iObj/nPis) );
|
||||
}
|
||||
Vec_IntPush( vDrivers, Gia_ManHashAndMulti2(pNew, vLits) );
|
||||
}
|
||||
Gia_ManHashStop( pNew );
|
||||
Vec_IntFree( vLits );
|
||||
Vec_IntForEachEntry( vDrivers, iLit, i )
|
||||
Gia_ManAppendCo( pNew, iLit );
|
||||
Vec_IntFree( vDrivers );
|
||||
return pNew;
|
||||
}
|
||||
Gia_Man_t * Gia_MiniAigSuperDerive( char * pFileName, int fVerbose )
|
||||
{
|
||||
Mini_Aig_t * p = Mini_AigLoad( pFileName );
|
||||
Vec_Wec_t * vSuper = Gia_MiniAigSuperGates( p );
|
||||
int Multi = Gia_MiniAigSuperPreprocess( p, vSuper, Mini_AigPiNum(p), fVerbose );
|
||||
Gia_Man_t * pNew = Gia_MiniAigSuperDeriveGia( vSuper, Mini_AigPiNum(p), Multi );
|
||||
Vec_WecFree( vSuper );
|
||||
Mini_AigStop( p );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Process file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_MiniAigProcessFile()
|
||||
{
|
||||
Vec_Int_t * vTriples = Vec_IntAlloc( 100 );
|
||||
char * pFileName = "test.txt";
|
||||
FILE * pFile = fopen( pFileName, "rb" );
|
||||
if ( pFile == NULL )
|
||||
printf( "Cannot open the file.\n" );
|
||||
else
|
||||
{
|
||||
int nLines = 0, nLinesAll = 0;
|
||||
char * pToken;
|
||||
char Buffer[1000];
|
||||
while ( fgets( Buffer, 1000, pFile ) != NULL )
|
||||
{
|
||||
nLinesAll++;
|
||||
if ( Buffer[0] != '#' )
|
||||
continue;
|
||||
//printf( "%s", Buffer );
|
||||
nLines++;
|
||||
pToken = strtok( Buffer+3, " \r\n\r+=" );
|
||||
while ( pToken )
|
||||
{
|
||||
Vec_IntPush( vTriples, atoi(pToken) );
|
||||
pToken = strtok( NULL, " \r\n\r+=" );
|
||||
}
|
||||
}
|
||||
fclose( pFile );
|
||||
printf( "Collected %d (out of %d) lines.\n", nLines, nLinesAll );
|
||||
printf( "Entries = %d\n", Vec_IntSize(vTriples) );
|
||||
}
|
||||
return vTriples;
|
||||
}
|
||||
void Gia_MiniAigGenerate_rec( Mini_Aig_t * p, Vec_Int_t * vTriples, int iObj, Vec_Int_t * vDefs, Vec_Int_t * vMap )
|
||||
{
|
||||
int Index, Entry0, Entry1, Entry2, Value;
|
||||
if ( Vec_IntEntry(vMap, iObj) >= 0 )
|
||||
return;
|
||||
Index = Vec_IntEntry( vDefs, iObj );
|
||||
Entry0 = Vec_IntEntry( vTriples, 3*Index+0 );
|
||||
Entry1 = Vec_IntEntry( vTriples, 3*Index+1 );
|
||||
Entry2 = Vec_IntEntry( vTriples, 3*Index+2 );
|
||||
Gia_MiniAigGenerate_rec( p, vTriples, Entry1, vDefs, vMap );
|
||||
Gia_MiniAigGenerate_rec( p, vTriples, Entry2, vDefs, vMap );
|
||||
assert( Vec_IntEntry(vMap, Entry1) >= 0 );
|
||||
assert( Vec_IntEntry(vMap, Entry2) >= 0 );
|
||||
Value = Mini_AigAnd( p, Vec_IntEntry(vMap, Entry1), Vec_IntEntry(vMap, Entry2) );
|
||||
Vec_IntWriteEntry( vMap, Entry0, Value );
|
||||
}
|
||||
void Gia_MiniAigGenerateFromFile()
|
||||
{
|
||||
Mini_Aig_t * p = Mini_AigStart();
|
||||
Vec_Int_t * vTriples = Gia_MiniAigProcessFile();
|
||||
Vec_Int_t * vDefs = Vec_IntStartFull( Vec_IntSize(vTriples) );
|
||||
Vec_Int_t * vMap = Vec_IntStartFull( Vec_IntSize(vTriples) );
|
||||
Vec_Int_t * vMapIn = Vec_IntStart( Vec_IntSize(vTriples) );
|
||||
Vec_Int_t * vMapOut = Vec_IntStart( Vec_IntSize(vTriples) );
|
||||
Vec_Int_t * vPis = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vPos = Vec_IntAlloc( 100 );
|
||||
int i, ObjOut, ObjIn;
|
||||
assert( Vec_IntSize(vTriples) % 3 == 0 );
|
||||
for ( i = 0; i < Vec_IntSize(vTriples)/3; i++ )
|
||||
{
|
||||
int Entry0 = Vec_IntEntry(vTriples, 3*i+0);
|
||||
int Entry1 = Vec_IntEntry(vTriples, 3*i+1);
|
||||
int Entry2 = Vec_IntEntry(vTriples, 3*i+2);
|
||||
Vec_IntWriteEntry( vDefs, Entry0, i );
|
||||
Vec_IntAddToEntry( vMapOut, Entry0, 1 );
|
||||
Vec_IntAddToEntry( vMapIn, Entry1, 1 );
|
||||
Vec_IntAddToEntry( vMapIn, Entry2, 1 );
|
||||
}
|
||||
Vec_IntForEachEntryTwo( vMapOut, vMapIn, ObjOut, ObjIn, i )
|
||||
if ( !ObjOut && ObjIn )
|
||||
Vec_IntPush( vPis, i );
|
||||
else if ( ObjOut && !ObjIn )
|
||||
Vec_IntPush( vPos, i );
|
||||
Vec_IntForEachEntry( vPis, ObjIn, i )
|
||||
Vec_IntWriteEntry( vMap, ObjIn, Mini_AigCreatePi(p) );
|
||||
Vec_IntForEachEntry( vPos, ObjOut, i )
|
||||
Gia_MiniAigGenerate_rec( p, vTriples, ObjOut, vDefs, vMap );
|
||||
Vec_IntForEachEntry( vPos, ObjOut, i )
|
||||
{
|
||||
assert( Vec_IntEntry(vMap, ObjOut) >= 0 );
|
||||
Mini_AigCreatePo( p, Vec_IntEntry(vMap, ObjOut) );
|
||||
}
|
||||
Vec_IntFree( vTriples );
|
||||
Vec_IntFree( vDefs );
|
||||
Vec_IntFree( vMap );
|
||||
Vec_IntFree( vMapIn );
|
||||
Vec_IntFree( vMapOut );
|
||||
Vec_IntFree( vPis );
|
||||
Vec_IntFree( vPos );
|
||||
Mini_AigDump( p, "test.miniaig" );
|
||||
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
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaSim5.c]
|
||||
FileName [giaReshape.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Simulation engine.]
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
|
|
@ -14,23 +14,19 @@
|
|||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaSim5.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
#include "base/main/main.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Sim_Init( Abc_Frame_t * pAbc ) {}
|
||||
void Sim_End( Abc_Frame_t * pAbc ) {}
|
||||
void Gia_DatFree( Gia_Dat_t * p ) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -40,12 +36,16 @@ void Gia_DatFree( Gia_Dat_t * p ) {}
|
|||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManReshape1( Gia_Man_t * p, int fUseSimple, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaSim4.c]
|
||||
FileName [giaReshape.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Simulation engine.]
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaSim4.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
Revision [$Id: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
|
@ -35,15 +35,15 @@ ABC_NAMESPACE_IMPL_START
|
|||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fVerbose )
|
||||
Gia_Man_t * Gia_ManReshape2( Gia_Man_t * p, int fUseSimple, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,24 +1,24 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [cbaCba.c]
|
||||
FileName [giaResub3.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Hierarchical word-level netlist.]
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Reading binary representation.]
|
||||
Synopsis [Resubstitution computation.]
|
||||
|
||||
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: giaResub3.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "cba.h"
|
||||
#include "gia.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -41,18 +41,14 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Cba_Man_t * Cba_ManReadCba( char * pFileName )
|
||||
Gia_Man_t * Gia_ManPerformNewResub( Gia_Man_t * p, int nWinCount, int nCutSize, int nProcs, int fVerbose )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
void Cba_ManWriteCba( char * pFileName, Cba_Man_t * p )
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -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 [bacLib.c]
|
||||
FileName [giaSyn.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Hierarchical word-level netlist.]
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Library procedures.]
|
||||
Synopsis [High-effort synthesis.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - November 29, 2014.]
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: bacLib.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 "bac.h"
|
||||
#include "gia.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "sat/glucose/AbcGlucose.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -41,7 +45,11 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
@ -88,7 +88,12 @@ Gia_Man_t * Gia_ManAigSyn2( Gia_Man_t * pInit, int fOldAlgo, int fCoarsen, int f
|
|||
p = Gia_ManDup( pInit );
|
||||
Gia_ManTransferTiming( p, pInit );
|
||||
if ( Gia_ManAndNum(p) == 0 )
|
||||
return p;
|
||||
{
|
||||
pNew = Gia_ManDup(p);
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
Gia_ManStop( p );
|
||||
return pNew;
|
||||
}
|
||||
// delay optimization
|
||||
if ( fDelayMin && p->pManTime == NULL )
|
||||
{
|
||||
|
|
@ -157,7 +162,12 @@ Gia_Man_t * Gia_ManAigSyn3( Gia_Man_t * p, int fVerbose, int fVeryVerbose )
|
|||
pPars->nRelaxRatio = 40;
|
||||
if ( fVerbose ) Gia_ManPrintStats( p, NULL );
|
||||
if ( Gia_ManAndNum(p) == 0 )
|
||||
return Gia_ManDup(p);
|
||||
{
|
||||
pNew = Gia_ManDup(p);
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
//Gia_ManStop( p );
|
||||
return pNew;
|
||||
}
|
||||
// perform balancing
|
||||
pNew = Gia_ManAreaBalance( p, 0, ABC_INFINITY, fVeryVerbose, 0 );
|
||||
if ( fVerbose ) Gia_ManPrintStats( pNew, NULL );
|
||||
|
|
@ -189,7 +199,12 @@ Gia_Man_t * Gia_ManAigSyn4( Gia_Man_t * p, int fVerbose, int fVeryVerbose )
|
|||
pPars->nRelaxRatio = 40;
|
||||
if ( fVerbose ) Gia_ManPrintStats( p, NULL );
|
||||
if ( Gia_ManAndNum(p) == 0 )
|
||||
return Gia_ManDup(p);
|
||||
{
|
||||
pNew = Gia_ManDup(p);
|
||||
Gia_ManTransferTiming( pNew, p );
|
||||
//Gia_ManStop( p );
|
||||
return pNew;
|
||||
}
|
||||
//Gia_ManAigPrintPiLevels( p );
|
||||
// perform balancing
|
||||
pNew = Gia_ManAreaBalance( p, 0, ABC_INFINITY, fVeryVerbose, 0 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -1222,6 +1222,172 @@ int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 )
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManSimOneBit( Gia_Man_t * p, Vec_Int_t * vValues )
|
||||
{
|
||||
Gia_Obj_t * pObj; int k;
|
||||
assert( Vec_IntSize(vValues) == Gia_ManCiNum(p) );
|
||||
|
||||
Gia_ManConst0(p)->fMark0 = 0;
|
||||
Gia_ManForEachCi( p, pObj, k )
|
||||
pObj->fMark0 = Vec_IntEntry(vValues, k);
|
||||
Gia_ManForEachAnd( p, pObj, k )
|
||||
pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
|
||||
Gia_ManForEachCo( p, pObj, k )
|
||||
pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
|
||||
|
||||
Gia_ManForEachCi( p, pObj, k )
|
||||
printf( "%d", k % 10 );
|
||||
printf( "\n" );
|
||||
Gia_ManForEachCi( p, pObj, k )
|
||||
printf( "%d", Vec_IntEntry(vValues, k) );
|
||||
printf( "\n" );
|
||||
|
||||
Gia_ManForEachCo( p, pObj, k )
|
||||
printf( "%d", k % 10 );
|
||||
printf( "\n" );
|
||||
Gia_ManForEachCo( p, pObj, k )
|
||||
printf( "%d", pObj->fMark0 );
|
||||
printf( "\n" );
|
||||
printf( "\n" );
|
||||
}
|
||||
void Gia_ManSimOneBitTest2( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
|
||||
|
||||
Vec_IntWriteEntry( vValues, 0, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntWriteEntry( vValues, 0, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntWriteEntry( vValues, 0, 1 );
|
||||
Vec_IntWriteEntry( vValues, 1, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2+2, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntWriteEntry( vValues, 0, 1 );
|
||||
Vec_IntWriteEntry( vValues, 1, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues)/2, 1 );
|
||||
Vec_IntFillExtra( vValues, Gia_ManCiNum(p), 0 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
|
||||
|
||||
Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
|
||||
|
||||
Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
|
||||
Vec_IntWriteEntry( vValues, 127, 1 );
|
||||
Vec_IntWriteEntry( vValues, 255, 0 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
|
||||
|
||||
Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
|
||||
Vec_IntWriteEntry( vValues, 127, 0 );
|
||||
Vec_IntWriteEntry( vValues, 255, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
|
||||
|
||||
Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
|
||||
Vec_IntWriteEntry( vValues, 127, 0 );
|
||||
Vec_IntWriteEntry( vValues, 255, 0 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Gia_ManCiNum(p), 0 );
|
||||
|
||||
Vec_IntFree( vValues );
|
||||
}
|
||||
void Gia_ManSimOneBitTest3( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
|
||||
|
||||
Vec_IntWriteEntry( vValues, 0, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntWriteEntry( vValues, 0, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntWriteEntry( vValues, 0, 1 );
|
||||
Vec_IntWriteEntry( vValues, 1, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2+2, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-1, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-3, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -1, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -3, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-2, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p)/2-3, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -2, 1 );
|
||||
Vec_IntWriteEntry( vValues, Gia_ManCiNum(p) -3, 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 1 );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
Vec_IntFill( vValues, Vec_IntSize(vValues), 0 );
|
||||
|
||||
Vec_IntFree( vValues );
|
||||
}
|
||||
|
||||
|
||||
void Gia_ManSimOneBitTest( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
|
||||
int i, k;
|
||||
for ( i = 0; i < 10; i++ )
|
||||
{
|
||||
for ( k = 0; k < Vec_IntSize(vValues); k++ )
|
||||
Vec_IntWriteEntry( vValues, k, Vec_IntEntry(vValues, k) ^ (rand()&1) );
|
||||
|
||||
printf( "Values = %d ", Vec_IntSum(vValues) );
|
||||
Gia_ManSimOneBit( p, vValues );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
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
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -736,7 +736,7 @@ Str_Ntk_t * Str_ManNormalizeInt( Gia_Man_t * p, Vec_Wec_t * vGroups, Vec_Int_t *
|
|||
if ( p->vStore == NULL )
|
||||
p->vStore = Vec_IntAlloc( STR_SUPER );
|
||||
Gia_ManFillValue( p );
|
||||
pNtk = Str_NtkCreate( Gia_ManObjNum(p), 1 + Gia_ManCoNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManMuxNum(p) );
|
||||
pNtk = Str_NtkCreate( Gia_ManObjNum(p) + 10000, 1 + Gia_ManCoNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManMuxNum(p) + 10000 );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachObj1( p, pObj, i )
|
||||
{
|
||||
|
|
@ -749,7 +749,7 @@ Str_Ntk_t * Str_ManNormalizeInt( Gia_Man_t * p, Vec_Wec_t * vGroups, Vec_Int_t *
|
|||
pObj->Value = Str_ObjCreate( pNtk, STR_PO, 1, &iFanin );
|
||||
}
|
||||
}
|
||||
assert( pNtk->nObjs <= Gia_ManObjNum(p) );
|
||||
//assert( pNtk->nObjs <= Gia_ManObjNum(p) );
|
||||
return pNtk;
|
||||
}
|
||||
Str_Ntk_t * Str_ManNormalize( Gia_Man_t * p )
|
||||
|
|
@ -859,21 +859,23 @@ static inline void transpose64( word A[64] )
|
|||
static inline int Str_ManNum( Gia_Man_t * p, int iObj ) { return Vec_IntEntry(&p->vCopies, iObj); }
|
||||
static inline void Str_ManSetNum( Gia_Man_t * p, int iObj, int Num ) { Vec_IntWriteEntry(&p->vCopies, iObj, Num); }
|
||||
|
||||
int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay, word Matrix[256], int nLimit )
|
||||
int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay, word * Matrix, int nLimit )
|
||||
{
|
||||
int fVerbose = 0;
|
||||
int Levels[256];
|
||||
int * Levels = NULL;
|
||||
int nSize = Vec_IntSize(vSuper);
|
||||
int Prev = nSize, nLevels = 1;
|
||||
int i, k, iLit, iFanin, nSizeNew;
|
||||
word Mask;
|
||||
assert( nSize > 2 );
|
||||
assert( nSize <= nLimit );
|
||||
if ( nSize > 64 )
|
||||
{
|
||||
for ( i = 0; i < 64; i++ )
|
||||
Matrix[i] = 0;
|
||||
return 0;
|
||||
}
|
||||
Levels = ABC_ALLOC( int, nLimit+256 );
|
||||
// mark current nodes
|
||||
Gia_ManIncrementTravId( p );
|
||||
Vec_IntForEachEntry( vSuper, iLit, i )
|
||||
|
|
@ -948,6 +950,7 @@ int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay
|
|||
if ( nSizeNew == 0 )
|
||||
{
|
||||
Vec_IntShrink( vSuper, nSize );
|
||||
ABC_FREE( Levels );
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
|
|
@ -979,6 +982,7 @@ int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay
|
|||
}
|
||||
i = 0;
|
||||
}
|
||||
ABC_FREE( Levels );
|
||||
Vec_IntShrink( vSuper, nSize );
|
||||
return nSizeNew;
|
||||
}
|
||||
|
|
@ -1088,15 +1092,14 @@ int Str_NtkBalanceTwo( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, int i,
|
|||
|
||||
void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec_Int_t * vDelay, int nLutSize )
|
||||
{
|
||||
word pMatrix[256];
|
||||
int Limit = 256;
|
||||
word * pMatrix = ABC_ALLOC( word, pObj->nFanins+256 );
|
||||
Vec_Int_t * vSuper = pNew->vSuper;
|
||||
Vec_Int_t * vCosts = pNew->vStore;
|
||||
int * pSuper = Vec_IntArray(vSuper);
|
||||
int * pCost = Vec_IntArray(vCosts);
|
||||
int k, iLit, MatrixSize = 0;
|
||||
assert( Limit <= Vec_IntCap(vSuper) );
|
||||
assert( Limit <= Vec_IntCap(vCosts) );
|
||||
assert( (int)pObj->nFanins <= Vec_IntCap(vSuper) );
|
||||
assert( (int)pObj->nFanins <= Vec_IntCap(vCosts) );
|
||||
|
||||
// collect nodes
|
||||
Vec_IntClear( vSuper );
|
||||
|
|
@ -1111,11 +1114,13 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
|
|||
if ( Vec_IntSize(vSuper) == 1 )
|
||||
{
|
||||
pObj->iCopy = Vec_IntEntry(vSuper, 0);
|
||||
ABC_FREE( pMatrix );
|
||||
return;
|
||||
}
|
||||
if ( Vec_IntSize(vSuper) == 2 )
|
||||
{
|
||||
pObj->iCopy = Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, 2, nLutSize, -1 );
|
||||
ABC_FREE( pMatrix );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1127,7 +1132,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
|
|||
|
||||
// compute affinity
|
||||
if ( Vec_IntSize(vSuper) < 64 )
|
||||
MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, Limit );
|
||||
MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, pObj->nFanins );
|
||||
|
||||
// start the new product
|
||||
while ( Vec_IntSize(vSuper) > 2 )
|
||||
|
|
@ -1147,7 +1152,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
|
|||
|
||||
// compute affinity
|
||||
if ( Vec_IntSize(vSuper) == 64 )
|
||||
MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, Limit );
|
||||
MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, pObj->nFanins );
|
||||
assert( Vec_IntSize(vSuper) <= 64 );
|
||||
// Str_PrintState( pCost, pSuper, pMatrix, Vec_IntSize(vSuper) );
|
||||
|
||||
|
|
@ -1236,6 +1241,7 @@ void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec
|
|||
continue;
|
||||
}
|
||||
pObj->iCopy = Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, 2, nLutSize, -1 );
|
||||
ABC_FREE( pMatrix );
|
||||
|
||||
/*
|
||||
// simple
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -388,6 +388,14 @@ Vec_Int_t * Gia_ManComputeCarryOuts( Gia_Man_t * p )
|
|||
Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
|
||||
int i, iLast, iBox, nBoxes = Tim_ManBoxNum( pManTime );
|
||||
Vec_Int_t * vCarryOuts = Vec_IntAlloc( nBoxes );
|
||||
|
||||
// Create and populate reference count (and free later) only if not already
|
||||
// done.
|
||||
int createRefs = (p->pRefs == NULL);
|
||||
if (createRefs) {
|
||||
Gia_ManCreateRefs( p );
|
||||
}
|
||||
|
||||
for ( i = 0; i < nBoxes; i++ )
|
||||
{
|
||||
iLast = Tim_ManBoxInputLast( pManTime, i );
|
||||
|
|
@ -398,9 +406,24 @@ Vec_Int_t * Gia_ManComputeCarryOuts( Gia_Man_t * p )
|
|||
if ( iBox == -1 )
|
||||
continue;
|
||||
assert( Gia_ObjIsCi(pObj) );
|
||||
if ( Gia_ObjCioId(pObj) == Tim_ManBoxOutputLast(pManTime, iBox) )
|
||||
if ( Gia_ObjCioId(pObj) == Tim_ManBoxOutputLast(pManTime, iBox) ) {
|
||||
Vec_IntPush( vCarryOuts, Gia_ObjId(p, pObj) );
|
||||
|
||||
// We have identified a carry connection. Check if the carry out
|
||||
// of the destination box is unconnected. If so then add it to
|
||||
// the carry list as well.
|
||||
iLast = Tim_ManBoxOutputLast(pManTime, i);
|
||||
pObj = Gia_ManCi(p, iLast);
|
||||
if ( Gia_ObjRefNum(p, pObj) == 0 ) {
|
||||
Vec_IntPush( vCarryOuts, Gia_ObjId(p, pObj) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (createRefs) {
|
||||
ABC_FREE( p->pRefs );
|
||||
}
|
||||
|
||||
return vCarryOuts;
|
||||
}
|
||||
|
||||
|
|
@ -446,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 []
|
||||
|
|
@ -460,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 )
|
||||
{
|
||||
|
|
@ -490,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) );
|
||||
|
|
@ -497,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) )
|
||||
|
|
@ -526,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;
|
||||
|
|
@ -542,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;
|
||||
}
|
||||
|
||||
|
|
@ -714,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 );
|
||||
|
|
@ -728,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 );
|
||||
|
|
@ -752,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
|
||||
|
|
@ -118,27 +119,6 @@ word Gia_LutComputeTruth6Map( Gia_Man_t * p, int iPo, Vec_Int_t * vMap )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static unsigned s_Truths5[5] = {
|
||||
0xAAAAAAAA,
|
||||
0xCCCCCCCC,
|
||||
0xF0F0F0F0,
|
||||
0xFF00FF00,
|
||||
0xFFFF0000,
|
||||
};
|
||||
static inline int Abc_Tt5HasVar( unsigned t, int iVar )
|
||||
{
|
||||
return ((t << (1<<iVar)) & s_Truths5[iVar]) != (t & s_Truths5[iVar]);
|
||||
}
|
||||
static inline unsigned Abc_Tt5Cofactor0( unsigned t, int iVar )
|
||||
{
|
||||
assert( iVar >= 0 && iVar < 6 );
|
||||
return (t & ~s_Truths5[iVar]) | ((t & ~s_Truths5[iVar]) << (1<<iVar));
|
||||
}
|
||||
static inline unsigned Abc_Tt5Cofactor1( unsigned t, int iVar )
|
||||
{
|
||||
assert( iVar >= 0 && iVar < 6 );
|
||||
return (t & s_Truths5[iVar]) | ((t & s_Truths5[iVar]) >> (1<<iVar));
|
||||
}
|
||||
int Gia_Truth5ToGia( Gia_Man_t * p, int * pVarLits, int nVars, unsigned Truth, int fHash )
|
||||
{
|
||||
int Var, Lit0, Lit1;
|
||||
|
|
@ -580,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 )
|
||||
{
|
||||
|
|
@ -645,9 +630,18 @@ word * Gia_ObjComputeTruthTableCut( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t
|
|||
{
|
||||
Gia_Obj_t * pTemp;
|
||||
word * pTruth, * pTruthL, * pTruth0, * pTruth1;
|
||||
int i, iObj, Id0, Id1;
|
||||
int i, iObj, Id0, Id1, Index = Vec_IntFind(vLeaves, Gia_ObjId(p, pRoot));
|
||||
assert( p->vTtMemory != NULL );
|
||||
assert( Vec_IntSize(vLeaves) <= p->nTtVars );
|
||||
if ( Index >= 0 )
|
||||
return Gla_ObjTruthElem( p, Index );
|
||||
if ( Gia_ObjIsConst0(pRoot) )
|
||||
{
|
||||
if ( Vec_WrdSize(p->vTtMemory) < p->nTtWords )
|
||||
Vec_WrdFillExtra( p->vTtMemory, p->nTtWords, 0 );
|
||||
return Gla_ObjTruthConst0( p, Gla_ObjTruthFree1(p) );
|
||||
}
|
||||
assert( Gia_ObjIsAnd(pRoot) );
|
||||
// extend ID numbers
|
||||
if ( Vec_IntSize(p->vTtNums) < Gia_ManObjNum(p) )
|
||||
Vec_IntFillExtra( p->vTtNums, Gia_ManObjNum(p), -ABC_INFINITY );
|
||||
|
|
@ -816,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
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue