Version abc60407

This commit is contained in:
Alan Mishchenko 2006-04-07 08:01:00 -07:00
parent 8e5398c501
commit 3f4fc5e450
99 changed files with 238459 additions and 437 deletions

24
abc.dsp
View File

@ -214,6 +214,10 @@ SOURCE=.\src\base\abci\abcFxu.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcGen.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcMap.c
# End Source File
# Begin Source File
@ -262,6 +266,10 @@ SOURCE=.\src\base\abci\abcRewrite.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcRr.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcSat.c
# End Source File
# Begin Source File
@ -282,6 +290,10 @@ SOURCE=.\src\base\abci\abcTiming.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcTrace.c
# End Source File
# Begin Source File
SOURCE=.\src\base\abci\abcUnate.c
# End Source File
# Begin Source File
@ -934,6 +946,10 @@ SOURCE=.\src\sat\asat\asatmem.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\asat\jfront.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\asat\solver.c
# End Source File
# Begin Source File
@ -1310,6 +1326,10 @@ SOURCE=.\src\opt\cut\cutOracle.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\cut\cutPre22.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\cut\cutSeq.c
# End Source File
# Begin Source File
@ -1738,6 +1758,10 @@ SOURCE=.\src\misc\extra\extraUtilReader.c
# End Source File
# Begin Source File
SOURCE=.\src\misc\extra\extraUtilTruth.c
# End Source File
# Begin Source File
SOURCE=.\src\misc\extra\extraUtilUtil.c
# End Source File
# End Group

13
abc.rc
View File

@ -14,6 +14,10 @@ set siswin sis.exe
set sisunix sis
set mvsiswin mvsis.exe
set mvsisunix mvsis
set capowin MetaPl-Capo10.1-Win32.exe
set capounix MetaPl-Capo10.1
set gnuplotwin wgnuplot.exe
set gnuplotunix gnuplot
# standard aliases
alias b balance
@ -60,6 +64,9 @@ alias st strash
alias sw sweep
alias ssw ssweep
alias scl scleanup
alias tr0 trace_start
alias tr1 trace_check
alias trt "r c.blif; st; tr0; b; tr1"
alias u undo
alias wb write_blif
alias wl write_blif
@ -84,10 +91,8 @@ alias shake "st; ps; sat -C 5000; rw -l; ps; sat -C 5000; b -l; rf -l; ps;
# resubstitution scripts for the IWLS paper
alias src_rw "st; rw -l; rwz -l; rwz -l"
alias src_rs1 "st; rs -K 6 -l; rs -K 9 -l; rs -K 12 -l"
alias src_rs2 "st; rs -K 6 -N 2 -l; rs -K 9 -N 2 -l; rs -K 12 -N 2 -l"
alias src_rws1 "st; rw -l; rs -K 6 -l; rwz -l; rs -K 9 -l; rwz -l; rs -K 12 -l"
alias src_rws2 "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 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 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"

2395
examples/C2670.blif Normal file

File diff suppressed because it is too large Load Diff

18772
examples/ac.v Normal file

File diff suppressed because it is too large Load Diff

443
examples/apex4.pla Normal file
View File

@ -0,0 +1,443 @@
.i 9
.o 19
.p 438
010110011 0100000000000000011
100100001 0110000000000000000
100010100 0100010000000000000
100101001 0100001000000000000
001101010 0000001000000001001
00-0-0001 0000000000001011100
110101010 0000000000010100000
010111100 0100000001000000110
011010111 0100000001000000000
010111010 0000110000000000000
110000001 0100000000001010000
0110-0011 0001100000000000000
10011-010 0100000000000000000
101000110 0011000000000000000
100110110 0000101000000000000
101110100 0001100000000000000
111000101 0100000000100000000
100100100 0000000001100000000
111001110 0100000000100000000
111111001 0000000000001100000
001100100 0000000000100110000
001101101 0010000000010100000
-01111101 0100000000000000000
010001110 0100000010100000000
001011111 0000010100000000110
100101110 0100100100000000000
001011011 0000000010010010000
011111000 0010100000000000000
100110100 0000001000001100000
001101110 0000000100010010000
010011100 0000000001000110000
101111101 0000100100000000000
111010000 0100000000000110000
101011010 0000010100000000000
011000001 0000100000000110000
101101101 0000100001000000000
011011011 0001000000010010000
010011111 0000010001000001010
10111111- 0100000000000000000
010101010 0010000001000001001
011101010 0010000000001100000
11011111- 0100000000000000000
111111011 0001100000000000000
001010101 0000010000010101100
001110111 0010000000000111001
1001100-1 0010000000000000000
100100111 0100000000110010000
011101011 0101000001000000000
011011101 0000100000010010000
101110101 0101000001000000000
001110100 0010000000010011001
001110010 0001000110000000000
110011100 0000000000110010000
110101111 0000001000001100000
100111111 0001000110000000000
10-110000 0100000000000010000
101101100 0100001010000000000
010000011 0001000010000110000
-11000011 0001000000000000000
100001101 0000101100000000000
010000010 0000100000110100000
1-0001001 0100100000000000000
001001110 0001010010000001100
001110001 0000100011000000000
00101001- 0000000100000001100
100100010 0010000001100000000
011011110 0001110000000000000
110110000 0000100100001000000
101000101 0000011000001000000
100101111 0101010010000000000
101110110 0100000000110010000
001110000 0000010001100000000
011001110 0100000001000110000
010010100 0000010001100000000
100010010 0001000001001010000
100011000 0000100010000110000
-01001100 0000000000010010000
001001111 0010100010000001100
110111110 0001110000000000000
100110001 0000001110000000000
001100000 0000101000100000101
100110101 0000010011000000000
010010010 0010000000110010000
111100110 0000010000010010000
100-10001 0001100000000000000
100111101 0010010000000110000
011010100 0001000011000000000
101011101 0001100000011000000
010101011 0001001100000001001
110101100 0001100000000110000
110101000 0001010001000000000
001001101 0000101010000001110
110010100 0000110100000000000
011000101 0100000001001101100
111000111 0100001001000000000
001010000 0010000010001101100
100011101 0100011010000000000
1-0110000 0000000000100100000
10000-011 0001000001000000000
001011100 0000000011010010000
101111001 0000000110100000000
0010100-1 0000000010100000000
010001-01 0010000000100000000
110-11011 0000000000010010000
1110-1011 0000010000000000000
1001-1011 0000100000100000000
00110001- 0010000000100000000
100100110 0101000001010010000
101010101 0010000000100110000
-01101011 0001010000000000000
001001000 0000000011100100000
110000100 0000010011000000000
101000-00 0000000010001000000
010011110 0000000111000001100
110111100 0000110001000000000
001101001 0000010100001011010
10011-001 0010000000100000000
0100-0001 0000010010000000000
100111-10 0000100100000000000
110101101 0010001100000000000
001101000 0000001010001101100
-01111011 0001000100000000000
001000-11 0000000011000000000
110000101 0000101000010100000
011100100 0000011001000000000
011100110 0000100001000110000
1011-0000 0010000000010000000
100011011 0010000101001000000
101-00000 0000001000000100000
0011-1111 0000001000100000000
011011100 0010000010010010000
001010111 0001010001100000000
110000010 0010000001011000000
00-000-00 0000000000000010001
0-1100110 0000000010100000000
1001010-0 0000000011000000000
11-001011 0010000000001000000
011111-01 0011000000000000000
01-110100 0010000000100000000
101011001 0000001001001100000
011101110 0000011000011000000
101100001 0000000101000110000
011111011 0010000001011000000
011101100 0100000011100000000
1-1001011 0000000010000010000
-01011010 0000000001100000000
0-1001011 0000001100000000000
0110-0000 0000100010000000000
111001101 0101010010000000000
111000110 0010000011000000000
011-00111 0000100010000000000
01100-011 0000010000100000000
1101-1011 0000001000000010000
-11001010 0001010000000000000
01110011- 0001001000000000000
100011110 0010110001000000000
110001-01 0000100100000000000
011010110 0100000100111000000
100010110 0001000110010100000
100001011 0010110000000110000
110-10010 0000110000000000000
101-01101 0010010000000000000
0-1100111 0000000101000000000
110100-00 0010000000100000000
01001100- 0000000010010010000
110101-10 0010000000100000000
111010100 0000101000001100000
110-11001 0010000000100000000
1100-1100 0010010000000000000
1010101-0 0000010100000000000
100001111 0010010010001100000
11000011- 0001000000000110000
111100011 0000010101000000000
01010111- 0000010000100001001
010111111 0010010110000000000
011110000 0011000010100000000
111110001 0010000000111000000
100100011 0000000111100000000
011100000 0011100001000000000
011111110 0100001101000000000
010110101 0010011010000000000
010100011 0000110010001010000
111111000 0000010101000000000
111111101 0010000000111000000
11101100- 0100000000011000000
011111100 0001110100000000000
001111011 0000101010001100000
-11100001 0010000000100000000
0111-1000 0000001000100000000
100100000 0101110000011000000
010100111 0000100110010100000
101000010 0001011100000000000
11001-010 0000001010000000000
010001000 0010010001001100000
-11110011 0010000000100000000
010100101 0000001011100000000
100--1000 0010000000000000000
010101000 0001001001000110000
010010101 0000100101100000110
111101001 0000001010000110000
111000100 0101000001000110000
011001101 0001100100000110000
001111111 0010010100011000000
1010-1000 0000001001000000000
100101100 0001000101010010000
001110101 0001001110000001001
0100-101- 0000000010000000000
011100101 0000110100100000000
110010001 0001011100000000000
0-110-010 0000100000000000000
111001100 0100100100011000000
101100101 0001000110001100000
10-001-01 0000000000100000000
111111010 0000001001001100000
101111110 0001010010001100000
1-0001-00 0010000000000000000
011001000 0001000110001010000
001--0101 0000000001000000000
010000101 0100101011000000000
011011010 0010011000100000000
110011110 0000111000100000000
001110011 0010001100010010000
111010110 0011110000000000000
11101-111 0010000000100000000
111011-00 0000100100000000000
-01-11111 0000000000100000000
111100111 0001110000100000000
-10011000 0001110000000000000
110001110 0001000110011000000
01011-010 0001000110000000000
-01100001 0001010000100000000
010100100 0000000111011000000
01--00010 0000000100000000000
011011001 0010101001000000000
1101110-1 0000000010010010000
10-10-100 0000010000000000000
--1011000 0000100000000000000
-010-0110 0000000001000000000
10--01011 0000001000000000000
110110100 0001000110011000000
100010011 0100010110011000000
101110010 0000000111100000000
001001100 0000010110001101110
110100001 0010000111000000000
110100011 0010010100001100000
010100-10 0000010100100000000
010100000 0000100101001101001
11101-110 0000001010000000000
1-01010-1 0000000001000000000
001111000 0000001101100001001
00101100- 0010000001100000000
0100010-0 0000001100100000000
010000110 0001110011000000000
001-11110 0000001010100000000
101101111 0101110000010010000
-1-011101 0000000010000000000
00101-101 0000000101100000000
0101-0010 0010011000000000000
10100010- 0000100001010000000
-1011001- 0000000001000000000
10111100- 0100001001000000000
1111-1100 0000001100000000000
10000000- 0000100000110010000
110100101 0000011101000000000
010-01111 0000001110000000000
001010110 0000101000110011111
001111100 0011011100000000000
101100-11 0010100010000000000
11101111- 0000000000110010000
010111011 0011101001000000000
11001-1-1 0000000001000000000
101110111 0010000011010010000
111001001 0000101001100000000
0-1001010 0000000111000000000
100011010 0010101110000000000
01110100- 0011000001000000000
11-111-00 0010000000000000000
11-1-1111 0010000000000000000
110110-10 0010100010000000000
011101101 0000001011001010000
1-110110- 0000010000000000000
0-1001001 0000000100111000000
100100101 0011101000010010000
1-0111011 0100011000010000000
111110010 0010011100000000000
11-010-10 0000001000000000000
111101101 0000101000101100000
010111001 0000111100100000000
011001-01 0010001010000000000
010110001 0001110001011000000
10100000- 0010000000101100000
01110-111 0000110001000000000
111010001 0010000001100110000
1-1101011 0010010000100000000
100-11011 0000010010100100000
100111100 0010100110000110000
111000000 0010000001110010000
100010101 0010011101000000000
01011011- 0000010001010010000
10100101- 0010000000110010000
010010110 0001001101100000101
01111001- 0010000000100110000
-11000010 0000010001100000000
101-10001 0010000000110010000
010000100 0010010101000110000
10-00-100 0010000000100000000
110000111 0010111010000000000
1-00100-0 0010000000100000000
-100-0000 0010000000100000000
011000000 0001011101000000000
011-10011 0000001101000000000
1111011-0 0000100010100000000
-11010011 0000010011000000000
101000111 0010001110100000000
011010001 0001000101101100000
1-1100100 0010000101000000000
010010011 0000000111110010000
001111010 0000110111000001001
111-11010 0000100110000000000
010001011 0000011101011000000
01110001- 0010000001010010000
1010--011 0010000000100000000
010010001 0010001101010010000
110-01011 0000100110000100000
10-011001 0001010110000000000
10-1100-1 0000000001100000000
010001111 0011110001100000000
001111001 0000011011100001001
001110110 0010011101000001001
0101000-1 0001001101000000000
01100-01- 0000101000000000000
110110101 0010101101000000000
010101100 0010011010001101001
11001-01- 0010000000100000000
110001111 0010001010111000000
010110000 0000111010011001001
1-1-00011 0010100000000000000
0101101-0 0000111100000000000
011010101 0010000011111000000
110010110 0010000110110010000
11-01-101 0001000100000000000
101--0100 0010001000000000000
001010100 0000001011111001100
10-000101 0010100101000000000
101111010 0000101001100110000
101-01000 0001010110000000000
111011001 0000111010100000000
1010--110 0000001100000000000
01-000110 0010001100100000000
101010010 0010000111010010000
11-10-010 0010000000100000000
1011--011 0000010001000000000
110110011 0010011100011000000
110001010 0100111010001100000
01011-110 0001001010010010000
110-10111 0001010110000000000
100011111 0001111000111000000
10100111- 0000111000100000000
11111111- 0010001000011000000
00-0000-- 0000000000000110001
100111000 0001111010011000000
011000100 0011101110000000000
-1100101- 0000000101000000000
0110-1111 0010001100100000000
111100000 0001011100010010000
011111111 0011111000100000000
1111-100- 0010000000100000000
100-01010 0100001101100000000
010010111 0010011101100000000
1101-1000 0000101110000000000
111010101 0010001001101100000
110010-11 0000101011000000000
1-1100001 0000111010000000000
111000001 0000000111110010000
1100--0-0 0000000000100000000
011001100 0001111000110100000
001111110 0010110101001010000
1010-100- 0001110000000000000
111110000 0010000111001010000
100010111 0010101101000110000
011110101 0001111101000000000
01111110- 0000001011100000000
-1--00011 0000001000000000000
011111010 0011010110011000000
101010111 0000111011100000000
010111101 0010011100110010000
-11-01-11 0000000000100000000
111110100 0000011101010100000
010101001 0010001111000110000
1-1011-1- 0010000000000000000
011110001 0011011100010100000
100000111 0000011111010010000
101111100 0010010111100000000
110100111 0001111001011000000
101100010 0001011011000110000
111100-10 0000101011000000000
101101001 0010101110011000000
10-000011 0000111010100000000
11001010- 0010001001010010000
101100110 0010101101001100000
101-01110 0001111000100000000
011010010 0010001101101100000
10-001110 0001011011000000000
10000-000 0001011100010010000
110-11101 0001111000100000000
101011100 0000101111001010000
1-0000110 0010001101100000000
100011100 0011011001101100000
111110110 0001111001000110000
0110111-1 0001011101000000000
010000111 0001001111101100000
11011000- 0001011011000000000
101010000 0001101111100000000
100110111 0011001101101010000
1101-1001 0010010101100000000
111100101 0010001110110010000
110011111 0001101110100110000
100101101 0010010111110010000
111001000 0100001111101100000
0010001-- 0000000011011101110
010111000 0000011111110010000
1-0000000 0001101111000000000
110111010 0011011001110010000
101101010 0010010111111000000
011110111 0010101111001100000
110100110 0000111011101010000
111110111 0001111111000000000
01-011000 0001011111000000000
00-00-0-- 0000000000011001110
11110-1-0 0001001101000000000
111110101 0000111011100110000
001101100 0010011111111000000
010101101 0001111111001101001
010001100 0000111111111000011
111001111 0011101111010100000
1000000-0 0000111111010010000
011110110 0001111111101100000
000------ 0000000000011111111
.e

1867
examples/frg2.blif Normal file

File diff suppressed because it is too large Load Diff

5679
examples/i10.blif Normal file

File diff suppressed because it is too large Load Diff

120216
examples/pj1.blif Normal file

File diff suppressed because it is too large Load Diff

48956
examples/s38417.blif Normal file

File diff suppressed because it is too large Load Diff

21008
examples/s38584.bench Normal file

File diff suppressed because it is too large Load Diff

353
examples/s444.blif Normal file
View File

@ -0,0 +1,353 @@
.model s444
.inputs G0 G1 G2
.outputs G118 G167 G107 G119 G168 G108
.latch G11_in G11 0
.latch G12_in G12 0
.latch G13_in G13 0
.latch G14_in G14 0
.latch G15_in G15 0
.latch G16_in G16 0
.latch G17_in G17 0
.latch G18_in G18 0
.latch G19_in G19 0
.latch G20_in G20 0
.latch G21_in G21 0
.latch G22_in G22 0
.latch G23_in G23 0
.latch G24_in G24 0
.latch G25_in G25 0
.latch G26_in G26 0
.latch G27_in G27 0
.latch G28_in G28 0
.latch G29_in G29 0
.latch G30_in G30 0
.latch G31_in G31 0
.names G12 G13 [25]
00 1
.names G11 [25] [26]
01 1
.names G14 [26] [27]
10 1
.names G0 G11 [28]
00 1
.names [27] [28] G11_in
01 1
.names G11 G12 [30]
11 1
.names G12 [30] [31]
10 1
.names G11 [30] [32]
10 1
.names [31] [32] [33]
00 1
.names G0 [33] [34]
00 1
.names [27] [34] G12_in
01 1
.names G13 [30] [36]
11 1
.names G13 [36] [37]
10 1
.names [30] [36] [38]
10 1
.names [37] [38] [39]
00 1
.names G0 [39] [40]
00 1
.names [27] [40] G13_in
01 1
.names G12 G13 [42]
11 1
.names G11 [42] [43]
11 1
.names G14 [43] [44]
11 1
.names G14 [44] [45]
10 1
.names [43] [44] [46]
10 1
.names [45] [46] [47]
00 1
.names G0 [47] [48]
00 1
.names [27] [48] G14_in
01 1
.names G31 [27] [50]
00 1
.names G16 G17 [51]
00 1
.names G15 [51] [52]
01 1
.names [50] [52] [53]
00 1
.names G18 [53] [54]
11 1
.names G15 [50] [55]
10 1
.names G15 [55] [56]
10 1
.names [50] [55] [57]
00 1
.names [56] [57] [58]
00 1
.names G0 [58] [59]
00 1
.names [54] [59] G15_in
01 1
.names G16 [55] [61]
11 1
.names G16 [61] [62]
10 1
.names [55] [61] [63]
10 1
.names [62] [63] [64]
00 1
.names G0 [64] [65]
00 1
.names [54] [65] G16_in
01 1
.names G16 [50] [67]
10 1
.names G15 [67] [68]
11 1
.names G17 [68] [69]
11 1
.names G17 [69] [70]
10 1
.names [68] [69] [71]
10 1
.names [70] [71] [72]
00 1
.names G0 [72] [73]
00 1
.names [54] [73] G17_in
01 1
.names G15 G16 [75]
11 1
.names G17 [50] [76]
10 1
.names [75] [76] [77]
11 1
.names G18 [77] [78]
11 1
.names G18 [78] [79]
10 1
.names [77] [78] [80]
10 1
.names [79] [80] [81]
00 1
.names G0 [81] [82]
00 1
.names [54] [82] G18_in
01 1
.names G20 G21 [84]
00 1
.names G19 [84] [85]
01 1
.names [54] [85] [86]
10 1
.names G22 [86] [87]
11 1
.names G19 [54] [88]
11 1
.names G19 [88] [89]
10 1
.names [54] [88] [90]
10 1
.names [89] [90] [91]
00 1
.names G0 [91] [92]
00 1
.names [87] [92] G19_in
01 1
.names G20 [88] [94]
11 1
.names G20 [94] [95]
10 1
.names [88] [94] [96]
10 1
.names [95] [96] [97]
00 1
.names G0 [97] [98]
00 1
.names [87] [98] G20_in
01 1
.names G20 [54] [100]
11 1
.names G19 [100] [101]
11 1
.names G21 [101] [102]
11 1
.names G21 [102] [103]
10 1
.names [101] [102] [104]
10 1
.names [103] [104] [105]
00 1
.names G0 [105] [106]
00 1
.names [87] [106] G21_in
01 1
.names G19 G20 [108]
11 1
.names G21 [54] [109]
11 1
.names [108] [109] [110]
11 1
.names G22 [110] [111]
11 1
.names G22 [111] [112]
10 1
.names [110] [111] [113]
10 1
.names [112] [113] [114]
00 1
.names G0 [114] [115]
00 1
.names [87] [115] G22_in
01 1
.names G2 G23 [117]
00 1
.names G2 G23 [118]
11 1
.names [117] [118] [119]
00 1
.names G0 [119] G23_in
01 1
.names G20 G21 [121]
01 1
.names G0 G23 [122]
01 1
.names [121] [122] [123]
11 1
.names G19 [123] [124]
01 1
.names G21 G22 [126]
10 1
.names G19 G20 [125]
10 1
.names G23 [125] [127]
01 1
.names [126] [127] [128]
11 1
.names G0 G24 [129]
01 1
.names [128] [129] [130]
01 1
.names [124] [130] [131]
00 1
.names G22 G23 [132]
00 1
.names [125] [132] [133]
11 1
.names G24 [133] [134]
10 1
.names G19 G20 [135]
00 1
.names G23 [135] [136]
11 1
.names G22 G23 [137]
11 1
.names [136] [137] [138]
00 1
.names G0 G21 [139]
01 1
.names [138] [139] [140]
11 1
.names [134] [140] G25_in
01 1
.names G19 G22 [142]
01 1
.names G0 [142] [143]
01 1
.names G0 [108] [144]
01 1
.names [143] [144] [145]
00 1
.names [129] [139] [146]
00 1
.names [145] [146] G26_in
11 1
.names G21 G24 [148]
00 1
.names [125] [148] [149]
11 1
.names G21 G22 [150]
00 1
.names G24 [150] [151]
01 1
.names G0 [151] [152]
00 1
.names [149] [152] [153]
01 1
.names G0 G22 [154]
01 1
.names [135] [154] [155]
11 1
.names [146] [155] [156]
10 1
.names [131] [156] [157]
00 1
.names G17 [157] [158]
01 1
.names [131] [156] [159]
10 1
.names [158] [159] G28_in
00 1
.names [122] [126] [161]
11 1
.names G21 G22 [162]
01 1
.names G0 [162] [163]
01 1
.names [161] [163] [164]
00 1
.names G20 [164] [165]
00 1
.names G19 [165] [166]
01 1
.names [130] [166] [167]
00 1
.names [131] [167] [168]
00 1
.names G17 [168] [169]
01 1
.names [131] [167] [170]
10 1
.names [169] [170] G29_in
00 1
.names G20 G21 [172]
10 1
.names G0 G24 [173]
00 1
.names [172] [173] [174]
11 1
.names G19 [174] G30_in
11 1
.names G1 G31 [176]
00 1
.names G1 G31 [177]
11 1
.names [176] [177] [178]
00 1
.names G0 [178] G31_in
01 1
.names [131] G24_in
0 1
.names [153] G27_in
0 1
.names G27 G118
1 1
.names G29 G167
0 1
.names G25 G107
1 1
.names G28 G119
0 1
.names G30 G168
1 1
.names G26 G108
1 1
.end

6138
examples/s5378.blif Normal file

File diff suppressed because it is too large Load Diff

6413
examples/s6669.blif Normal file

File diff suppressed because it is too large Load Diff

View File

@ -154,6 +154,7 @@ struct Abc_Ntk_t_
Abc_NtkFunc_t ntkFunc; // functionality of the network
char * pName; // the network name
char * pSpec; // the name of the spec file if present
int Id; // network ID
// name representation
stmm_table * tName2Net; // the table hashing net names into net pointer
stmm_table * tObj2Name; // the table hashing PI/PO/latch pointers into names
@ -210,7 +211,7 @@ struct Abc_Ntk_t_
// maximum/minimum operators
#define ABC_MIN(a,b) (((a) < (b))? (a) : (b))
#define ABC_MAX(a,b) (((a) > (b))? (a) : (b))
#define ABC_INFINITY (10000000)
#define ABC_INFINITY (100000000)
// transforming floats into ints and back
static inline int Abc_Float2Int( float Val ) { return *((int *)&Val); }
@ -439,10 +440,10 @@ extern bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk );
extern bool Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj );
extern bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
/*=== abcCollapse.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fVerbose );
extern Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose );
/*=== abcCut.c ==========================================================*/
extern void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fMulti );
extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fMulti );
extern void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree );
extern void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree );
extern void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fFirst );
extern void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj );
extern void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj );
@ -492,6 +493,8 @@ extern int Abc_NtkRemoveDupFanins( Abc_Ntk_t * pNtk );
extern int Abc_NodeRemoveDupFanins( Abc_Obj_t * pNode );
/*=== abcMiter.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
extern Abc_Ntk_t * Abc_NtkMiterAnd( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
extern Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues );
extern Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In2 );
extern Abc_Ntk_t * Abc_NtkMiterQuantify( Abc_Ntk_t * pNtk, int In, int fExist );
extern Abc_Ntk_t * Abc_NtkMiterQuantifyPis( Abc_Ntk_t * pNtk );
@ -554,7 +557,7 @@ extern Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk );
/*=== abcNtbdd.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi );
extern Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk );
extern DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fLatchOnly );
extern DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fLatchOnly, int fReorder, int fVerbose );
extern void Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk );
/*=== abcNtk.c ==========================================================*/
extern Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func );
@ -584,7 +587,7 @@ extern void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode,
extern void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes );
extern void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode );
/*=== abcProve.c ==========================================================*/
extern int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, int nConfLimit, int nImpLimit, int fUseRewrite, int fUseFraig, int fVerbose );
extern int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pParams );
/*=== abcReconv.c ==========================================================*/
extern Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax, int nNodeFanStop, int nConeFanStop );
extern void Abc_NtkManCutStop( Abc_ManCut_t * p );
@ -607,8 +610,8 @@ extern int Abc_NodeRef_rec( Abc_Obj_t * pNode );
extern Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple, int fFactor );
extern DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld );
/*=== abcSat.c ==========================================================*/
extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fVerbose );
extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk );
extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFront, int fVerbose );
extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fJFront );
/*=== abcSop.c ==========================================================*/
extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName );
extern char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars );
@ -623,6 +626,7 @@ extern char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars );
extern char * Abc_SopCreateMux( Extra_MmFlex_t * pMan );
extern char * Abc_SopCreateInv( Extra_MmFlex_t * pMan );
extern char * Abc_SopCreateBuf( Extra_MmFlex_t * pMan );
extern int Abc_SopGetCubeNum( char * pSop );
@ -672,6 +676,19 @@ extern void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk );
extern void Abc_NodeSetReverseLevel( Abc_Obj_t * pObj, int LevelR );
extern int Abc_NodeReadReverseLevel( Abc_Obj_t * pObj );
extern int Abc_NodeReadRequiredLevel( Abc_Obj_t * pObj );
/*=== abcTrace.c ==========================================================*/
extern void Abc_HManStart();
extern void Abc_HManStop();
extern int Abc_HManIsRunning();
extern int Abc_HManGetNewNtkId();
extern void Abc_HManAddObj( Abc_Obj_t * pObj );
extern void Abc_HManAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin );
extern void Abc_HManXorFaninC( Abc_Obj_t * pObj, int iFanin );
extern void Abc_HManRemoveFanins( Abc_Obj_t * pObj );
extern void Abc_HManAddProto( Abc_Obj_t * pObj, Abc_Obj_t * pProto );
extern void Abc_HManMapAddEqu( Abc_Obj_t * pObj, Abc_Obj_t * pEqu );
extern int Abc_HManPopulate( Abc_Ntk_t * pNtk );
extern int Abc_HManVerify( int NtkIdOld, int NtkIdNew );
/*=== abcUtil.c ==========================================================*/
extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk );

View File

@ -807,6 +807,7 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i
Abc_AigAndDelete( pMan, pFanout );
// remove the fanins of the old fanout
Abc_ObjRemoveFanins( pFanout );
Abc_HManRemoveFanins( pFanout );
// recreate the old fanout with new fanins and add it to the table
Abc_AigAndCreateFrom( pMan, pFanin1, pFanin2, pFanout );
assert( Abc_AigNodeIsAcyclic(pFanout, pFanout) );

View File

@ -50,6 +50,7 @@ void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninR->vFanouts, pObj->Id );
if ( Abc_ObjIsComplement(pFanin) )
Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 );
Abc_HManAddFanin( pObj, pFanin );
}

View File

@ -24,6 +24,8 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define ABC_MUX_CUBES 100000
static int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase );
////////////////////////////////////////////////////////////////////////
@ -205,6 +207,7 @@ void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk )
int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect )
{
Abc_Obj_t * pNode;
Extra_MmFlex_t * pManNew;
DdManager * dd = pNtk->pManFunc;
DdNode * bFunc;
Vec_Str_t * vCube;
@ -217,10 +220,8 @@ int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect )
assert( Abc_NtkIsBddLogic(pNtk) );
Cudd_zddVarsFromBddVars( dd, 2 );
// allocate the new manager
pNtk->pManFunc = Extra_MmFlexStart();
// update the network type
pNtk->ntkFunc = ABC_FUNC_SOP;
// create the new manager
pManNew = Extra_MmFlexStart();
// go through the objects
vCube = Vec_StrAlloc( 100 );
@ -228,17 +229,30 @@ int Abc_NtkBddToSop( Abc_Ntk_t * pNtk, int fDirect )
{
assert( pNode->pData );
bFunc = pNode->pData;
pNode->pData = Abc_ConvertBddToSop( pNtk->pManFunc, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), vCube, fMode );
if ( pNode->pData == NULL )
pNode->pNext = (Abc_Obj_t *)Abc_ConvertBddToSop( pManNew, dd, bFunc, bFunc, Abc_ObjFaninNum(pNode), vCube, fMode );
if ( pNode->pNext == NULL )
{
Extra_MmFlexStop( pManNew, 0 );
Abc_NtkCleanNext( pNtk );
// printf( "Converting from BDDs to SOPs has failed.\n" );
Vec_StrFree( vCube );
Cudd_Quit( dd );
return 0;
}
Cudd_RecursiveDeref( dd, bFunc );
}
Vec_StrFree( vCube );
// update the network type
pNtk->ntkFunc = ABC_FUNC_SOP;
// set the new manager
pNtk->pManFunc = pManNew;
// transfer from next to data
Abc_NtkForEachNode( pNtk, pNode, i )
{
Cudd_RecursiveDeref( dd, pNode->pData );
pNode->pData = pNode->pNext;
pNode->pNext = NULL;
}
// check for remaining references in the package
Extra_StopManager( dd );
return 1;
@ -339,6 +353,13 @@ char * Abc_ConvertBddToSop( Extra_MmFlex_t * pMan, DdManager * dd, DdNode * bFun
assert( 0 );
}
if ( nCubes > ABC_MUX_CUBES )
{
Cudd_RecursiveDerefZdd( dd, zCover );
printf( "The number of cubes exceeded the predefined limit (%d).\n", ABC_MUX_CUBES );
return NULL;
}
// allocate memory for the cover
if ( pMan )
pSop = Extra_MmFlexEntryFetch( pMan, (nFanins + 3) * nCubes + 1 );
@ -468,6 +489,8 @@ void Abc_CountZddCubes_rec( DdManager * dd, DdNode * zCover, int * pnCubes )
(*pnCubes)++;
return;
}
if ( (*pnCubes) > ABC_MUX_CUBES )
return;
extraDecomposeCover( dd, zCover, &zC0, &zC1, &zC2 );
Abc_CountZddCubes_rec( dd, zC0, pnCubes );
Abc_CountZddCubes_rec( dd, zC1, pnCubes );

View File

@ -62,7 +62,7 @@ Abc_Ntk_t * Abc_NtkNetlistToLogic( Abc_Ntk_t * pNtk )
Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pFanin)->pCopy );
// collect the CO nodes
Abc_NtkFinalize( pNtk, pNtkNew );
// fix the problem with CO pointing directing to CIs
// fix the problem with CO pointing directly to CIs
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
// duplicate EXDC
if ( pNtk->pExdc )
@ -101,7 +101,8 @@ Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk, int fDirect )
}
else if ( Abc_NtkIsBddLogic(pNtk) )
{
Abc_NtkBddToSop(pNtk, fDirect);
if ( !Abc_NtkBddToSop(pNtk, fDirect) )
return NULL;
pNtkNew = Abc_NtkLogicSopToNetlist( pNtk );
Abc_NtkSopToBdd(pNtk);
}
@ -157,7 +158,10 @@ Abc_Ntk_t * Abc_NtkLogicSopToNetlist( Abc_Ntk_t * pNtk )
assert( Abc_NtkLogicHasSimpleCos(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
Abc_NtkBddToSop(pNtk,0);
{
if ( !Abc_NtkBddToSop(pNtk,0) )
return NULL;
}
// start the netlist by creating PI/PO/Latch objects
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST, pNtk->ntkFunc );

View File

@ -50,6 +50,7 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func )
memset( pNtk, 0, sizeof(Abc_Ntk_t) );
pNtk->ntkType = Type;
pNtk->ntkFunc = Func;
pNtk->Id = !Abc_HManIsRunning()? 0 : Abc_HManGetNewNtkId();
// start the object storage
pNtk->vObjs = Vec_PtrAlloc( 100 );
pNtk->vLats = Vec_PtrAlloc( 100 );
@ -136,6 +137,14 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
Vec_PtrPush( pNtkNew->vCis, pObjNew );
Vec_PtrPush( pNtkNew->vCos, pObjNew );
}
if ( Abc_NtkIsStrash(pNtk) && Abc_HManIsRunning() )
{
Abc_HManAddProto( Abc_NtkConst1(pNtk)->pCopy, Abc_NtkConst1(pNtk) );
Abc_NtkForEachCi( pNtk, pObj, i )
Abc_HManAddProto( pObj->pCopy, pObj );
Abc_NtkForEachCo( pNtk, pObj, i )
Abc_HManAddProto( pObj->pCopy, pObj );
}
// transfer the names
Abc_NtkDupCioNamesTable( pNtk, pNtkNew );
Abc_ManTimeDup( pNtk, pNtkNew );
@ -407,6 +416,11 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
}
if ( Abc_NtkIsStrash(pNtk) && Abc_HManIsRunning() )
{
Abc_AigForEachAnd( pNtk, pObj, i )
Abc_HManAddProto( pObj->pCopy, pObj );
}
// duplicate the EXDC Ntk
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );

View File

@ -50,6 +50,8 @@ Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
pObj->pNtk = pNtk;
pObj->Type = Type;
pObj->Id = -1;
if ( pNtk->ntkType != ABC_NTK_NETLIST )
Abc_HManAddObj( pObj );
return pObj;
}

View File

@ -61,7 +61,7 @@ char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName )
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with the given number of variables and cubes.]
Synopsis [Creates the constant 1 cover with the given number of variables and cubes.]
Description []
@ -92,7 +92,7 @@ char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars )
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with 0 variables.]
Synopsis [Creates the constant 1 cover with 0 variables.]
Description []
@ -108,7 +108,7 @@ char * Abc_SopCreateConst1( Extra_MmFlex_t * pMan )
/**Function*************************************************************
Synopsis [Starts the constant 1 cover with 0 variables.]
Synopsis [Creates the constant 1 cover with 0 variables.]
Description []
@ -124,7 +124,7 @@ char * Abc_SopCreateConst0( Extra_MmFlex_t * pMan )
/**Function*************************************************************
Synopsis [Starts the AND2 cover.]
Synopsis [Creates the AND2 cover.]
Description []
@ -147,7 +147,7 @@ char * Abc_SopCreateAnd2( Extra_MmFlex_t * pMan, int fCompl0, int fCompl1 )
/**Function*************************************************************
Synopsis [Starts the multi-input AND cover.]
Synopsis [Creates the multi-input AND cover.]
Description []
@ -169,7 +169,7 @@ char * Abc_SopCreateAnd( Extra_MmFlex_t * pMan, int nVars, int * pfCompl )
/**Function*************************************************************
Synopsis [Starts the multi-input NAND cover.]
Synopsis [Creates the multi-input NAND cover.]
Description []
@ -191,7 +191,7 @@ char * Abc_SopCreateNand( Extra_MmFlex_t * pMan, int nVars )
/**Function*************************************************************
Synopsis [Starts the multi-input OR cover.]
Synopsis [Creates the multi-input OR cover.]
Description []
@ -213,7 +213,7 @@ char * Abc_SopCreateOr( Extra_MmFlex_t * pMan, int nVars, int * pfCompl )
/**Function*************************************************************
Synopsis [Starts the multi-input OR cover.]
Synopsis [Creates the multi-input OR cover.]
Description []
@ -238,7 +238,7 @@ char * Abc_SopCreateOrMultiCube( Extra_MmFlex_t * pMan, int nVars, int * pfCompl
/**Function*************************************************************
Synopsis [Starts the multi-input NOR cover.]
Synopsis [Creates the multi-input NOR cover.]
Description []
@ -259,7 +259,7 @@ char * Abc_SopCreateNor( Extra_MmFlex_t * pMan, int nVars )
/**Function*************************************************************
Synopsis [Starts the multi-input XOR cover.]
Synopsis [Creates the multi-input XOR cover.]
Description []
@ -276,7 +276,7 @@ char * Abc_SopCreateXor( Extra_MmFlex_t * pMan, int nVars )
/**Function*************************************************************
Synopsis [Starts the multi-input XOR cover (special case).]
Synopsis [Creates the multi-input XOR cover (special case).]
Description []
@ -296,7 +296,7 @@ char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars )
/**Function*************************************************************
Synopsis [Starts the multi-input XNOR cover.]
Synopsis [Creates the multi-input XNOR cover.]
Description []
@ -313,7 +313,24 @@ char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars )
/**Function*************************************************************
Synopsis [Starts the inv cover.]
Synopsis [Creates the MUX cover.]
Description [The first input of MUX is the control. The second input
is DATA1. The third input is DATA0.]
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopCreateMux( Extra_MmFlex_t * pMan )
{
return Abc_SopRegister(pMan, "11- 1\n0-1 1\n");
}
/**Function*************************************************************
Synopsis [Creates the inv cover.]
Description []
@ -329,7 +346,7 @@ char * Abc_SopCreateInv( Extra_MmFlex_t * pMan )
/**Function*************************************************************
Synopsis [Starts the buf cover.]
Synopsis [Creates the buf cover.]
Description []

View File

@ -64,6 +64,7 @@ static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRestructure ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandResubstitute ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandRr ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv );
@ -82,6 +83,7 @@ static int Abc_CommandExdcSet ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Abc_CommandCut ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandXyz ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandEspresso ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
@ -115,6 +117,9 @@ static int Abc_CommandSec ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTraceStart ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTraceCheck ( Abc_Frame_t * pAbc, int argc, char ** argv );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@ -167,6 +172,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Synthesis", "refactor", Abc_CommandRefactor, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "restructure", Abc_CommandRestructure, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "resub", Abc_CommandResubstitute, 1 );
Cmd_CommandAdd( pAbc, "Synthesis", "rr", Abc_CommandRr, 1 );
// Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 );
Cmd_CommandAdd( pAbc, "Various", "miter", Abc_CommandMiter, 1 );
@ -185,6 +191,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "cut", Abc_CommandCut, 0 );
Cmd_CommandAdd( pAbc, "Various", "xyz", Abc_CommandXyz, 1 );
Cmd_CommandAdd( pAbc, "Various", "espresso", Abc_CommandEspresso, 1 );
Cmd_CommandAdd( pAbc, "Various", "gen", Abc_CommandGen, 0 );
Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 );
Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
@ -218,9 +225,13 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 );
Cmd_CommandAdd( pAbc, "Verification", "trace_start", Abc_CommandTraceStart, 0 );
Cmd_CommandAdd( pAbc, "Verification", "trace_check", Abc_CommandTraceCheck, 0 );
// Rwt_Man4ExploreStart();
// Map_Var3Print();
// Map_Var4Test();
}
/**Function*************************************************************
@ -1598,6 +1609,7 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Ntk_t * pNtk, * pNtkRes;
int fBddSizeMax;
int fDualRail;
int fReorder;
int c;
pNtk = Abc_FrameReadNtk(pAbc);
@ -1605,10 +1617,11 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
fReorder = 1;
fDualRail = 0;
fBddSizeMax = 1000000;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Bdh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "Brdh" ) ) != EOF )
{
switch ( c )
{
@ -1626,6 +1639,9 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'd':
fDualRail ^= 1;
break;
case 'r':
fReorder ^= 1;
break;
case 'h':
goto usage;
default:
@ -1647,11 +1663,11 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
// get the new network
if ( Abc_NtkIsStrash(pNtk) )
pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, 1 );
pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, 1 );
else
{
pNtk = Abc_NtkStrash( pNtk, 0, 0 );
pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, 1 );
pNtkRes = Abc_NtkCollapse( pNtk, fBddSizeMax, fDualRail, fReorder, 1 );
Abc_NtkDelete( pNtk );
}
if ( pNtkRes == NULL )
@ -1664,9 +1680,10 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( pErr, "usage: collapse [-B num] [-dh]\n" );
fprintf( pErr, "usage: collapse [-B num] [-rdh]\n" );
fprintf( pErr, "\t collapses the network by constructing global BDDs\n" );
fprintf( pErr, "\t-B num : limit on live BDD nodes during collapsing [default = %d]\n", fBddSizeMax );
fprintf( pErr, "\t-r : toggles dynamic variable reordering [default = %s]\n", fReorder? "yes": "no" );
fprintf( pErr, "\t-d : toggles dual-rail collapsing mode [default = %s]\n", fDualRail? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
@ -2759,6 +2776,102 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandRr( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c, Window;
int nFaninLevels;
int nFanoutLevels;
int fUseFanouts;
int fVerbose;
extern int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFanouts, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
nFaninLevels = 3;
nFanoutLevels = 3;
fUseFanouts = 0;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Wfvh" ) ) != EOF )
{
switch ( c )
{
case 'W':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-W\" should be followed by an integer.\n" );
goto usage;
}
Window = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Window < 0 )
goto usage;
nFaninLevels = Window / 10;
nFanoutLevels = Window % 10;
break;
case 'f':
fUseFanouts ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
fprintf( pErr, "This command can only be applied to an AIG (run \"strash\").\n" );
return 1;
}
if ( Abc_NtkGetChoiceNum(pNtk) )
{
fprintf( pErr, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" );
return 1;
}
// modify the current network
if ( !Abc_NtkRR( pNtk, nFaninLevels, nFanoutLevels, fUseFanouts, fVerbose ) )
{
fprintf( pErr, "Redundancy removal has failed.\n" );
return 1;
}
return 0;
usage:
fprintf( pErr, "usage: rr [-W NM] [-fvh]\n" );
fprintf( pErr, "\t performs redundancy removal in the current network\n" );
fprintf( pErr, "\t-W NM : window size as the number of TFI (N) and TFO (M) logic levels [default = %d%d]\n", nFaninLevels, nFanoutLevels );
fprintf( pErr, "\t-f : toggle RR w.r.t. fanouts [default = %s]\n", fUseFanouts? "yes": "no" );
fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
@ -3806,10 +3919,12 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
pParams->fTruth = 0; // compute truth tables
pParams->fFilter = 1; // filter dominated cuts
pParams->fDrop = 0; // drop cuts on the fly
pParams->fMulti = 0; // use multi-input AND-gates
pParams->fDag = 0; // compute DAG cuts
pParams->fTree = 0; // compute tree cuts
pParams->fFancy = 0; // compute something fancy
pParams->fVerbose = 0; // the verbosiness flag
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "KMtfdmvoh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "KMtfdxyzvoh" ) ) != EOF )
{
switch ( c )
{
@ -3844,8 +3959,14 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'd':
pParams->fDrop ^= 1;
break;
case 'm':
pParams->fMulti ^= 1;
case 'x':
pParams->fDag ^= 1;
break;
case 'y':
pParams->fTree ^= 1;
break;
case 'z':
pParams->fFancy ^= 1;
break;
case 'v':
pParams->fVerbose ^= 1;
@ -3875,6 +3996,11 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Can only compute the cuts for %d <= K <= %d.\n", CUT_SIZE_MIN, CUT_SIZE_MAX );
return 1;
}
if ( pParams->fDag && pParams->fTree )
{
fprintf( pErr, "Cannot compute both DAG cuts and tree cuts at the same time.\n" );
return 1;
}
if ( fOracle )
pParams->fRecord = 1;
@ -3891,14 +4017,16 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdmvh]\n" );
fprintf( pErr, "usage: cut [-K num] [-M num] [-tfdxyzvh]\n" );
fprintf( pErr, "\t computes k-feasible cuts for the AIG\n" );
fprintf( pErr, "\t-K num : max number of leaves (%d <= num <= %d) [default = %d]\n", CUT_SIZE_MIN, CUT_SIZE_MAX, pParams->nVarsMax );
fprintf( pErr, "\t-M num : max number of cuts stored at a node [default = %d]\n", pParams->nKeepMax );
fprintf( pErr, "\t-t : toggle truth table computation [default = %s]\n", pParams->fTruth? "yes": "no" );
fprintf( pErr, "\t-f : toggle filtering of duplicated/dominated [default = %s]\n", pParams->fFilter? "yes": "no" );
fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "yes": "no" );
fprintf( pErr, "\t-m : toggle computing only factor-cuts [default = %s]\n", pParams->fMulti? "yes": "no" );
fprintf( pErr, "\t-x : toggle computing only DAG cuts [default = %s]\n", pParams->fDag? "yes": "no" );
fprintf( pErr, "\t-y : toggle computing only tree cuts [default = %s]\n", pParams->fTree? "yes": "no" );
fprintf( pErr, "\t-z : toggle fancy computations [default = %s]\n", pParams->fFancy? "yes": "no" );
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
@ -4160,6 +4288,99 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
int nVars;
int fAdder;
int fSorter;
int fVerbose;
char * FileName;
extern void Abc_GenAdder( char * pFileName, int nVars );
extern void Abc_GenSorter( char * pFileName, int nVars );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
nVars = 8;
fAdder = 0;
fSorter = 0;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Nasvh" ) ) != EOF )
{
switch ( c )
{
case 'N':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
goto usage;
}
nVars = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nVars < 0 )
goto usage;
break;
case 'a':
fAdder ^= 1;
break;
case 's':
fSorter ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( argc != globalUtilOptind + 1 )
{
goto usage;
}
// get the input file name
FileName = argv[globalUtilOptind];
if ( fAdder )
Abc_GenAdder( FileName, nVars );
else if ( fSorter )
Abc_GenSorter( FileName, nVars );
else
printf( "Type of circuit is not specified.\n" );
return 0;
usage:
fprintf( pErr, "usage: gen [-N] [-asvh] <file>\n" );
fprintf( pErr, "\t generates simple circuits\n" );
fprintf( pErr, "\t-N num : the number of variables [default = %d]\n", nVars );
fprintf( pErr, "\t-a : toggle ripple-carry adder [default = %s]\n", fAdder? "yes": "no" );
fprintf( pErr, "\t-s : toggle simple sorter [default = %s]\n", fSorter? "yes": "no" );
fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
fprintf( pErr, "\t<file> : output file name\n");
return 1;
}
/**Function*************************************************************
@ -4175,7 +4396,7 @@ usage:
int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes;
Abc_Ntk_t * pNtk;//, * pNtkRes;
int c;
// extern Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk );
@ -4195,25 +4416,27 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
/*
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( Abc_NtkIsSeq(pNtk) )
{
fprintf( pErr, "Only works for non-sequential networks.\n" );
return 1;
}
*/
// Abc_NtkTestEsop( pNtk );
// Abc_NtkTestSop( pNtk );
// printf( "This command is currently not used.\n" );
// run the command
// pNtkRes = Abc_NtkMiterForCofactors( pNtk, 0, 0, -1 );
// pNtkRes = Abc_NtkNewAig( pNtk );
/*
pNtkRes = NULL;
if ( pNtkRes == NULL )
{
@ -4222,6 +4445,14 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
*/
// if ( Cut_CellIsRunning() )
// Cut_CellDumpToFile();
// else
// Cut_CellPrecompute();
Cut_CellLoad();
return 0;
usage:
@ -6459,6 +6690,7 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Ntk_t * pNtk;
int c;
int RetValue;
int fJFront;
int fVerbose;
int nConfLimit;
int nImpLimit;
@ -6469,11 +6701,12 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
fJFront = 0;
fVerbose = 0;
nConfLimit = 100000;
nImpLimit = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "CIvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "CIvjh" ) ) != EOF )
{
switch ( c )
{
@ -6499,6 +6732,9 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nImpLimit < 0 )
goto usage;
break;
case 'j':
fJFront ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
@ -6528,13 +6764,13 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
clk = clock();
if ( Abc_NtkIsStrash(pNtk) )
{
RetValue = Abc_NtkMiterSat( pNtk, nConfLimit, nImpLimit, fVerbose );
RetValue = Abc_NtkMiterSat( pNtk, nConfLimit, nImpLimit, fJFront, fVerbose );
}
else
{
Abc_Ntk_t * pTemp;
pTemp = Abc_NtkStrash( pNtk, 0, 0 );
RetValue = Abc_NtkMiterSat( pTemp, nConfLimit, nImpLimit, fVerbose );
RetValue = Abc_NtkMiterSat( pTemp, nConfLimit, nImpLimit, fJFront, fVerbose );
pNtk->pModel = pTemp->pModel; pTemp->pModel = NULL;
Abc_NtkDelete( pTemp );
}
@ -6544,7 +6780,7 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
{
int * pSimInfo = Abc_NtkVerifySimulatePattern( pNtk, pNtk->pModel );
if ( pSimInfo[0] != 1 )
printf( "ERROR in Abc_NtkMiterProve(): Generated counter example is invalid.\n" );
printf( "ERROR in Abc_NtkMiterSat(): Generated counter example is invalid.\n" );
free( pSimInfo );
}
@ -6559,11 +6795,12 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( pErr, "usage: sat [-C num] [-I num] [-vh]\n" );
fprintf( pErr, "usage: sat [-C num] [-I num] [-jvh]\n" );
fprintf( pErr, "\t solves the combinational miter using SAT solver MiniSat-1.14\n" );
fprintf( pErr, "\t derives CNF from the current network and leave it unchanged\n" );
fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
fprintf( pErr, "\t-I num : limit on the number of implications [default = %d]\n", nImpLimit );
fprintf( pErr, "\t-j : toggle the use of J-frontier [default = %s]\n", fJFront? "yes": "no" );
fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
@ -6584,60 +6821,72 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkTemp;
int c;
int RetValue;
int fVerbose;
int fRewrite;
int fFraig;
int nConfLimit;
int nImpLimit;
int clk;
Prove_Params_t Params, * pParams = &Params;
int c, clk, RetValue;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
fVerbose = 0;
fRewrite = 1;
fFraig = 1;
nConfLimit = 300000;
nImpLimit = 0;
Prove_ParamsSetDefault( pParams );
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "CIrfvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "NCFLrfvh" ) ) != EOF )
{
switch ( c )
{
case 'N':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
goto usage;
}
pParams->nItersMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pParams->nItersMax < 0 )
goto usage;
break;
case 'C':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" );
goto usage;
}
nConfLimit = atoi(argv[globalUtilOptind]);
pParams->nMiteringLimitStart = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nConfLimit < 0 )
if ( pParams->nMiteringLimitStart < 0 )
goto usage;
break;
case 'I':
case 'F':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" );
fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" );
goto usage;
}
nImpLimit = atoi(argv[globalUtilOptind]);
pParams->nFraigingLimitStart = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nImpLimit < 0 )
if ( pParams->nFraigingLimitStart < 0 )
goto usage;
break;
case 'L':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" );
goto usage;
}
pParams->nMiteringLimitLast = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pParams->nMiteringLimitLast < 0 )
goto usage;
break;
case 'r':
fRewrite ^= 1;
pParams->fUseRewriting ^= 1;
break;
case 'f':
fFraig ^= 1;
pParams->fUseFraiging ^= 1;
break;
case 'v':
fVerbose ^= 1;
pParams->fVerbose ^= 1;
break;
case 'h':
goto usage;
@ -6674,7 +6923,7 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv )
else
pNtkTemp = Abc_NtkStrash( pNtk, 0, 0 );
RetValue = Abc_NtkMiterProve( &pNtkTemp, nConfLimit, nImpLimit, fRewrite, fFraig, fVerbose );
RetValue = Abc_NtkMiterProve( &pNtkTemp, pParams );
// verify that the pattern is correct
if ( RetValue == 0 )
@ -6699,19 +6948,143 @@ int Abc_CommandProve( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
fprintf( pErr, "usage: prove [-C num] [-I num] [-rfvh]\n" );
fprintf( pErr, "usage: prove [-N num] [-C num] [-F num] [-L num] [-rfvh]\n" );
fprintf( pErr, "\t solves combinational miter by rewriting, FRAIGing, and SAT\n" );
fprintf( pErr, "\t replaces the current network by the cone modified by rewriting\n" );
fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
fprintf( pErr, "\t-I num : limit on the number of implications [default = %d]\n", nImpLimit );
fprintf( pErr, "\t-r : toggle the use of rewriting [default = %s]\n", fRewrite? "yes": "no" );
fprintf( pErr, "\t-f : toggle the use of FRAIGing [default = %s]\n", fFraig? "yes": "no" );
fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-N num : max number of iterations [default = %d]\n", pParams->nItersMax );
fprintf( pErr, "\t-C num : max starting number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitStart );
fprintf( pErr, "\t-F num : max starting number of conflicts in fraiging [default = %d]\n", pParams->nFraigingLimitStart );
fprintf( pErr, "\t-L num : max last-gasp number of conflicts in mitering [default = %d]\n", pParams->nMiteringLimitLast );
fprintf( pErr, "\t-r : toggle the use of rewriting [default = %s]\n", pParams->fUseRewriting? "yes": "no" );
fprintf( pErr, "\t-f : toggle the use of FRAIGing [default = %s]\n", pParams->fUseFraiging? "yes": "no" );
fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", pParams->fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandTraceStart( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
fprintf( pErr, "This command is applicable to AIGs.\n" );
return 1;
}
Abc_HManStart();
if ( !Abc_HManPopulate( pNtk ) )
{
fprintf( pErr, "Failed to start the tracing database.\n" );
return 1;
}
return 0;
usage:
fprintf( pErr, "usage: trace_start [-h]\n" );
fprintf( pErr, "\t starts verification tracing\n" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandTraceCheck( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
{
switch ( c )
{
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
fprintf( pErr, "This command is applicable to AIGs.\n" );
return 1;
}
if ( !Abc_HManIsRunning(pNtk) )
{
fprintf( pErr, "The tracing database is not available.\n" );
return 1;
}
if ( !Abc_HManVerify( 1, pNtk->Id ) )
fprintf( pErr, "Verification failed.\n" );
Abc_HManStop();
return 0;
usage:
fprintf( pErr, "usage: trace_check [-h]\n" );
fprintf( pErr, "\t checks the current network using verification trace\n" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -51,7 +51,7 @@ void Abc_NtkAutoPrint( Abc_Ntk_t * pNtk, int Output, int fNaive, int fVerbose )
int nOutputs, nInputs, i;
// compute the global BDDs
if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0) == NULL )
if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0, 1, fVerbose) == NULL )
return;
// get information about the network

View File

@ -29,6 +29,8 @@ static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode,
static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vSuper, int Level, int fDuplicate, bool fSelective );
static int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate, bool fSelective );
static void Abc_NtkMarkCriticalNodes( Abc_Ntk_t * pNtk );
static Vec_Ptr_t * Abc_NodeBalanceConeExor( Abc_Obj_t * pNode );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@ -227,6 +229,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_
return pNodeOld->pCopy;
assert( Abc_ObjIsNode(pNodeOld) );
// get the implication supergate
// Abc_NodeBalanceConeExor( pNodeOld );
vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, Level, fDuplicate, fSelective );
if ( vSuper->nSize == 0 )
{ // it means that the supergate contains two nodes in the opposite polarity
@ -260,6 +263,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_
assert( pNodeOld->pCopy == NULL );
// mark the old node with the new node
pNodeOld->pCopy = vSuper->pArray[0];
Abc_HManAddProto( pNodeOld->pCopy, pNodeOld );
vSuper->nSize = 0;
return pNodeOld->pCopy;
}
@ -351,6 +355,65 @@ int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst,
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NodeBalanceConeExor_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst )
{
int RetValue1, RetValue2, i;
// check if the node occurs in the same polarity
for ( i = 0; i < vSuper->nSize; i++ )
if ( vSuper->pArray[i] == pNode )
return 1;
// if the new node is complemented or a PI, another gate begins
if ( !fFirst && (!pNode->fExor || !Abc_ObjIsNode(pNode)) )
{
Vec_PtrPush( vSuper, pNode );
return 0;
}
assert( !Abc_ObjIsComplement(pNode) );
assert( Abc_ObjIsNode(pNode) );
assert( pNode->fExor );
// go through the branches
RetValue1 = Abc_NodeBalanceConeExor_rec( Abc_ObjFanin0(Abc_ObjFanin0(pNode)), vSuper, 0 );
RetValue2 = Abc_NodeBalanceConeExor_rec( Abc_ObjFanin1(Abc_ObjFanin0(pNode)), vSuper, 0 );
if ( RetValue1 == -1 || RetValue2 == -1 )
return -1;
// return 1 if at least one branch has a duplicate
return RetValue1 || RetValue2;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NodeBalanceConeExor( Abc_Obj_t * pNode )
{
Vec_Ptr_t * vSuper;
if ( !pNode->fExor )
return NULL;
vSuper = Vec_PtrAlloc( 10 );
Abc_NodeBalanceConeExor_rec( pNode, vSuper, 1 );
printf( "%d ", Vec_PtrSize(vSuper) );
Vec_PtrFree( vSuper );
return NULL;
}
/**Function*************************************************************

View File

@ -43,14 +43,14 @@ static Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd,
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fVerbose )
Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fVerbose )
{
Abc_Ntk_t * pNtkNew;
assert( Abc_NtkIsStrash(pNtk) );
// compute the global BDDs
if ( Abc_NtkGlobalBdds(pNtk, fBddSizeMax, 0) == NULL )
if ( Abc_NtkGlobalBdds(pNtk, fBddSizeMax, 0, fReorder, fVerbose) == NULL )
return NULL;
if ( fVerbose )
printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(pNtk->pManGlob) - Cudd_ReadDead(pNtk->pManGlob) );

View File

@ -29,6 +29,9 @@
static void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq );
static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
extern int nTotal, nGood, nEqual;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@ -46,6 +49,7 @@ static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
***********************************************************************/
Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
{
ProgressBar * pProgress;
Cut_Man_t * p;
Abc_Obj_t * pObj, * pNode;
Vec_Ptr_t * vNodes;
@ -56,6 +60,8 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk );
extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk );
nTotal = nGood = nEqual = 0;
assert( Abc_NtkIsStrash(pNtk) );
// start the manager
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
@ -69,6 +75,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
// compute cuts for internal nodes
vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs
vChoices = Vec_IntAlloc( 100 );
pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodes) );
Vec_PtrForEachEntry( vNodes, pObj, i )
{
// when we reached a CO, it is time to deallocate the cuts
@ -81,8 +88,9 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
// skip constant node, it has no cuts
if ( Abc_NodeIsConst(pObj) )
continue;
Extra_ProgressBarUpdate( pProgress, i, NULL );
// compute the cuts to the internal node
Abc_NodeGetCuts( p, pObj, pParams->fMulti );
Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree );
// consider dropping the fanins cuts
if ( pParams->fDrop )
{
@ -98,11 +106,16 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
Cut_NodeUnionCuts( p, vChoices );
}
}
Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vNodes );
Vec_IntFree( vChoices );
PRT( "Total", clock() - clk );
//Abc_NtkPrintCuts_( p, pNtk, 0 );
// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk );
// temporary printout of stats
if ( nTotal )
printf( "Total cuts = %d. Good cuts = %d. Ratio = %5.2f\n", nTotal, nGood, ((double)nGood)/nTotal );
return p;
}
@ -276,14 +289,14 @@ printf( "Converged after %d iterations.\n", nIters );
SeeAlso []
***********************************************************************/
void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fMulti )
void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
{
void * pList;
if ( pList = Abc_NodeReadCuts( p, pObj ) )
return pList;
Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fMulti );
Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fMulti );
return Abc_NodeGetCuts( p, pObj, fMulti );
Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fDag, fTree );
Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fDag, fTree );
return Abc_NodeGetCuts( p, pObj, fDag, fTree );
}
/**Function*************************************************************
@ -297,14 +310,28 @@ void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fMulti )
SeeAlso []
***********************************************************************/
void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fMulti )
void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
{
// int fTriv = (!fMulti) || pObj->fMarkB;
int fTriv = (!fMulti) || (pObj->vFanouts.nSize > 1 && !Abc_NodeIsMuxControlType(pObj));
Abc_Obj_t * pFanin;
int fDagNode, fTriv, TreeCode = 0;
assert( Abc_NtkIsStrash(pObj->pNtk) );
assert( Abc_ObjFaninNum(pObj) == 2 );
// check if the node is a DAG node
fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj));
// increment the counter of DAG nodes
if ( fDagNode ) Cut_ManIncrementDagNodes( p );
// add the trivial cut if the node is a DAG node, or if we compute all cuts
fTriv = fDagNode || !fDag;
// check if fanins are DAG nodes
if ( fTree )
{
pFanin = Abc_ObjFanin0(pObj);
TreeCode |= (Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin));
pFanin = Abc_ObjFanin1(pObj);
TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1);
}
return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv );
Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv, TreeCode );
}
/**Function*************************************************************

View File

@ -60,7 +60,7 @@ Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool
assert( Abc_NtkIsStrash(pNtk) );
// perform FPGA mapping
if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0) == NULL )
if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0, 1, fVerbose) == NULL )
return NULL;
if ( fVerbose )
printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(pNtk->pManGlob) - Cudd_ReadDead(pNtk->pManGlob) );

View File

@ -54,7 +54,13 @@ void Abc_NtkEspresso( Abc_Ntk_t * pNtk, int fVerbose )
if ( Abc_NtkHasMapping(pNtk) )
Abc_NtkUnmap(pNtk);
else if ( Abc_NtkHasBdd(pNtk) )
Abc_NtkBddToSop(pNtk, 0);
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return;
}
}
// minimize SOPs of all nodes
Abc_NtkForEachNode( pNtk, pNode, i )
if ( i ) Abc_NodeEspresso( pNode );

View File

@ -684,7 +684,7 @@ int Abc_NtkFraigStore( Abc_Ntk_t * pNtk )
// set the number of networks stored
Abc_FrameSetNtkStoreSize( Abc_FrameReadNtkStoreSize() + 1 );
}
printf( "The number of AIG nodes added to storage = %5d.\n", Abc_NtkNodeNum(pStore) - nAndsOld );
// printf( "The number of AIG nodes added to storage = %5d.\n", Abc_NtkNodeNum(pStore) - nAndsOld );
return 1;
}

View File

@ -57,7 +57,13 @@ bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
if ( Abc_NtkIsMappedLogic(pNtk) )
Abc_NtkUnmap(pNtk);
else if ( Abc_NtkIsBddLogic(pNtk) )
Abc_NtkBddToSop(pNtk, 0);
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return 0;
}
}
else
{ // to make sure the SOPs are SCC-free
// Abc_NtkSopToBdd(pNtk);

261
src/base/abci/abcGen.c Normal file
View File

@ -0,0 +1,261 @@
/**CFile****************************************************************
FileName [abc_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
void Abc_WriteLayer( FILE * pFile, int nVars, int fSkip1 );
void Abc_WriteComp( FILE * pFile );
void Abc_WriteFullAdder( FILE * pFile );
void Abc_GenAdder( char * pFileName, int nVars );
void Abc_GenSorter( char * pFileName, int nVars );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_GenAdder( char * pFileName, int nVars )
{
FILE * pFile;
int i;
assert( nVars > 0 );
pFile = fopen( pFileName, "w" );
fprintf( pFile, "# %d-bit ripple-carry adder generated by ABC on %s\n", nVars, Extra_TimeStamp() );
fprintf( pFile, ".model Adder%02d\n", nVars );
fprintf( pFile, ".inputs" );
for ( i = 0; i < nVars; i++ )
fprintf( pFile, " a%02d", i );
for ( i = 0; i < nVars; i++ )
fprintf( pFile, " b%02d", i );
fprintf( pFile, "\n" );
fprintf( pFile, ".outputs" );
for ( i = 0; i <= nVars; i++ )
fprintf( pFile, " y%02d", i );
fprintf( pFile, "\n" );
fprintf( pFile, ".names c\n" );
if ( nVars == 1 )
fprintf( pFile, ".subckt FA a=a00 b=b00 cin=c s=y00 cout=y01\n" );
else
{
fprintf( pFile, ".subckt FA a=a00 b=b00 cin=c s=y00 cout=%02d\n", 0 );
for ( i = 1; i < nVars-1; i++ )
fprintf( pFile, ".subckt FA a=a%02d b=b%02d cin=%02d s=y%02d cout=%02d\n", i, i, i-1, i, i );
fprintf( pFile, ".subckt FA a=a%02d b=b%02d cin=%02d s=y%02d cout=y%02d\n", i, i, i-1, i, i+1 );
}
fprintf( pFile, ".end\n" );
fprintf( pFile, "\n" );
Abc_WriteFullAdder( pFile );
fclose( pFile );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_GenSorter( char * pFileName, int nVars )
{
FILE * pFile;
int i, k, Counter, nDigits;
assert( nVars > 1 );
pFile = fopen( pFileName, "w" );
fprintf( pFile, "# %d-bit sorter generated by ABC on %s\n", nVars, Extra_TimeStamp() );
fprintf( pFile, ".model Sorter%02d\n", nVars );
fprintf( pFile, ".inputs" );
for ( i = 0; i < nVars; i++ )
fprintf( pFile, " x%02d", i );
fprintf( pFile, "\n" );
fprintf( pFile, ".outputs" );
for ( i = 0; i < nVars; i++ )
fprintf( pFile, " y%02d", i );
fprintf( pFile, "\n" );
Counter = 0;
nDigits = Extra_Base10Log( (nVars-2)*nVars );
if ( nVars == 2 )
fprintf( pFile, ".subckt Comp a=x00 b=x01 x=y00 y=y01\n" );
else
{
fprintf( pFile, ".subckt Layer0" );
for ( k = 0; k < nVars; k++ )
fprintf( pFile, " x%02d=x%02d", k, k );
for ( k = 0; k < nVars; k++ )
fprintf( pFile, " y%02d=%0*d", k, nDigits, Counter++ );
fprintf( pFile, "\n" );
Counter -= nVars;
for ( i = 1; i < nVars-2; i++ )
{
fprintf( pFile, ".subckt Layer%d", (i&1) );
for ( k = 0; k < nVars; k++ )
fprintf( pFile, " x%02d=%0*d", k, nDigits, Counter++ );
for ( k = 0; k < nVars; k++ )
fprintf( pFile, " y%02d=%0*d", k, nDigits, Counter++ );
fprintf( pFile, "\n" );
Counter -= nVars;
}
fprintf( pFile, ".subckt Layer%d", (i&1) );
for ( k = 0; k < nVars; k++ )
fprintf( pFile, " x%02d=%0*d", k, nDigits, Counter++ );
for ( k = 0; k < nVars; k++ )
fprintf( pFile, " y%02d=y%02d", k, k );
fprintf( pFile, "\n" );
}
fprintf( pFile, ".end\n" );
fprintf( pFile, "\n" );
Abc_WriteLayer( pFile, nVars, 0 );
Abc_WriteLayer( pFile, nVars, 1 );
Abc_WriteComp( pFile );
fclose( pFile );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_WriteLayer( FILE * pFile, int nVars, int fSkip1 )
{
int i;
fprintf( pFile, ".model Layer%d\n", fSkip1 );
fprintf( pFile, ".inputs" );
for ( i = 0; i < nVars; i++ )
fprintf( pFile, " x%02d", i );
fprintf( pFile, "\n" );
fprintf( pFile, ".outputs" );
for ( i = 0; i < nVars; i++ )
fprintf( pFile, " y%02d", i );
fprintf( pFile, "\n" );
if ( fSkip1 )
{
fprintf( pFile, ".names x00 y00\n" );
fprintf( pFile, "1 1\n" );
i = 1;
}
else
i = 0;
for ( ; i + 1 < nVars; i += 2 )
fprintf( pFile, ".subckt Comp a=x%02d b=x%02d x=y%02d y=y%02d\n", i, i+1, i, i+1 );
if ( i < nVars )
{
fprintf( pFile, ".names x%02d y%02d\n", i, i );
fprintf( pFile, "1 1\n" );
}
fprintf( pFile, ".end\n" );
fprintf( pFile, "\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_WriteComp( FILE * pFile )
{
fprintf( pFile, ".model Comp\n" );
fprintf( pFile, ".inputs a b\n" );
fprintf( pFile, ".outputs x y\n" );
fprintf( pFile, ".names a b x\n" );
fprintf( pFile, "11 1\n" );
fprintf( pFile, ".names a b y\n" );
fprintf( pFile, "1- 1\n" );
fprintf( pFile, "-1 1\n" );
fprintf( pFile, ".end\n" );
fprintf( pFile, "\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_WriteFullAdder( FILE * pFile )
{
fprintf( pFile, ".model FA\n" );
fprintf( pFile, ".inputs a b cin\n" );
fprintf( pFile, ".outputs s cout\n" );
fprintf( pFile, ".names a b k\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names k cin s\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names a b cin cout\n" );
fprintf( pFile, "11- 1\n" );
fprintf( pFile, "1-1 1\n" );
fprintf( pFile, "-11 1\n" );
fprintf( pFile, ".end\n" );
fprintf( pFile, "\n" );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -522,7 +522,11 @@ Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
// duplicate the network
pNtkNew2 = Abc_NtkDup( pNtk );
pNtkNew = Abc_NtkRenode( pNtkNew2, 0, 20, 0, 0, 1, 0 );
Abc_NtkBddToSop( pNtkNew, 0 );
if ( !Abc_NtkBddToSop( pNtkNew, 0 ) )
{
printf( "Converting to SOPs has failed.\n" );
return NULL;
}
// set the old network to point to the new network
Abc_NtkForEachCi( pNtk, pNode, i )

View File

@ -282,7 +282,129 @@ void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNt
/**Function*************************************************************
Synopsis [Derives the AND of two miters.]
Description [The network should have the same names of PIs.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkMiterAnd( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
{
char Buffer[100];
Abc_Ntk_t * pNtkMiter;
Abc_Obj_t * pOutput1, * pOutput2;
Abc_Obj_t * pRoot1, * pRoot2, * pMiter;
assert( Abc_NtkIsStrash(pNtk1) );
assert( Abc_NtkIsStrash(pNtk2) );
assert( 1 == Abc_NtkCoNum(pNtk1) );
assert( 1 == Abc_NtkCoNum(pNtk2) );
assert( 0 == Abc_NtkLatchNum(pNtk1) );
assert( 0 == Abc_NtkLatchNum(pNtk2) );
assert( Abc_NtkCiNum(pNtk1) == Abc_NtkCiNum(pNtk2) );
// start the new network
pNtkMiter = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG );
sprintf( Buffer, "%s_%s_miter", pNtk1->pName, pNtk2->pName );
pNtkMiter->pName = Extra_UtilStrsav(Buffer);
// perform strashing
Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, 1 );
Abc_NtkMiterAddOne( pNtk1, pNtkMiter );
Abc_NtkMiterAddOne( pNtk2, pNtkMiter );
// Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, 1 );
pRoot1 = Abc_NtkPo(pNtk1,0);
pRoot2 = Abc_NtkPo(pNtk2,0);
pOutput1 = Abc_ObjNotCond( Abc_ObjFanin0(pRoot1)->pCopy, Abc_ObjFaninC0(pRoot1) );
pOutput2 = Abc_ObjNotCond( Abc_ObjFanin0(pRoot2)->pCopy, Abc_ObjFaninC0(pRoot2) );
// create the miter of the two outputs
pMiter = Abc_AigAnd( pNtkMiter->pManFunc, pOutput1, pOutput2 );
Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter );
// make sure that everything is okay
if ( !Abc_NtkCheck( pNtkMiter ) )
{
printf( "Abc_NtkMiterAnd: The network check has failed.\n" );
Abc_NtkDelete( pNtkMiter );
return NULL;
}
return pNtkMiter;
}
/**Function*************************************************************
Synopsis [Derives the cofactor of the miter w.r.t. the set of vars.]
Description [The array of variable values contains -1/0/1 for each PI.
-1 means this PI remains, 0/1 means this PI is set to 0/1.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkMiterCofactor( Abc_Ntk_t * pNtk, Vec_Int_t * vPiValues )
{
char Buffer[100];
Abc_Ntk_t * pNtkMiter;
Abc_Obj_t * pRoot, * pOutput1;
int Value, i;
assert( Abc_NtkIsStrash(pNtk) );
assert( 1 == Abc_NtkCoNum(pNtk) );
// start the new network
pNtkMiter = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG );
sprintf( Buffer, "%s_miter", pNtk->pName );
pNtkMiter->pName = Extra_UtilStrsav(Buffer);
// get the root output
pRoot = Abc_NtkCo( pNtk, 0 );
// perform strashing
Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 );
// set the first cofactor
Vec_IntForEachEntry( vPiValues, Value, i )
{
if ( Value == -1 )
continue;
if ( Value == 0 )
{
Abc_NtkCi(pNtk, i)->pCopy = Abc_ObjNot( Abc_NtkConst1(pNtkMiter) );
continue;
}
if ( Value == 1 )
{
Abc_NtkCi(pNtk, i)->pCopy = Abc_NtkConst1(pNtkMiter);
continue;
}
assert( 0 );
}
// add the first cofactor
Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
// save the output
pOutput1 = Abc_ObjNotCond( Abc_ObjFanin0(pRoot)->pCopy, Abc_ObjFaninC0(pRoot) );
// create the miter of the two outputs
Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pOutput1 );
// make sure that everything is okay
if ( !Abc_NtkCheck( pNtkMiter ) )
{
printf( "Abc_NtkMiterCofactor: The network check has failed.\n" );
Abc_NtkDelete( pNtkMiter );
return NULL;
}
return pNtkMiter;
}
/**Function*************************************************************
Synopsis [Derives the miter of two cofactors of one output.]

View File

@ -65,7 +65,13 @@ Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk )
assert( !Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsSeq(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
Abc_NtkBddToSop(pNtk, 0);
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return;
}
}
// print warning about choice nodes
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );

View File

@ -27,7 +27,7 @@
static void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
static Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew );
static Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node );
static DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSizeMax );
static DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSizeMax, ProgressBar * pProgress, int * pCounter, int fVerbose );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@ -243,15 +243,14 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t *
SeeAlso []
***********************************************************************/
DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly )
DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly, int fReorder, int fVerbose )
{
int fReorder = 1;
ProgressBar * pProgress;
Vec_Ptr_t * vFuncsGlob;
Abc_Obj_t * pNode;
DdNode * bFunc;
DdManager * dd;
int i;
int i, Counter;
// start the manager
assert( pNtk->pManGlob == NULL );
@ -269,18 +268,20 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly
// collect the global functions of the COs
vFuncsGlob = Vec_PtrAlloc( 100 );
Counter = 0;
if ( fLatchOnly )
{
// construct the BDDs
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkLatchNum(pNtk) );
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
Abc_NtkForEachLatch( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode), nBddSizeMax );
// Extra_ProgressBarUpdate( pProgress, i, NULL );
bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode), nBddSizeMax, pProgress, &Counter, fVerbose );
if ( bFunc == NULL )
{
if ( fVerbose )
printf( "Constructing global BDDs is aborted.\n" );
Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vFuncsGlob );
Cudd_Quit( dd );
return NULL;
}
@ -292,15 +293,16 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly
else
{
// construct the BDDs
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
pProgress = Extra_ProgressBarStart( stdout, Abc_NtkNodeNum(pNtk) );
Abc_NtkForEachCo( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode), nBddSizeMax );
// Extra_ProgressBarUpdate( pProgress, i, NULL );
bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode), nBddSizeMax, pProgress, &Counter, fVerbose );
if ( bFunc == NULL )
{
if ( fVerbose )
printf( "Constructing global BDDs is aborted.\n" );
Extra_ProgressBarStop( pProgress );
Vec_PtrFree( vFuncsGlob );
Cudd_Quit( dd );
return NULL;
}
@ -339,12 +341,14 @@ DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fLatchOnly
SeeAlso []
***********************************************************************/
DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSizeMax )
DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSizeMax, ProgressBar * pProgress, int * pCounter, int fVerbose )
{
DdNode * bFunc, * bFunc0, * bFunc1;
assert( !Abc_ObjIsComplement(pNode) );
if ( Cudd_ReadKeys(dd)-Cudd_ReadDead(dd) > (unsigned)nBddSizeMax )
{
Extra_ProgressBarStop( pProgress );
if ( fVerbose )
printf( "The number of live nodes reached %d.\n", nBddSizeMax );
fflush( stdout );
return NULL;
@ -353,11 +357,11 @@ DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSize
if ( pNode->pCopy )
return (DdNode *)pNode->pCopy;
// compute the result for both branches
bFunc0 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,0), nBddSizeMax );
bFunc0 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,0), nBddSizeMax, pProgress, pCounter, fVerbose );
if ( bFunc0 == NULL )
return NULL;
Cudd_Ref( bFunc0 );
bFunc1 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,1), nBddSizeMax );
bFunc1 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,1), nBddSizeMax, pProgress, pCounter, fVerbose );
if ( bFunc1 == NULL )
return NULL;
Cudd_Ref( bFunc1 );
@ -370,6 +374,9 @@ DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode, int nBddSize
// set the result
assert( pNode->pCopy == NULL );
pNode->pCopy = (Abc_Obj_t *)bFunc;
// increment the progress bar
if ( pProgress )
Extra_ProgressBarUpdate( pProgress, (*pCounter)++, NULL );
return bFunc;
}
@ -427,7 +434,7 @@ double Abc_NtkSpacePercentage( Abc_Obj_t * pNode )
Vec_PtrForEachEntry( vNodes, pObj, i )
pObj->pCopy = (Abc_Obj_t *)dd->vars[i];
// build the BDD of the cone
bFunc = Abc_NodeGlobalBdds_rec( dd, pNodeR, 10000000 ); Cudd_Ref( bFunc );
bFunc = Abc_NodeGlobalBdds_rec( dd, pNodeR, 10000000, NULL, NULL, 1 ); Cudd_Ref( bFunc );
bFunc = Cudd_NotCond( bFunc, pNode != pNodeR );
// count minterms
Result = Cudd_CountMinterm( dd, bFunc, dd->size );

View File

@ -28,6 +28,9 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
//extern int s_TotalNodes = 0;
//extern int s_TotalChanges = 0;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@ -147,6 +150,11 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
fclose( pTable );
}
*/
/*
s_TotalNodes += Abc_NtkNodeNum(pNtk);
printf( "Total nodes = %6d %6.2f Mb Changes = %6d.\n",
s_TotalNodes, s_TotalNodes * 20.0 / (1<<20), s_TotalChanges );
*/
}
/**Function*************************************************************
@ -644,7 +652,13 @@ void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary )
// transform logic functions from BDD to SOP
if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) )
Abc_NtkBddToSop(pNtk, 0);
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return;
}
}
// get hold of the SOP of the node
CountConst = CountBuf = CountInv = CountAnd = CountOr = CountOther = CounterTotal = 0;

View File

@ -20,6 +20,7 @@
#include "abc.h"
#include "fraig.h"
#include "math.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -32,10 +33,11 @@ extern Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
static Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, int * pRetValue, int * pNumFails );
static void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, int clk, int fVerbose );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Attempts to solve the miter using a number of tricks.]
@ -50,106 +52,126 @@ static void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, int clk, int fV
SeeAlso []
***********************************************************************/
int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, int nConfLimit, int nImpLimit, int fUseRewrite, int fUseFraig, int fVerbose )
int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
{
Prove_Params_t * pParams = pPars;
Abc_Ntk_t * pNtk, * pNtkTemp;
int nConfsStart = 1000, nImpsStart = 0, nBTLimitStart = 2; // was 5000
int nConfs, nImps, nBTLimit, RetValue, nSatFails;
int nIter = 0, clk, timeStart = clock();
int RetValue, nIter, Counter, clk, timeStart = clock();
// get the starting network
pNtk = *ppNtk;
assert( Abc_NtkIsStrash(pNtk) );
assert( Abc_NtkPoNum(pNtk) == 1 );
// set the initial limits
nConfs = !nConfLimit? nConfsStart : ABC_MIN( nConfsStart, nConfLimit );
nImps = !nImpLimit ? nImpsStart : ABC_MIN( nImpsStart , nImpLimit );
nBTLimit = nBTLimitStart;
if ( fVerbose )
printf( "Global resource limits: ConfsLim = %6d. ImpsLim = %d.\n", nConfLimit, nImpLimit );
if ( pParams->fVerbose )
{
printf( "RESOURCE LIMITS: Iterations = %d. Rewriting = %s. Fraiging = %s.\n",
pParams->nItersMax, pParams->fUseRewriting? "yes":"no", pParams->fUseFraiging? "yes":"no" );
printf( "Mitering = %d (%3.1f). Rewriting = %d (%3.1f). Fraiging = %d (%3.1f).\n",
pParams->nMiteringLimitStart, pParams->nMiteringLimitMulti,
pParams->nRewritingLimitStart, pParams->nRewritingLimitMulti,
pParams->nFraigingLimitStart, pParams->nFraigingLimitMulti );
printf( "Mitering last = %d.\n",
pParams->nMiteringLimitLast );
}
// if SAT only, solve without iteration
if ( !fUseRewrite && !fUseFraig )
if ( !pParams->fUseRewriting && !pParams->fUseFraiging )
{
clk = clock();
RetValue = Abc_NtkMiterSat( pNtk, nConfLimit, nImpLimit, 0 );
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, fVerbose );
RetValue = Abc_NtkMiterSat( pNtk, pParams->nMiteringLimitLast, 0, 0, 0 );
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
*ppNtk = pNtk;
return RetValue;
}
// check the current resource limits
do {
nIter++;
if ( fVerbose )
for ( nIter = 0; nIter < pParams->nItersMax; nIter++ )
{
if ( pParams->fVerbose )
{
printf( "ITERATION %2d : Confs = %6d. FraigBTL = %3d. \n", nIter, nConfs, nBTLimit );
printf( "ITERATION %2d : Confs = %6d. FraigBTL = %3d. \n", nIter+1,
(int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)),
(int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)) );
fflush( stdout );
}
// try brute-force SAT
clk = clock();
RetValue = Abc_NtkMiterSat( pNtk, nConfs, nImps, 0 );
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, fVerbose );
RetValue = Abc_NtkMiterSat( pNtk, (int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)), 0, 0, 0 );
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
if ( RetValue >= 0 )
break;
if ( fUseRewrite )
// try rewriting
if ( pParams->fUseRewriting )
{
clk = clock();
// try rewriting
Abc_NtkRewrite( pNtk, 0, 0, 0 );
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
break;
Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 );
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
break;
pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 ); Abc_NtkDelete( pNtkTemp );
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
break;
Abc_NtkMiterPrint( pNtk, "Rewriting ", clk, fVerbose );
Counter = (int)(pParams->nRewritingLimitStart * pow(pParams->nRewritingLimitMulti,nIter));
while ( 1 )
{
Abc_NtkRewrite( pNtk, 0, 0, 0 );
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
break;
if ( --Counter == 0 )
break;
Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 );
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
break;
if ( --Counter == 0 )
break;
pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 ); Abc_NtkDelete( pNtkTemp );
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
break;
if ( --Counter == 0 )
break;
}
Abc_NtkMiterPrint( pNtk, "Rewriting ", clk, pParams->fVerbose );
}
if ( fUseFraig )
if ( pParams->fUseFraiging )
{
int nSatFails;
// try FRAIGing
clk = clock();
pNtk = Abc_NtkMiterFraig( pNtkTemp = pNtk, nBTLimit, &RetValue, &nSatFails ); Abc_NtkDelete( pNtkTemp );
Abc_NtkMiterPrint( pNtk, "FRAIGing ", clk, fVerbose );
pNtk = Abc_NtkMiterFraig( pNtkTemp = pNtk, (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)), &RetValue, &nSatFails ); Abc_NtkDelete( pNtkTemp );
Abc_NtkMiterPrint( pNtk, "FRAIGing ", clk, pParams->fVerbose );
// printf( "NumFails = %d\n", nSatFails );
if ( RetValue >= 0 )
break;
}
else
nSatFails = 1000;
// increase resource limits
// nConfs = ABC_MIN( nConfs * 3 / 2, 1000000000 ); // was 4/2
nConfs = nSatFails * nBTLimit / 2;
nImps = ABC_MIN( nImps * 3 / 2, 1000000000 );
nBTLimit = ABC_MIN( nBTLimit * 8, 1000000000 );
// timeout at 5 minutes
// if ( clock() - timeStart >= 1200 * CLOCKS_PER_SEC )
// break;
if ( nIter == 7 )
break;
}
// while ( (nConfLimit == 0 || nConfs <= nConfLimit) &&
// (nImpLimit == 0 || nImps <= nImpLimit ) );
while ( 1 );
// try to prove it using brute force SAT
if ( RetValue < 0 && pParams->fUseBdds )
{
if ( pParams->fVerbose )
{
printf( "Attempting BDDs with node limit %d ...\n", pParams->nBddSizeLimit );
fflush( stdout );
}
clk = clock();
pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0 );
if ( pNtk )
{
Abc_NtkDelete( pNtkTemp );
RetValue = ( (Abc_NtkNodeNum(pNtk) == 1) && (Abc_ObjFanin0(Abc_NtkPo(pNtk,0))->pData == Cudd_ReadLogicZero(pNtk->pManFunc)) );
}
else
pNtk = pNtkTemp;
Abc_NtkMiterPrint( pNtk, "BDD building", clk, pParams->fVerbose );
}
if ( RetValue < 0 )
{
if ( pParams->fVerbose )
{
printf( "Attempting SAT with conflict limit %d ...\n", pParams->nMiteringLimitLast );
fflush( stdout );
}
clk = clock();
RetValue = Abc_NtkMiterSat( pNtk, nConfLimit, nImpLimit, 0 );
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, fVerbose );
RetValue = Abc_NtkMiterSat( pNtk, pParams->nMiteringLimitLast, 0, 0, 0 );
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
}
// assign the model if it was proved by rewriting (const 1 miter)
@ -240,7 +262,8 @@ void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, int clk, int fVerbose
{
if ( !fVerbose )
return;
printf( "Nodes = %7d. Levels = %4d. ", Abc_NtkNodeNum(pNtk), Abc_AigGetLevelNum(pNtk) );
printf( "Nodes = %7d. Levels = %4d. ", Abc_NtkNodeNum(pNtk),
Abc_NtkIsStrash(pNtk)? Abc_AigGetLevelNum(pNtk) : Abc_NtkGetLevelNum(pNtk) );
PRT( pString, clock() - clk );
}

View File

@ -132,6 +132,10 @@ clk = clock();
Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRef->nLastGain );
pManRef->timeNtk += clock() - clk;
Dec_GraphFree( pFForm );
// {
// extern int s_TotalChanges;
// s_TotalChanges++;
// }
}
Extra_ProgressBarStop( pProgress );
pManRef->timeTotal = clock() - clkStart;

View File

@ -74,7 +74,7 @@ static Dec_Graph_t * Abc_NodeRestructure( Abc_ManRst_t * p, Abc_Obj_t * pNode, C
static Dec_Graph_t * Abc_NodeRestructureCut( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCut );
static Dec_Graph_t * Abc_NodeEvaluateDsd( Abc_ManRst_t * pManRst, Dsd_Node_t * pNodeDsd, Abc_Obj_t * pRoot, int Required, int nNodesSaved, int * pnNodesAdded );
static Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fMulti );
static Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fDag );
static Abc_ManRst_t * Abc_NtkManRstStart( int nCutMax, bool fUpdateLevel, bool fUseZeros, bool fVerbose );
static void Abc_NtkManRstStop( Abc_ManRst_t * p );
static void Abc_NtkManRstPrintStats( Abc_ManRst_t * p );
@ -145,7 +145,7 @@ pManRst->timeCut += clock() - clk;
break;
// get the cuts for the given node
clk = clock();
pCutList = Abc_NodeGetCutsRecursive( pManCut, pNode, fMulti );
pCutList = Abc_NodeGetCutsRecursive( pManCut, pNode, fMulti, 0 );
pManRst->timeCut += clock() - clk;
// perform restructuring
@ -203,7 +203,7 @@ pManRst->timeTotal = clock() - clkStart;
***********************************************************************/
void Abc_RestructNodeDivisors( Abc_ManRst_t * p, Abc_Obj_t * pRoot, int nNodesSaved )
{
Abc_Obj_t * pNode, * pFanin, * pFanout;
Abc_Obj_t * pNode, * pFanout;//, * pFanin;
int i, k;
// start with the leaves
Vec_PtrClear( p->vDecs );
@ -276,7 +276,7 @@ Dec_Graph_t * Abc_NodeRestructure( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_
{
Dec_Graph_t * pGraph;
Cut_Cut_t * pCut;
int nCuts;
// int nCuts;
p->nNodesConsidered++;
/*
// count the number of cuts with four inputs or more
@ -949,7 +949,7 @@ Dec_Graph_t * Abc_NodeEvaluateDsd( Abc_ManRst_t * pManRst, Dsd_Node_t * pNodeDsd
SeeAlso []
***********************************************************************/
Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fMulti )
Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fDag )
{
static Cut_Params_t Params, * pParams = &Params;
Cut_Man_t * pManCut;
@ -963,7 +963,8 @@ Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fM
pParams->fFilter = 1; // filter dominated cuts
pParams->fSeq = 0; // compute sequential cuts
pParams->fDrop = 0; // drop cuts on the fly
pParams->fMulti = fMulti; // compute factor-cuts
pParams->fDag = fDag; // compute DAG cuts
pParams->fTree = 0; // compute tree cuts
pParams->fVerbose = 0; // the verbosiness flag
pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
pManCut = Cut_ManStart( pParams );
@ -1351,9 +1352,9 @@ Dec_Graph_t * Abc_NodeMffcSingleNode( Abc_ManRst_t * p, Vec_Int_t * vSims, int n
***********************************************************************/
Dec_Graph_t * Abc_NodeMffcDoubleNode( Abc_ManRst_t * p, Vec_Int_t * vSims, int nNodes, Vec_Int_t * vOnes )
{
Dec_Graph_t * pGraph;
unsigned uRoot, uNode;
int i;
// Dec_Graph_t * pGraph;
// unsigned uRoot, uNode;
// int i;
return NULL;

View File

@ -25,6 +25,9 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define ABC_RS_DIV1_MAX 150 // the max number of divisors to consider
#define ABC_RS_DIV2_MAX 500 // the max number of pair-wise divisors to consider
typedef struct Abc_ManRes_t_ Abc_ManRes_t;
struct Abc_ManRes_t_
{
@ -79,6 +82,7 @@ struct Abc_ManRes_t_
int nUsedNodeTotal;
int nTotalDivs;
int nTotalLeaves;
int nTotalGain;
};
// external procedures
@ -90,8 +94,8 @@ static void Abc_ManResubPrint( Abc_ManRes_t * p );
// other procedures
static int Abc_ManResubCollectDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int Required );
static int Abc_ManResubMffc( Abc_ManRes_t * p, Vec_Ptr_t * vDivs, Abc_Obj_t * pRoot, int nLeaves );
static void Abc_ManResubSimulate( Vec_Ptr_t * vDivs, int nLeaves, Vec_Ptr_t * vSims, int nLeavesMax, int nWords );
static void Abc_ManResubPrintDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves );
static void Abc_ManResubDivsS( Abc_ManRes_t * p, int Required );
static void Abc_ManResubDivsD( Abc_ManRes_t * p, int Required );
@ -136,13 +140,17 @@ int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, bool fUpd
// cleanup the AIG
Abc_AigCleanup(pNtk->pManFunc);
// start the managers
pManCut = Abc_NtkManCutStart( nCutMax, 10000, 100000, 100000 );
pManRes = Abc_ManResubStart( nCutMax, 200 );
pManCut = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 );
pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX );
// compute the reverse levels if level update is requested
if ( fUpdateLevel )
Abc_NtkStartReverseLevels( pNtk );
if ( Abc_NtkLatchNum(pNtk) )
Abc_NtkForEachLatch(pNtk, pNode, i)
pNode->pNext = pNode->pData;
// resynthesize each node once
nNodes = Abc_NtkObjNumMax(pNtk);
pProgress = Extra_ProgressBarStart( stdout, nNodes );
@ -179,13 +187,16 @@ clk = clock();
pManRes->timeRes += clock() - clk;
if ( pFForm == NULL )
continue;
pManRes->nTotalGain += pManRes->nLastGain;
/*
if ( pNode->Id % 25 == 0 )
if ( pManRes->nLeaves == 4 && pManRes->nMffc == 2 && pManRes->nLastGain == 1 )
{
printf( "%6d : L = %2d. V = %2d. Mffc = %2d. Divs = %3d. Up = %3d. Un = %3d. B = %3d.\n",
pNode->Id, pManRes->nLeaves, Abc_CutVolumeCheck(pNode, vLeaves), pManRes->nMffc, pManRes->nDivs,
pManRes->vDivs1UP->nSize, pManRes->vDivs1UN->nSize, pManRes->vDivs1B->nSize );
Abc_ManResubPrintDivs( pManRes, pNode, vLeaves );
}
*/
// acceptable replacement found, update the graph
clk = clock();
Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRes->nLastGain );
@ -207,6 +218,10 @@ pManRes->timeTotal = clock() - clkStart;
Abc_NtkForEachObj( pNtk, pNode, i )
pNode->pData = NULL;
if ( Abc_NtkLatchNum(pNtk) )
Abc_NtkForEachLatch(pNtk, pNode, i)
pNode->pData = pNode->pNext, pNode->pNext = NULL;
// put the nodes into the DFS order and reassign their IDs
Abc_NtkReassignIds( pNtk );
// Abc_AigCheckFaninOrder( pNtk->pManFunc );
@ -340,6 +355,7 @@ void Abc_ManResubPrint( Abc_ManRes_t * p )
); PRT( "TOTAL ", p->timeTotal );
printf( "Total leaves = %8d.\n", p->nTotalLeaves );
printf( "Total divisors = %8d.\n", p->nTotalDivs );
printf( "Total gain = %8d.\n", p->nTotalGain );
}
@ -382,7 +398,7 @@ void Abc_ManResubCollectDivs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vInternal )
***********************************************************************/
int Abc_ManResubCollectDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int Required )
{
Abc_Obj_t * pNode, * pFanout;//, * pFanin;
Abc_Obj_t * pNode, * pFanout;
int i, k, Limit, Counter;
Vec_PtrClear( p->vDivs1UP );
@ -451,10 +467,24 @@ Quits :
assert( pRoot == Vec_PtrEntryLast(p->vDivs) );
assert( Vec_PtrSize(p->vDivs) - Vec_PtrSize(vLeaves) <= Vec_PtrSize(p->vSims) - p->nLeavesMax );
return 1;
}
/*
if (pRoot->Id == 15281 )
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ManResubPrintDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves )
{
Abc_Obj_t * pFanin, * pNode;
int i, k;
// print the nodes
Vec_PtrForEachEntry( p->vDivs, pNode, i )
{
@ -488,59 +518,7 @@ if (pRoot->Id == 15281 )
}
printf( "\n" );
}
*/
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_ManResubMffc( Abc_ManRes_t * p, Vec_Ptr_t * vDivs, Abc_Obj_t * pRoot, int nLeaves )
{
Abc_Obj_t * pObj;
int Counter, i, k;
// increment the traversal ID for the leaves
// increment the fanout counters of the leaves
Abc_NtkIncrementTravId( pRoot->pNtk );
Vec_PtrForEachEntryStop( vDivs, pObj, i, nLeaves )
{
pObj->vFanouts.nSize++;
Abc_NodeSetTravIdCurrent( pObj );
}
// make sure the node is in the cone and is no one of the leaves
assert( Abc_NodeIsTravIdPrevious(pRoot) );
Counter = Abc_NodeMffcLabel( pRoot );
// remove the extra counters
Vec_PtrForEachEntryStop( vDivs, pObj, i, nLeaves )
pObj->vFanouts.nSize--;
// sort the nodes by level!!!
// move the labeled nodes to the end
Vec_PtrClear( p->vTemp );
k = nLeaves;
Vec_PtrForEachEntryStart( vDivs, pObj, i, nLeaves )
if ( Abc_NodeIsTravIdCurrent(pObj) )
Vec_PtrPush( p->vTemp, pObj );
else
Vec_PtrWriteEntry( vDivs, k++, pObj );
// add the labeled nodes
Vec_PtrForEachEntry( p->vTemp, pObj, i )
Vec_PtrWriteEntry( vDivs, k++, pObj );
assert( k == Vec_PtrSize(p->vDivs) );
assert( pRoot == Vec_PtrEntryLast(p->vDivs) );
return Counter;
}
/**Function*************************************************************
@ -928,7 +906,7 @@ void Abc_ManResubDivsD( Abc_ManRes_t * p, int Required )
puData1 = pObj1->pData;
if ( Vec_PtrSize(p->vDivs2UP0) < 500 )
if ( Vec_PtrSize(p->vDivs2UP0) < ABC_RS_DIV2_MAX )
{
// get positive unate divisors
for ( w = 0; w < p->nWords; w++ )
@ -965,7 +943,7 @@ void Abc_ManResubDivsD( Abc_ManRes_t * p, int Required )
}
}
if ( Vec_PtrSize(p->vDivs2UN0) < 500 )
if ( Vec_PtrSize(p->vDivs2UN0) < ABC_RS_DIV2_MAX )
{
// get negative unate divisors
for ( w = 0; w < p->nWords; w++ )

View File

@ -110,6 +110,10 @@ clk = clock();
Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain );
Rwr_ManAddTimeUpdate( pManRwr, clock() - clk );
if ( fCompl ) Dec_GraphComplement( pGraph );
// {
// extern int s_TotalChanges;
// s_TotalChanges++;
// }
}
}
Extra_ProgressBarStop( pProgress );

601
src/base/abci/abcRr.c Normal file
View File

@ -0,0 +1,601 @@
/**CFile****************************************************************
FileName [abcRr.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Redundancy removal.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcRr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
#include "fraig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef struct Abc_RRMan_t_ Abc_RRMan_t;
struct Abc_RRMan_t_
{
// the parameters
Abc_Ntk_t * pNtk; // the network
int nFaninLevels; // the number of fanin levels
int nFanoutLevels; // the number of fanout levels
// the node/fanin/fanout
Abc_Obj_t * pNode; // the node
Abc_Obj_t * pFanin; // the fanin
Abc_Obj_t * pFanout; // the fanout
// the intermediate cones
Vec_Ptr_t * vFaninLeaves; // the leaves of the fanin cone
Vec_Ptr_t * vFanoutRoots; // the roots of the fanout cone
// the window
Vec_Ptr_t * vLeaves; // the leaves of the window
Vec_Ptr_t * vCone; // the internal nodes of the window
Vec_Ptr_t * vRoots; // the roots of the window
Abc_Ntk_t * pWnd; // the window derived for the edge
// the miter
Abc_Ntk_t * pMiter; // the miter derived from the window
Prove_Params_t * pParams; // the miter proving parameters
};
static Abc_RRMan_t * Abc_RRManStart();
static void Abc_RRManStop( Abc_RRMan_t * p );
static void Abc_RRManClean( Abc_RRMan_t * p );
static int Abc_NtkRRProve( Abc_RRMan_t * p );
static int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Abc_Obj_t * pFanout );
static int Abc_NtkRRWindow( Abc_RRMan_t * p );
static int Abc_NtkRRTfi_int( Vec_Ptr_t * vFaninLeaves, int LevelLimit );
static int Abc_NtkRRTfo_int( Vec_Ptr_t * vFanoutRoots, int LevelLimit, Abc_Obj_t * pEdgeFanin, Abc_Obj_t * pEdgeFanout );
static int Abc_NtkRRTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vRoots, int LevelLimit );
static void Abc_NtkRRTfi_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone );
static Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vRoots );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Removes stuck-at redundancies.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRR( Abc_Ntk_t * pNtk, int nFaninLevels, int nFanoutLevels, int fUseFanouts, int fVerbose )
{
ProgressBar * pProgress;
Abc_RRMan_t * p;
Abc_Obj_t * pNode, * pFanin, * pFanout;
int i, k, m, nNodes;
// start the manager
p = Abc_RRManStart( nFaninLevels, nFanoutLevels );
p->pNtk = pNtk;
p->nFaninLevels = nFaninLevels;
p->nFanoutLevels = nFanoutLevels;
// go through the nodes
nNodes = Abc_NtkObjNumMax(pNtk);
pProgress = Extra_ProgressBarStart( stdout, nNodes );
Abc_NtkForEachNode( pNtk, pNode, i )
{
Extra_ProgressBarUpdate( pProgress, i, NULL );
// stop if all nodes have been tried once
if ( i >= nNodes )
break;
// skip the constant node
if ( Abc_NodeIsConst(pNode) )
continue;
// skip the nodes with many fanouts
if ( Abc_ObjFanoutNum(pNode) > 1000 )
continue;
// construct the window
if ( !fUseFanouts )
{
Abc_ObjForEachFanin( pNode, pFanin, k )
{
Abc_RRManClean( p );
p->pNode = pNode;
p->pFanin = pFanin;
p->pFanout = NULL;
if ( !Abc_NtkRRWindow( p ) )
continue;
if ( !Abc_NtkRRProve( p ) )
continue;
Abc_NtkRRUpdate( pNtk, p->pNode, p->pFanin, p->pFanout );
break;
}
continue;
}
// use the fanouts
Abc_ObjForEachFanout( pNode, pFanout, m )
Abc_ObjForEachFanin( pNode, pFanin, k )
{
Abc_RRManClean( p );
p->pNode = pNode;
p->pFanin = pFanin;
p->pFanout = pFanout;
if ( !Abc_NtkRRWindow( p ) )
continue;
if ( !Abc_NtkRRProve( p ) )
continue;
Abc_NtkRRUpdate( pNtk, p->pNode, p->pFanin, p->pFanout );
break;
}
}
Extra_ProgressBarStop( pProgress );
Abc_RRManStop( p );
// put the nodes into the DFS order and reassign their IDs
Abc_NtkReassignIds( pNtk );
Abc_NtkGetLevelNum( pNtk );
// check
if ( !Abc_NtkCheck( pNtk ) )
{
printf( "Abc_NtkRR: The network check has failed.\n" );
return 0;
}
return 1;
}
/**Function*************************************************************
Synopsis [Start the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_RRMan_t * Abc_RRManStart()
{
Abc_RRMan_t * p;
p = ALLOC( Abc_RRMan_t, 1 );
memset( p, 0, sizeof(Abc_RRMan_t) );
p->vFaninLeaves = Vec_PtrAlloc( 100 ); // the leaves of the fanin cone
p->vFanoutRoots = Vec_PtrAlloc( 100 ); // the roots of the fanout cone
p->vLeaves = Vec_PtrAlloc( 100 ); // the leaves of the window
p->vCone = Vec_PtrAlloc( 100 ); // the internal nodes of the window
p->vRoots = Vec_PtrAlloc( 100 ); // the roots of the window
p->pParams = ALLOC( Prove_Params_t, 1 );
memset( p->pParams, 0, sizeof(Prove_Params_t) );
Prove_ParamsSetDefault( p->pParams );
return p;
}
/**Function*************************************************************
Synopsis [Stop the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_RRManStop( Abc_RRMan_t * p )
{
Abc_RRManClean( p );
Vec_PtrFree( p->vFaninLeaves );
Vec_PtrFree( p->vFanoutRoots );
Vec_PtrFree( p->vLeaves );
Vec_PtrFree( p->vCone );
Vec_PtrFree( p->vRoots );
free( p->pParams );
free( p );
}
/**Function*************************************************************
Synopsis [Clean the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_RRManClean( Abc_RRMan_t * p )
{
p->pNode = NULL;
p->pFanin = NULL;
p->pFanout = NULL;
Vec_PtrClear( p->vFaninLeaves );
Vec_PtrClear( p->vFanoutRoots );
Vec_PtrClear( p->vLeaves );
Vec_PtrClear( p->vCone );
Vec_PtrClear( p->vRoots );
if ( p->pWnd ) Abc_NtkDelete( p->pWnd );
if ( p->pMiter ) Abc_NtkDelete( p->pMiter );
p->pWnd = NULL;
p->pMiter = NULL;
}
/**Function*************************************************************
Synopsis [Returns 1 if the miter is constant 0.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRRProve( Abc_RRMan_t * p )
{
Abc_Ntk_t * pWndCopy;
int RetValue;
pWndCopy = Abc_NtkDup( p->pWnd );
Abc_NtkRRUpdate( pWndCopy, p->pNode->pCopy, p->pFanin->pCopy, p->pFanout? p->pFanout->pCopy : NULL );
p->pMiter = Abc_NtkMiter( p->pWnd, pWndCopy, 1 );
RetValue = Abc_NtkMiterProve( &p->pMiter, p->pParams );
if ( RetValue == 1 )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Updates the network after redundancy removal.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Abc_Obj_t * pFanout )
{
Abc_Obj_t * pNodeNew, * pFanoutNew;
assert( pFanout == NULL );
assert( !Abc_ObjIsComplement(pNode) );
assert( !Abc_ObjIsComplement(pFanin) );
assert( !Abc_ObjIsComplement(pFanout) );
// find the node after redundancy removal
if ( pFanin == Abc_ObjFanin0(pNode) )
pNodeNew = Abc_ObjChild1(pNode);
else if ( pFanin == Abc_ObjFanin1(pNode) )
pNodeNew = Abc_ObjChild0(pNode);
else assert( 0 );
// replace
if ( pFanout == NULL )
{
Abc_AigReplace( pNtk->pManFunc, pNode, pNodeNew, 0 );
return 1;
}
// find the fanout after redundancy removal
if ( pNode == Abc_ObjFanin0(pFanout) )
pFanoutNew = Abc_AigAnd( pNtk->pManFunc, Abc_ObjNotCond(pNodeNew,Abc_ObjFaninC0(pFanout)), Abc_ObjChild1(pFanout) );
else if ( pNode == Abc_ObjFanin1(pFanout) )
pFanoutNew = Abc_AigAnd( pNtk->pManFunc, Abc_ObjNotCond(pNodeNew,Abc_ObjFaninC1(pFanout)), Abc_ObjChild0(pFanout) );
else assert( 0 );
// replace
Abc_AigReplace( pNtk->pManFunc, pFanout, pFanoutNew, 0 );
return 1;
}
/**Function*************************************************************
Synopsis [Constructs window for checking RR.]
Description [If the window (p->pWnd) with the given scope (p->nFaninLevels,
p->nFanoutLevels) cannot be constructed, returns 0. Otherwise, returns 1.
The levels are measured from the fanin node (pFanin) and the fanout node
(pEdgeFanout), respectively.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRRWindow( Abc_RRMan_t * p )
{
Abc_Obj_t * pObj, * pFanout, * pEdgeFanin, * pEdgeFanout;
int i, k;
// get the edge
pEdgeFanout = p->pFanout? p->pFanout : p->pNode;
pEdgeFanin = p->pFanout? p->pNode : p->pFanin;
// start the TFI leaves with the fanin
Abc_NtkIncrementTravId( p->pNtk );
Abc_NodeSetTravIdCurrent( p->pFanin );
Vec_PtrPush( p->vFaninLeaves, p->pFanin );
// mark the TFI cone and collect the leaves down to the given level
while ( Abc_NtkRRTfi_int(p->vFaninLeaves, p->pFanin->Level - p->nFaninLevels) );
// collect the TFO cone of the leaves
Abc_NtkIncrementTravId( p->pNtk );
Vec_PtrForEachEntry( p->vFaninLeaves, pObj, i )
{
Abc_ObjForEachFanout( pObj, pFanout, k )
{
if ( !Abc_ObjIsNode(pFanout) )
continue;
if ( pFanout->Level > pEdgeFanout->Level + p->nFanoutLevels )
continue;
if ( Abc_NodeIsTravIdCurrent(pFanout) )
continue;
Abc_NodeSetTravIdCurrent( pFanout );
Vec_PtrPush( p->vFanoutRoots, pFanout );
}
}
// mark the TFO cone and collect the leaves up to the given level (while skipping the edge)
while ( Abc_NtkRRTfo_int(p->vFanoutRoots, pEdgeFanout->Level + p->nFanoutLevels, pEdgeFanin, pEdgeFanout) );
// unmark the nodes
Vec_PtrForEachEntry( p->vFanoutRoots, pObj, i )
pObj->fMarkA = 0;
// mark the current roots
Abc_NtkIncrementTravId( p->pNtk );
Vec_PtrForEachEntry( p->vFanoutRoots, pObj, i )
Abc_NodeSetTravIdCurrent( pObj );
// collect roots reachable from the fanout (p->vRoots)
if ( !Abc_NtkRRTfo_rec( pEdgeFanout, p->vRoots, pEdgeFanout->Level + p->nFanoutLevels + 5 ) )
return 0;
// collect the DFS-ordered new cone (p->vCone) and new leaves (p->vLeaves)
// using the previous marks coming from the TFO cone
Vec_PtrForEachEntry( p->vRoots, pObj, i )
Abc_NtkRRTfi_rec( pObj, p->vLeaves, p->vCone );
// unmark the nodes
Vec_PtrForEachEntry( p->vCone, pObj, i )
pObj->fMarkA = 0;
Vec_PtrForEachEntry( p->vLeaves, pObj, i )
pObj->fMarkA = 0;
// create a new network
p->pWnd = Abc_NtkWindow( p->pNtk, p->vLeaves, p->vCone, p->vRoots );
return 1;
}
/**Function*************************************************************
Synopsis [Marks the nodes in the TFI and collects their leaves.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRRTfi_int( Vec_Ptr_t * vFaninLeaves, int LevelLimit )
{
Abc_Obj_t * pObj, * pNext;
int i, k, LevelMax, nSize;
// find the maximum level of leaves
LevelMax = 0;
Vec_PtrForEachEntry( vFaninLeaves, pObj, i )
if ( LevelMax < (int)pObj->Level )
LevelMax = pObj->Level;
// if the nodes are all PIs, LevelMax == 0
if ( LevelMax == 0 || LevelMax <= LevelLimit )
return 0;
// expand the nodes with the minimum level
nSize = Vec_PtrSize(vFaninLeaves);
Vec_PtrForEachEntryStop( vFaninLeaves, pObj, i, nSize )
{
if ( LevelMax != (int)pObj->Level )
continue;
Abc_ObjForEachFanin( pObj, pNext, k )
{
if ( Abc_NodeIsTravIdCurrent(pNext) )
continue;
Abc_NodeSetTravIdCurrent( pNext );
Vec_PtrPush( vFaninLeaves, pNext );
}
}
// remove old nodes (cannot remove a PI)
k = 0;
Vec_PtrForEachEntry( vFaninLeaves, pObj, i )
{
if ( LevelMax == (int)pObj->Level )
continue;
Vec_PtrWriteEntry( vFaninLeaves, k++, pObj );
}
Vec_PtrShrink( vFaninLeaves, k );
return 1;
}
/**Function*************************************************************
Synopsis [Marks the nodes in the TFO and collects their roots.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRRTfo_int( Vec_Ptr_t * vFanoutRoots, int LevelLimit, Abc_Obj_t * pEdgeFanin, Abc_Obj_t * pEdgeFanout )
{
Abc_Obj_t * pObj, * pNext;
int i, k, LevelMin, nSize;
// find the minimum level of roots
LevelMin = ABC_INFINITY;
Vec_PtrForEachEntry( vFanoutRoots, pObj, i )
if ( Abc_ObjIsNode(pObj) && !pObj->fMarkA && LevelMin > (int)pObj->Level )
LevelMin = pObj->Level;
// if the nodes are all POs, LevelMin == ABC_INFINITY
if ( LevelMin == ABC_INFINITY || LevelMin > LevelLimit )
return 0;
// expand the nodes with the minimum level
nSize = Vec_PtrSize(vFanoutRoots);
Vec_PtrForEachEntryStop( vFanoutRoots, pObj, i, nSize )
{
if ( LevelMin != (int)pObj->Level )
continue;
Abc_ObjForEachFanout( pObj, pNext, k )
{
if ( !Abc_ObjIsNode(pNext) || pNext->Level > (unsigned)LevelLimit )
{
pObj->fMarkA = 1;
continue;
}
if ( pObj == pEdgeFanin && pNext == pEdgeFanout )
continue;
if ( Abc_NodeIsTravIdCurrent(pNext) )
continue;
Abc_NodeSetTravIdCurrent( pNext );
Vec_PtrPush( vFanoutRoots, pNext );
}
}
// remove old nodes
k = 0;
Vec_PtrForEachEntry( vFanoutRoots, pObj, i )
{
if ( LevelMin == (int)pObj->Level )
{
// check if the node has external fanouts
Abc_ObjForEachFanout( pObj, pNext, k )
{
if ( pObj == pEdgeFanin && pNext == pEdgeFanout )
continue;
if ( !Abc_NodeIsTravIdCurrent(pNext) )
break;
}
// if external fanout is found, do not remove the node
if ( pNext )
continue;
}
Vec_PtrWriteEntry( vFanoutRoots, k++, pObj );
}
Vec_PtrShrink( vFanoutRoots, k );
return 1;
}
/**Function*************************************************************
Synopsis [Collects the roots in the TFO of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkRRTfo_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vRoots, int LevelLimit )
{
Abc_Obj_t * pFanout;
int i;
if ( Abc_ObjIsCo(pNode) || pNode->Level > (unsigned)LevelLimit )
return 0;
if ( Abc_NodeIsTravIdCurrent(pNode) )
{
Vec_PtrPushUnique( vRoots, pNode );
return 1;
}
Abc_NodeSetTravIdCurrent( pNode );
Abc_ObjForEachFanout( pNode, pFanout, i )
if ( !Abc_NtkRRTfo_rec( pFanout, vRoots, LevelLimit ) )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkRRTfi_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
{
Abc_Obj_t * pFanin;
int i;
// skip visited nodes
if ( pNode->fMarkA )
return;
pNode->fMarkA = 1;
// add the node if it was not visited in the previus run
if ( !Abc_NodeIsTravIdPrevious(pNode) )
{
Vec_PtrPush( vLeaves, pNode );
return;
}
Abc_ObjForEachFanin( pNode, pFanin, i )
Abc_NtkRRTfi_rec( pFanin, vLeaves, vCone );
Vec_PtrPush( vCone, pNode );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkWindow( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vRoots )
{
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkIsStrash(pNtk) );
// start the network
pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc );
// duplicate the name and the spec
pNtkNew->pName = Extra_UtilStrsav( "temp" );
// map the constant nodes
if ( Abc_NtkConst1(pNtk) )
Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
// create and map the PIs
Vec_PtrForEachEntry( vLeaves, pObj, i )
pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
// copy the AND gates
Vec_PtrForEachEntry( vCone, pObj, i )
pObj->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
// compare the number of nodes before and after
if ( Vec_PtrSize(vCone) != Abc_NtkNodeNum(pNtkNew) )
printf( "Warning: Structural hashing during windowing reduced %d nodes (this is a bug).\n",
Vec_PtrSize(vCone) - Abc_NtkNodeNum(pNtkNew) );
// create the POs
Vec_PtrForEachEntry( vRoots, pObj, i )
Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pObj->pCopy );
// add the PI/PO names
Abc_NtkAddDummyPiNames( pNtkNew );
Abc_NtkAddDummyPoNames( pNtkNew );
// check
if ( !Abc_NtkCheck( pNtkNew ) )
{
printf( "Abc_NtkWindow: The network check has failed.\n" );
return NULL;
}
return pNtkNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -24,7 +24,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk );
extern Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk );
static nMuxes;
////////////////////////////////////////////////////////////////////////
@ -42,7 +42,7 @@ static nMuxes;
SeeAlso []
***********************************************************************/
int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fVerbose )
int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fJFront, int fVerbose )
{
solver * pSat;
lbool status;
@ -56,7 +56,7 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fVerbo
// load clauses into the solver
clk = clock();
pSat = Abc_NtkMiterSatCreate( pNtk );
pSat = Abc_NtkMiterSatCreate( pNtk, fJFront );
if ( pSat == NULL )
return 1;
// printf( "Created SAT problem with %d variable and %d clauses. ", solver_nvars(pSat), solver_nclauses(pSat) );
@ -107,6 +107,8 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nConfLimit, int nImpLimit, int fVerbo
Vec_IntFree( vCiIds );
}
// free the solver
if ( fVerbose )
Asat_SatPrintStats( stdout, pSat );
solver_delete( pSat );
return RetValue;
}
@ -391,12 +393,14 @@ void Abc_NtkCollectSupergate( Abc_Obj_t * pNode, int fStopAtMux, Vec_Ptr_t * vNo
SeeAlso []
***********************************************************************/
int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk )
int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
{
Abc_Obj_t * pNode, * pFanin, * pNodeC, * pNodeT, * pNodeE;
Vec_Ptr_t * vNodes, * vSuper;
Vec_Int_t * vVars;
Vec_Int_t * vVars, * vFanio;
Vec_Vec_t * vCircuit;
int i, k, fUseMuxes = 1;
int clk1 = clock(), clk;
assert( Abc_NtkIsStrash(pNtk) );
@ -408,6 +412,9 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk )
vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver
vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate
vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause
if ( fJFront )
vCircuit = Vec_VecAlloc( 1000 );
// vCircuit = Vec_VecStart( 184 );
// add the clause for the constant node
pNode = Abc_NtkConst1(pNtk);
@ -485,6 +492,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk )
if ( vSuper->nSize == 0 )
{
if ( !Abc_NtkClauseTriv( pSat, Abc_ObjNot(pNode), vVars ) )
// if ( !Abc_NtkClauseTriv( pSat, pNode, vVars ) )
return 0;
}
else
@ -493,6 +501,32 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk )
return 0;
}
}
// add the variables to the J-frontier
if ( !fJFront )
continue;
// make sure that the fanin entries go first
assert( pNode->pCopy );
Vec_VecExpand( vCircuit, (int)pNode->pCopy );
vFanio = Vec_VecEntry( vCircuit, (int)pNode->pCopy );
Vec_PtrForEachEntryReverse( vSuper, pFanin, k )
// Vec_PtrForEachEntry( vSuper, pFanin, k )
{
pFanin = Abc_ObjRegular( pFanin );
assert( pFanin->pCopy && pFanin->pCopy != pNode->pCopy );
Vec_IntPushFirst( vFanio, (int)pFanin->pCopy );
Vec_VecPush( vCircuit, (int)pFanin->pCopy, pNode->pCopy );
}
}
// create the variable order
if ( fJFront )
{
clk = clock();
Asat_JManStart( pSat, vCircuit );
Vec_VecFree( vCircuit );
PRT( "Setup", clock() - clk );
// Asat_JManStop( pSat );
// PRT( "Total", clock() - clk1 );
}
// delete
@ -513,7 +547,7 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk )
solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fJFront )
{
solver * pSat;
Abc_Obj_t * pNode;
@ -522,7 +556,7 @@ solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk )
nMuxes = 0;
pSat = solver_new();
RetValue = Abc_NtkMiterSatCreateInt( pSat, pNtk );
RetValue = Abc_NtkMiterSatCreateInt( pSat, pNtk, fJFront );
Abc_NtkForEachObj( pNtk, pNode, i )
pNode->fMarkA = 0;
// Asat_SolverWriteDimacs( pSat, "temp_sat.cnf", NULL, NULL, 1 );

View File

@ -58,7 +58,13 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
assert( !Abc_NtkIsNetlist(pNtk) );
assert( !Abc_NtkIsSeq(pNtk) );
if ( Abc_NtkIsBddLogic(pNtk) )
Abc_NtkBddToSop(pNtk, 0);
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return NULL;
}
}
// print warning about choice nodes
if ( Abc_NtkGetChoiceNum( pNtk ) )
printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
@ -72,7 +78,9 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
// if ( Abc_NtkCountSelfFeedLatches(pNtkAig) )
// printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
{
// printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
}
// duplicate EXDC
if ( pNtk->pExdc )
pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
@ -108,7 +116,13 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
assert( Abc_NtkIsStrash(pNtk1) );
assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) );
if ( Abc_NtkIsBddLogic(pNtk2) )
Abc_NtkBddToSop(pNtk2, 0);
{
if ( !Abc_NtkBddToSop(pNtk2, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return 0;
}
}
// check that the networks have the same PIs
// reorder PIs of pNtk2 according to pNtk1
if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1 ) )
@ -163,6 +177,7 @@ void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes
assert( pObj->pCopy == NULL );
// mark the old object with the new AIG node
pObj->pCopy = pNodeNew;
Abc_HManAddProto( pObj->pCopy, pObj );
}
Vec_PtrFree( vNodes );
Extra_ProgressBarStop( pProgress );

View File

@ -88,7 +88,7 @@ void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose )
// compute the global functions
clk = clock();
dd = Abc_NtkGlobalBdds( pNtk, 10000000, 0 );
dd = Abc_NtkGlobalBdds( pNtk, 10000000, 0, 1, fVerbose );
Cudd_AutodynDisable( dd );
Cudd_zddVarsFromBddVars( dd, 2 );
clkBdd = clock() - clk;

804
src/base/abci/abcTrace.c Normal file
View File

@ -0,0 +1,804 @@
/**CFile****************************************************************
FileName [abcHistory.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcHistory.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abc.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define ABC_SIM_VARS 16 // the max number of variables in the cone
#define ABC_SIM_OBJS 200 // the max number of objects in the cone
typedef struct Abc_HMan_t_ Abc_HMan_t;
typedef struct Abc_HObj_t_ Abc_HObj_t;
typedef struct Abc_HNum_t_ Abc_HNum_t;
struct Abc_HNum_t_
{
unsigned fCompl : 1; // set to 1 if the node is complemented
unsigned NtkId : 6; // the network ID
unsigned ObjId : 24; // the node ID
};
struct Abc_HObj_t_
{
// object info
unsigned fProof : 1; // set to 1 if the node is proved
unsigned fPhase : 1; // set to 1 if the node's phase differs from Old
unsigned fPi : 1; // the node is a PI
unsigned fPo : 1; // the node is a PO
unsigned fConst : 1; // the node is a constant
unsigned fVisited: 1; // the flag shows if the node is visited
unsigned NtkId : 10; // the network ID
unsigned Num : 16; // a temporary number
// history record
Abc_HNum_t Fan0; // immediate fanin
Abc_HNum_t Fan1; // immediate fanin
Abc_HNum_t Proto; // old node if present
// Abc_HNum_t Equ; // equiv node if present
};
struct Abc_HMan_t_
{
// storage for history information
Vec_Vec_t * vNtks; // the history nodes belonging to each network
Vec_Int_t * vProof; // flags showing if the network is proved
// storage for simulation info
int nVarsMax; // the max number of cone leaves
int nObjsMax; // the max number of cone nodes
Vec_Ptr_t * vObjs; // the cone nodes
int nBits; // the number of simulation bits
int nWords; // the number of unsigneds for siminfo
int nWordsCur; // the current number of words
Vec_Ptr_t * vSims; // simulation info
unsigned * pInfo; // pointer to simulation info
// other info
Vec_Ptr_t * vCone0;
Vec_Ptr_t * vCone1;
// memory manager
Extra_MmFixed_t* pMmObj; // memory manager for objects
};
static Abc_HMan_t * s_pHMan = NULL;
static inline int Abc_HObjProof( Abc_HObj_t * p ) { return p->fProof; }
static inline int Abc_HObjPhase( Abc_HObj_t * p ) { return p->fPhase; }
static inline int Abc_HObjPi ( Abc_HObj_t * p ) { return p->fPi; }
static inline int Abc_HObjPo ( Abc_HObj_t * p ) { return p->fPo; }
static inline int Abc_HObjConst( Abc_HObj_t * p ) { return p->fConst; }
static inline int Abc_HObjNtkId( Abc_HObj_t * p ) { return p->NtkId; }
static inline int Abc_HObjNum ( Abc_HObj_t * p ) { return p->Num; }
static inline Abc_HObj_t * Abc_HObjFanin0( Abc_HObj_t * p ) { return !p->Fan0.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Fan0.NtkId), p->Fan0.ObjId ); }
static inline Abc_HObj_t * Abc_HObjFanin1( Abc_HObj_t * p ) { return !p->Fan1.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Fan1.NtkId), p->Fan1.ObjId ); }
static inline Abc_HObj_t * Abc_HObjProto ( Abc_HObj_t * p ) { return !p->Proto.NtkId ? NULL : Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->Proto.NtkId), p->Proto.ObjId ); }
static inline int Abc_HObjFaninC0( Abc_HObj_t * p ) { return p->Fan0.fCompl; }
static inline int Abc_HObjFaninC1( Abc_HObj_t * p ) { return p->Fan1.fCompl; }
static inline Abc_HObj_t * Abc_ObjHObj( Abc_Obj_t * p ) { return Vec_PtrEntry( Vec_VecEntry(s_pHMan->vNtks, p->pNtk->Id), p->Id ); }
static int Abc_HManVerifyPair( int NtkIdOld, int NtkIdNew );
static int Abc_HManVerifyNodes_rec( Abc_HObj_t * pHOld, Abc_HObj_t * pHNew );
static Vec_Ptr_t * Abc_HManCollectLeaves( Abc_HObj_t * pHNew );
static Vec_Ptr_t * Abc_HManCollectCone( Abc_HObj_t * pHOld, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone );
static int Abc_HManSimulate( Vec_Ptr_t * vCone0, Vec_Ptr_t * vCone1, int nLeaves, int * pPhase );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManStart()
{
Abc_HMan_t * p;
unsigned * pData;
int i, k;
assert( s_pHMan == NULL );
assert( sizeof(unsigned) == 4 );
// allocate manager
p = ALLOC( Abc_HMan_t, 1 );
memset( p, 0, sizeof(Abc_HMan_t) );
// allocate storage for all nodes
p->vNtks = Vec_VecStart( 1 );
p->vProof = Vec_IntStart( 1 );
// allocate temporary storage for objects
p->nVarsMax = ABC_SIM_VARS;
p->nObjsMax = ABC_SIM_OBJS;
p->vObjs = Vec_PtrAlloc( p->nObjsMax );
// allocate simulation info
p->nBits = (1 << p->nVarsMax);
p->nWords = (p->nBits <= 32)? 1 : (p->nBits / 32);
p->pInfo = ALLOC( unsigned, p->nWords * p->nObjsMax );
memset( p->pInfo, 0, sizeof(unsigned) * p->nWords * p->nVarsMax );
p->vSims = Vec_PtrAlloc( p->nObjsMax );
for ( i = 0; i < p->nObjsMax; i++ )
Vec_PtrPush( p->vSims, p->pInfo + i * p->nWords );
// set elementary truth tables
for ( k = 0; k < p->nVarsMax; k++ )
{
pData = p->vSims->pArray[k];
for ( i = 0; i < p->nBits; i++ )
if ( i & (1 << k) )
pData[i/32] |= (1 << (i%32));
}
// allocate storage for the nodes
p->pMmObj = Extra_MmFixedStart( sizeof(Abc_HObj_t) );
p->vCone0 = Vec_PtrAlloc( p->nObjsMax );
p->vCone1 = Vec_PtrAlloc( p->nObjsMax );
s_pHMan = p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManStop()
{
assert( s_pHMan != NULL );
Extra_MmFixedStop( s_pHMan->pMmObj, 0 );
Vec_PtrFree( s_pHMan->vObjs );
Vec_PtrFree( s_pHMan->vSims );
Vec_VecFree( s_pHMan->vNtks );
Vec_IntFree( s_pHMan->vProof );
Vec_PtrFree( s_pHMan->vCone0 );
Vec_PtrFree( s_pHMan->vCone1 );
free( s_pHMan->pInfo );
free( s_pHMan );
s_pHMan = NULL;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManIsRunning()
{
return s_pHMan != NULL;
}
/**Function*************************************************************
Synopsis [Called when a new network is created.]
Description [Returns the new ID for the network.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManGetNewNtkId()
{
if ( s_pHMan == NULL )
return 0;
return Vec_VecSize( s_pHMan->vNtks ); // what if the new network has no nodes?
}
/**Function*************************************************************
Synopsis [Called when the object is created.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManAddObj( Abc_Obj_t * pObj )
{
Abc_HObj_t * pHObj;
if ( s_pHMan == NULL )
return;
pHObj = (Abc_HObj_t *)Extra_MmFixedEntryFetch( s_pHMan->pMmObj );
memset( pHObj, 0, sizeof(Abc_HObj_t) );
// set the object type
pHObj->NtkId = pObj->pNtk->Id;
if ( Abc_ObjIsCi(pObj) )
pHObj->fPi = 1;
else if ( Abc_ObjIsCo(pObj) )
pHObj->fPo = 1;
Vec_VecPush( s_pHMan->vNtks, pObj->pNtk->Id, pHObj );
// set the proof parameter for the network
if ( Vec_IntSize( s_pHMan->vProof ) == pObj->pNtk->Id )
Vec_IntPush( s_pHMan->vProof, 0 );
}
/**Function*************************************************************
Synopsis [Called when the fanin is added to the object.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
{
Abc_HObj_t * pHObj;
int fCompl;
if ( s_pHMan == NULL )
return;
// take off the complemented attribute
assert( !Abc_ObjIsComplement(pObj) );
fCompl = Abc_ObjIsComplement(pFanin);
pFanin = Abc_ObjRegular(pFanin);
// add the fanin
assert( pObj->pNtk == pFanin->pNtk );
pHObj = Abc_ObjHObj(pObj);
if ( pHObj->Fan0.NtkId == 0 )
{
pHObj->Fan0.NtkId = pFanin->pNtk->Id;
pHObj->Fan0.ObjId = pFanin->Id;
pHObj->Fan0.fCompl = fCompl;
}
else if ( pHObj->Fan1.NtkId == 0 )
{
pHObj->Fan1.NtkId = pFanin->pNtk->Id;
pHObj->Fan1.ObjId = pFanin->Id;
pHObj->Fan1.fCompl = fCompl;
}
else assert( 0 );
}
/**Function*************************************************************
Synopsis [Called when the fanin's input should be complemented.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManXorFaninC( Abc_Obj_t * pObj, int iFanin )
{
Abc_HObj_t * pHObj;
if ( s_pHMan == NULL )
return;
assert( iFanin < 2 );
pHObj = Abc_ObjHObj(pObj);
if ( iFanin == 0 )
pHObj->Fan0.fCompl ^= 1;
else if ( iFanin == 1 )
pHObj->Fan1.fCompl ^= 1;
}
/**Function*************************************************************
Synopsis [Called when the fanin is added to the object.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManRemoveFanins( Abc_Obj_t * pObj )
{
Abc_HObj_t * pHObj;
if ( s_pHMan == NULL )
return;
assert( !Abc_ObjIsComplement(pObj) );
pHObj = Abc_ObjHObj(pObj);
pHObj->Fan0.NtkId = 0;
pHObj->Fan0.ObjId = 0;
pHObj->Fan0.fCompl = 0;
pHObj->Fan1.NtkId = 0;
pHObj->Fan1.ObjId = 0;
pHObj->Fan1.fCompl = 0;
}
/**Function*************************************************************
Synopsis [Called when a new prototype of the old object is set.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManAddProto( Abc_Obj_t * pObj, Abc_Obj_t * pProto )
{
Abc_HObj_t * pHObj;
if ( s_pHMan == NULL )
return;
// ignore polarity for now
pObj = Abc_ObjRegular(pObj);
pProto = Abc_ObjRegular(pProto);
// set the prototype
assert( pObj->pNtk != pProto->pNtk );
if ( pObj->pNtk->Id == 0 )
return;
pHObj = Abc_ObjHObj(pObj);
pHObj->Proto.NtkId = pProto->pNtk->Id;
pHObj->Proto.ObjId = pProto->Id;
}
/**Function*************************************************************
Synopsis [Called when an equivalent node is created.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManMapAddEqu( Abc_Obj_t * pObj, Abc_Obj_t * pEqu )
{
/*
Abc_HObj_t * pHObj;
if ( s_pHMan == NULL )
return;
// ignore polarity for now
pObj = Abc_ObjRegular(pObj);
pEqu = Abc_ObjRegular(pEqu);
// set the equivalent node
assert( pObj->pNtk == pEqu->pNtk );
pHObj = Abc_ObjHObj(pObj);
Abc_ObjHObj(pObj)->Equ.NtkId = pEqu->pNtk->Id;
Abc_ObjHObj(pObj)->Equ.ObjId = pEqu->Id;
*/
}
/**Function*************************************************************
Synopsis [Starts the verification procedure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManPopulate( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
int i;
if ( !Abc_NtkIsStrash(pNtk) )
return 0;
// allocate the network ID
pNtk->Id = Abc_HManGetNewNtkId();
assert( pNtk->Id == 1 );
// create the objects
Abc_NtkForEachObj( pNtk, pObj, i )
{
Abc_HManAddObj( pObj );
if ( Abc_ObjFaninNum(pObj) > 0 )
Abc_HManAddFanin( pObj, Abc_ObjChild0(pObj) );
if ( Abc_ObjFaninNum(pObj) > 1 )
Abc_HManAddFanin( pObj, Abc_ObjChild1(pObj) );
}
return 1;
}
/**Function*************************************************************
Synopsis [The main verification procedure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManVerify( int NtkIdOld, int NtkIdNew )
{
int i;
// prove the equality pairwise
for ( i = NtkIdOld; i < NtkIdNew; i++ )
{
if ( Vec_IntEntry(s_pHMan->vProof, i) )
continue;
if ( !Abc_HManVerifyPair( i, i+1 ) )
return 0;
Vec_IntWriteEntry( s_pHMan->vProof, i, 1 );
}
return 1;
}
/**Function*************************************************************
Synopsis [Verifies two networks.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManVerifyPair( int NtkIdOld, int NtkIdNew )
{
Vec_Ptr_t * vNtkNew, * vNtkOld, * vPosNew;
Abc_HObj_t * pHObj;
int i;
// get hold of the network nodes
vNtkNew = Vec_VecEntry( s_pHMan->vNtks, NtkIdNew );
vNtkOld = Vec_VecEntry( s_pHMan->vNtks, NtkIdOld );
Vec_PtrForEachEntry( vNtkNew, pHObj, i )
pHObj->fVisited = 0;
Vec_PtrForEachEntry( vNtkOld, pHObj, i )
pHObj->fVisited = 0;
// collect new POs
vPosNew = Vec_PtrAlloc( 100 );
Vec_PtrForEachEntry( vNtkNew, pHObj, i )
if ( pHObj->fPo )
Vec_PtrPush( vPosNew, pHObj );
// prove them recursively (assuming PO ordering is the same)
Vec_PtrForEachEntry( vPosNew, pHObj, i )
{
if ( Abc_HObjProto(pHObj) == NULL )
{
printf( "History: PO %d has no prototype\n", i );
return 0;
}
if ( !Abc_HManVerifyNodes_rec( Abc_HObjProto(pHObj), pHObj ) )
{
printf( "History: Verification failed for outputs of PO pair number %d\n", i );
return 0;
}
}
printf( "History: Verification succeeded.\n" );
return 1;
}
/**Function*************************************************************
Synopsis [Recursively verifies two nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManVerifyNodes_rec( Abc_HObj_t * pHOld, Abc_HObj_t * pHNew )
{
Vec_Ptr_t * vLeaves;
Abc_HObj_t * pHObj, * pHPro0, * pHPro1;
int i, fPhase;
assert( Abc_HObjProto(pHNew) == pHOld );
if ( pHNew->fProof )
return 1;
pHNew->fProof = 1;
// consider simple cases
if ( pHNew->fPi || pHNew->fConst )
return 1;
if ( pHNew->fPo )
{
if ( !Abc_HManVerifyNodes_rec( Abc_HObjFanin0(pHOld), Abc_HObjFanin0(pHNew) ) )
return 0;
if ( (Abc_HObjFaninC0(pHOld) ^ Abc_HObjFaninC0(pHNew)) != (int)pHNew->fPhase )
{
printf( "History: Phase of PO nodes does not agree.\n" );
return 0;
}
return 1;
}
// the elementary node
pHPro0 = Abc_HObjProto( Abc_HObjFanin0(pHNew) );
pHPro1 = Abc_HObjProto( Abc_HObjFanin1(pHNew) );
if ( pHPro0 && pHPro1 )
{
if ( !Abc_HManVerifyNodes_rec( pHPro0, Abc_HObjFanin0(pHNew) ) )
return 0;
if ( !Abc_HManVerifyNodes_rec( pHPro1, Abc_HObjFanin1(pHNew) ) )
return 0;
if ( Abc_HObjFanin0(pHOld) != pHPro0 || Abc_HObjFanin1(pHOld) != pHPro1 )
{
printf( "History: Internal node does not match.\n" );
return 0;
}
if ( Abc_HObjFaninC0(pHOld) != Abc_HObjFaninC0(pHNew) ||
Abc_HObjFaninC1(pHOld) != Abc_HObjFaninC1(pHNew) )
{
printf( "History: Phase of internal node does not match.\n" );
return 0;
}
return 1;
}
// collect the leaves
vLeaves = Abc_HManCollectLeaves( pHNew );
if ( Vec_PtrSize(vLeaves) > 16 )
{
printf( "History: The bound on the number of inputs is exceeded.\n" );
return 0;
}
s_pHMan->nWordsCur = ((1 << Vec_PtrSize(vLeaves)) <= 32)? 1 : ((1 << Vec_PtrSize(vLeaves)) / 32);
// prove recursively
Vec_PtrForEachEntry( vLeaves, pHObj, i )
if ( !Abc_HManVerifyNodes_rec( Abc_HObjProto(pHObj), pHObj ) )
{
Vec_PtrFree( vLeaves );
return 0;
}
// get the first node
Abc_HManCollectCone( pHNew, vLeaves, s_pHMan->vCone1 );
if ( Vec_PtrSize(s_pHMan->vCone1) > ABC_SIM_OBJS - ABC_SIM_VARS - 1 )
{
printf( "History: The bound on the number of cone nodes is exceeded.\n" );
return 0;
}
// get the second cone
Vec_PtrForEachEntry( vLeaves, pHObj, i )
Vec_PtrWriteEntry( vLeaves, i, Abc_HObjProto(pHObj) );
Abc_HManCollectCone( pHOld, vLeaves, s_pHMan->vCone0 );
if ( Vec_PtrSize(s_pHMan->vCone0) > ABC_SIM_OBJS - ABC_SIM_VARS - 1 )
{
printf( "History: The bound on the number of cone nodes is exceeded.\n" );
return 0;
}
// compare the truth tables
if ( !Abc_HManSimulate( s_pHMan->vCone0, s_pHMan->vCone1, Vec_PtrSize(vLeaves), &fPhase ) )
{
Vec_PtrFree( vLeaves );
printf( "History: Verification failed at an internal node.\n" );
return 0;
}
printf( "Succeeded.\n" );
pHNew->fPhase = fPhase;
Vec_PtrFree( vLeaves );
return 1;
}
/**Function*************************************************************
Synopsis [Finds the leaves of the TFI cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManCollectLeaves_rec( Abc_HObj_t * pHNew, Vec_Ptr_t * vLeaves )
{
Abc_HObj_t * pHPro;
if ( pHPro = Abc_HObjProto( pHNew ) )
{
Vec_PtrPushUnique( vLeaves, pHNew );
return;
}
assert( !pHNew->fPi && !pHNew->fPo && !pHNew->fConst );
Abc_HManCollectLeaves_rec( Abc_HObjFanin0(pHNew), vLeaves );
Abc_HManCollectLeaves_rec( Abc_HObjFanin1(pHNew), vLeaves );
}
/**Function*************************************************************
Synopsis [Finds the leaves of the TFI cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_HManCollectLeaves( Abc_HObj_t * pHNew )
{
Vec_Ptr_t * vLeaves;
vLeaves = Vec_PtrAlloc( 100 );
Abc_HManCollectLeaves_rec( Abc_HObjFanin0(pHNew), vLeaves );
Abc_HManCollectLeaves_rec( Abc_HObjFanin1(pHNew), vLeaves );
return vLeaves;
}
/**Function*************************************************************
Synopsis [Collects the TFI cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManCollectCone_rec( Abc_HObj_t * pHObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
{
if ( pHObj->fVisited )
return;
pHObj->fVisited = 1;
assert( !pHObj->fPi && !pHObj->fPo && !pHObj->fConst );
Abc_HManCollectCone_rec( Abc_HObjFanin0(pHObj), vLeaves, vCone );
Abc_HManCollectCone_rec( Abc_HObjFanin1(pHObj), vLeaves, vCone );
pHObj->Num = Vec_PtrSize(vCone);
Vec_PtrPush( vCone, pHObj );
}
/**Function*************************************************************
Synopsis [Collects the TFI cone.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_HManCollectCone( Abc_HObj_t * pHRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
{
Abc_HObj_t * pHObj;
int i;
Vec_PtrClear( vCone );
Vec_PtrForEachEntry( vLeaves, pHObj, i )
{
pHObj->fVisited = 1;
pHObj->Num = Vec_PtrSize(vCone);
Vec_PtrPush( vCone, pHObj );
}
Abc_HManCollectCone_rec( Abc_HObjFanin0(pHRoot), vLeaves, vCone );
Abc_HManCollectCone_rec( Abc_HObjFanin1(pHRoot), vLeaves, vCone );
return vCone;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_HManSimulateOne( Vec_Ptr_t * vCone, int nLeaves, int fUsePhase )
{
Abc_HObj_t * pHObj, * pHFan0, * pHFan1;
unsigned * puData0, * puData1, * puData;
int k, i, fComp0, fComp1;
// set the leaves
Vec_PtrForEachEntryStart( vCone, pHObj, i, nLeaves )
{
pHFan0 = Abc_HObjFanin0(pHObj);
pHFan1 = Abc_HObjFanin1(pHObj);
// consider the case of interver or buffer
if ( pHFan1 == NULL )
{
puData = Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+i-nLeaves);
puData0 = ((int)pHFan0->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan0->Num) :
Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan0->Num-nLeaves);
fComp0 = Abc_HObjFaninC0(pHObj) ^ (fUsePhase && (int)pHFan0->Num < nLeaves && pHFan0->fPhase);
if ( fComp0 )
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = ~puData0[k];
else
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = puData0[k];
continue;
}
// get the pointers to simulation data
puData = Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+i-nLeaves);
puData0 = ((int)pHFan0->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan0->Num) :
Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan0->Num-nLeaves);
puData1 = ((int)pHFan1->Num < nLeaves)? Vec_PtrEntry(s_pHMan->vSims, pHFan1->Num) :
Vec_PtrEntry(s_pHMan->vSims, ABC_SIM_VARS+pHFan1->Num-nLeaves);
// here are the phases
fComp0 = Abc_HObjFaninC0(pHObj) ^ (fUsePhase && (int)pHFan0->Num < nLeaves && pHFan0->fPhase);
fComp1 = Abc_HObjFaninC1(pHObj) ^ (fUsePhase && (int)pHFan1->Num < nLeaves && pHFan1->fPhase);
// simulate
if ( fComp0 && fComp1 )
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = ~puData0[k] & ~puData1[k];
else if ( fComp0 )
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = ~puData0[k] & puData1[k];
else if ( fComp1 )
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = puData0[k] & ~puData1[k];
else
for ( k = 0; k < s_pHMan->nWordsCur; k++ )
puData[k] = puData0[k] & puData1[k];
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_HManSimulate( Vec_Ptr_t * vCone0, Vec_Ptr_t * vCone1, int nLeaves, int * pPhase )
{
unsigned * pDataTop, * pDataLast;
int w;
// simulate the first one
Abc_HManSimulateOne( vCone0, nLeaves, 0 );
// save the last simulation value
pDataTop = Vec_PtrEntry( s_pHMan->vSims, ((Abc_HObj_t *)Vec_PtrEntryLast(vCone0))->Num );
pDataLast = Vec_PtrEntry( s_pHMan->vSims, Vec_PtrSize(s_pHMan->vSims)-1 );
for ( w = 0; w < s_pHMan->nWordsCur; w++ )
pDataLast[w] = pDataTop[w];
// simulate the other one
Abc_HManSimulateOne( vCone1, nLeaves, 1 );
// complement the output if needed
pDataTop = Vec_PtrEntry( s_pHMan->vSims, ((Abc_HObj_t *)Vec_PtrEntryLast(vCone1))->Num );
// mask unused bits
if ( nLeaves < 5 )
{
pDataTop[0] &= ((~((unsigned)0)) >> (32-(1<<nLeaves)));
pDataLast[0] &= ((~((unsigned)0)) >> (32-(1<<nLeaves)));
}
if ( *pPhase = ((pDataTop[0] & 1) != (pDataLast[0] & 1)) )
for ( w = 0; w < s_pHMan->nWordsCur; w++ )
pDataTop[w] = ~pDataTop[w];
// compare
for ( w = 0; w < s_pHMan->nWordsCur; w++ )
if ( pDataLast[w] != pDataTop[w] )
return 0;
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -73,7 +73,7 @@ void Abc_NtkPrintUnateBdd( Abc_Ntk_t * pNtk, int fUseNaive, int fVerbose )
int clkBdd, clkUnate;
// compute the global BDDs
if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0) == NULL )
if ( Abc_NtkGlobalBdds(pNtk, 10000000, 0, 1, fVerbose) == NULL )
return;
clkBdd = clock() - clk;

View File

@ -58,7 +58,7 @@ int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, bool fVerbose )
}
// compute the global BDDs of the latches
dd = Abc_NtkGlobalBdds( pNtk, 10000000, 1 );
dd = Abc_NtkGlobalBdds( pNtk, 10000000, 1, 1, fVerbose );
if ( dd == NULL )
return 0;
if ( fVerbose )
@ -331,7 +331,11 @@ Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUn
Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
// transform the network to the SOP representation
Abc_NtkBddToSop( pNtkNew, 0 );
if ( !Abc_NtkBddToSop( pNtkNew, 0 ) )
{
printf( "Converting to SOPs has failed.\n" );
return NULL;
}
return pNtkNew;
}

View File

@ -713,7 +713,7 @@ Fraig_Man_t * Abc_NtkVanEijkFraig( Abc_Ntk_t * pMulti, int fInit )
Abc_Ntk_t * Abc_NtkVanEijkDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vClasses )
{
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pClass, * pNode, * pRepr, * pObj, *pObjNew;
Abc_Obj_t * pClass, * pNode, * pRepr, * pObj;//, *pObjNew;
Abc_Obj_t * pMiter, * pTotal;
Vec_Ptr_t * vCone;
int i, k;

View File

@ -870,7 +870,7 @@ Abc_Ntk_t * Abc_NtkVanImpDeriveExdc( Abc_Ntk_t * pNtk, Vec_Ptr_t * vZeros, Vec_I
{
Abc_Ntk_t * pNtkNew;
Vec_Ptr_t * vCone;
Abc_Obj_t * pObj, * pMiter, * pTotal, * pNode, * pNode1, * pNode2, * pObjNew;
Abc_Obj_t * pObj, * pMiter, * pTotal, * pNode, * pNode1, * pNode2;//, * pObjNew;
unsigned Imp;
int i, k;

View File

@ -85,7 +85,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
}
// solve the CNF using the SAT solver
RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0 );
RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0, 0 );
if ( RetValue == -1 )
printf( "Networks are undecided (SAT solver timed out).\n" );
else if ( RetValue == 0 )
@ -112,6 +112,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
***********************************************************************/
void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose )
{
Prove_Params_t Params, * pParams = &Params;
// Fraig_Params_t Params;
// Fraig_Man_t * pMan;
Abc_Ntk_t * pMiter;
@ -171,7 +172,9 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV
Abc_NtkDelete( pMiter );
*/
// solve the CNF using the SAT solver
RetValue = Abc_NtkMiterProve( &pMiter, 0, 0, 1, 1, 0 );
Prove_ParamsSetDefault( pParams );
pParams->nItersMax = 5;
RetValue = Abc_NtkMiterProve( &pMiter, pParams );
if ( RetValue == -1 )
printf( "Networks are undecided (resource limits is reached).\n" );
else if ( RetValue == 0 )
@ -254,7 +257,7 @@ void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
}
// solve the CNF using the SAT solver
RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0 );
RetValue = Abc_NtkMiterSat( pCnf, nConfLimit, nImpLimit, 0, 0 );
if ( RetValue == -1 )
printf( "Networks are undecided (SAT solver timed out).\n" );
else if ( RetValue == 0 )

View File

@ -23,7 +23,7 @@
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@ -40,6 +40,7 @@
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -10,6 +10,7 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcFpga.c \
src/base/abci/abcFraig.c \
src/base/abci/abcFxu.c \
src/base/abci/abcGen.c \
src/base/abci/abcMap.c \
src/base/abci/abcMiter.c \
src/base/abci/abcNtbdd.c \
@ -22,11 +23,13 @@ SRC += src/base/abci/abc.c \
src/base/abci/abcRestruct.c \
src/base/abci/abcResub.c \
src/base/abci/abcRewrite.c \
src/base/abci/abcRr.c \
src/base/abci/abcSat.c \
src/base/abci/abcStrash.c \
src/base/abci/abcSweep.c \
src/base/abci/abcSymm.c \
src/base/abci/abcTiming.c \
src/base/abci/abcTrace.c \
src/base/abci/abcUnate.c \
src/base/abci/abcUnreach.c \
src/base/abci/abcVanEijk.c \

View File

@ -18,6 +18,10 @@
***********************************************************************/
#ifdef WIN32
#include <process.h>
#endif
#include "mainInt.h"
#include "cmdInt.h"
#include "abc.h"
@ -45,6 +49,7 @@ static int CmdCommandLs ( Abc_Frame_t * pAbc, int argc, char ** argv
#endif
static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@ -85,6 +90,7 @@ void Cmd_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "sis", CmdCommandSis, 1);
Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1);
Cmd_CommandAdd( pAbc, "Various", "capo", CmdCommandCapo, 0);
}
/**Function********************************************************************
@ -1253,6 +1259,11 @@ int CmdCommandSis( Abc_Frame_t * pAbc, int argc, char **argv )
// write out the current network
pNetlist = Abc_NtkLogicToNetlist(pNtk,0);
if ( pNetlist == NULL )
{
fprintf( pErr, "Cannot produce the intermediate network.\n" );
goto usage;
}
Io_WriteBlif( pNetlist, "_sis_in.blif", 1 );
Abc_NtkDelete( pNetlist );
@ -1389,6 +1400,11 @@ int CmdCommandMvsis( Abc_Frame_t * pAbc, int argc, char **argv )
// write out the current network
pNetlist = Abc_NtkLogicToNetlist(pNtk,0);
if ( pNetlist == NULL )
{
fprintf( pErr, "Cannot produce the intermediate network.\n" );
goto usage;
}
Io_WriteBlif( pNetlist, "_mvsis_in.blif", 1 );
Abc_NtkDelete( pNetlist );
@ -1454,6 +1470,190 @@ usage:
}
/**Function********************************************************************
Synopsis [Calls Capo internally.]
Description []
SideEffects []
SeeAlso []
******************************************************************************/
int CmdCommandCapo( Abc_Frame_t * pAbc, int argc, char **argv )
{
FILE * pFile;
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNetlist;
char Command[1000], Buffer[100];
char * pProgNameCapoWin = "capo.exe";
char * pProgNameCapoUnix = "capo";
char * pProgNameGnuplotWin = "wgnuplot.exe";
char * pProgNameGnuplotUnix = "gnuplot";
char * pProgNameCapo;
char * pProgNameGnuplot;
char * pPlotFileName;
int i;
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
goto usage;
}
if ( strcmp( argv[0], "capo" ) != 0 )
{
fprintf( pErr, "Wrong command: \"%s\".\n", argv[0] );
goto usage;
}
if ( argc > 1 )
{
if ( strcmp( argv[1], "-h" ) == 0 )
goto usage;
if ( strcmp( argv[1], "-?" ) == 0 )
goto usage;
}
// get the names from the resource file
if ( Cmd_FlagReadByName(pAbc, "capowin") )
pProgNameCapoWin = Cmd_FlagReadByName(pAbc, "capowin");
if ( Cmd_FlagReadByName(pAbc, "capounix") )
pProgNameCapoUnix = Cmd_FlagReadByName(pAbc, "capounix");
// check if capo is available
if ( (pFile = fopen( pProgNameCapoWin, "r" )) )
pProgNameCapo = pProgNameCapoWin;
else if ( (pFile = fopen( pProgNameCapoUnix, "r" )) )
pProgNameCapo = pProgNameCapoUnix;
else if ( pFile == NULL )
{
fprintf( pErr, "Cannot find \"%s\" or \"%s\" in the current directory.\n", pProgNameCapoWin, pProgNameCapoUnix );
goto usage;
}
fclose( pFile );
if ( Abc_NtkIsMappedLogic(pNtk) )
{
Abc_NtkUnmap(pNtk);
printf( "The current network is unmapped before calling Capo.\n" );
}
// write out the current network
pNetlist = Abc_NtkLogicToNetlist(pNtk,0);
if ( pNetlist == NULL )
{
fprintf( pErr, "Cannot produce the intermediate network.\n" );
goto usage;
}
Io_WriteBlif( pNetlist, "_capo_in.blif", 1 );
Abc_NtkDelete( pNetlist );
// create the file for Capo
sprintf( Command, "%s -f _capo_in.blif -log out.txt ", pProgNameCapo );
pPlotFileName = NULL;
for ( i = 1; i < argc; i++ )
{
sprintf( Buffer, " %s", argv[i] );
strcat( Command, Buffer );
if ( !strcmp( argv[i], "-plot" ) )
pPlotFileName = argv[i+1];
}
// call Capo
if ( system( Command ) )
{
fprintf( pErr, "The following command has returned non-zero exit status:\n" );
fprintf( pErr, "\"%s\"\n", Command );
unlink( "_capo_in.blif" );
goto usage;
}
// remove temporary networks
unlink( "_capo_in.blif" );
if ( pPlotFileName == NULL )
return 0;
// get the file name
sprintf( Buffer, "%s.plt", pPlotFileName );
pPlotFileName = Buffer;
// read in the Capo plotting output
if ( (pFile = fopen( pPlotFileName, "r" )) == NULL )
{
fprintf( pErr, "Cannot open the plot file \"%s\".\n\n", pPlotFileName );
goto usage;
}
fclose( pFile );
// get the names from the plotting software
if ( Cmd_FlagReadByName(pAbc, "gnuplotwin") )
pProgNameGnuplotWin = Cmd_FlagReadByName(pAbc, "gnuplotwin");
if ( Cmd_FlagReadByName(pAbc, "gnuplotunix") )
pProgNameGnuplotUnix = Cmd_FlagReadByName(pAbc, "gnuplotunix");
// check if Gnuplot is available
if ( (pFile = fopen( pProgNameGnuplotWin, "r" )) )
pProgNameGnuplot = pProgNameGnuplotWin;
else if ( (pFile = fopen( pProgNameGnuplotUnix, "r" )) )
pProgNameGnuplot = pProgNameGnuplotUnix;
else if ( pFile == NULL )
{
fprintf( pErr, "Cannot find \"%s\" or \"%s\" in the current directory.\n", pProgNameGnuplotWin, pProgNameGnuplotUnix );
goto usage;
}
fclose( pFile );
// spawn the viewer
#ifdef WIN32
if ( _spawnl( _P_NOWAIT, pProgNameGnuplot, pProgNameGnuplot, pPlotFileName, NULL ) == -1 )
{
fprintf( stdout, "Cannot find \"%s\".\n", pProgNameGnuplot );
goto usage;
}
#else
{
sprintf( Command, "%s %s ", pProgNameGnuplot, pPlotFileName );
if ( system( Command ) == -1 )
{
fprintf( stdout, "Cannot execute \"%s\".\n", Command );
goto usage;
}
}
#endif
// remove temporary networks
// unlink( pPlotFileName );
return 0;
usage:
fprintf( pErr, "\n" );
fprintf( pErr, "Usage: capo [-h] <com>\n");
fprintf( pErr, " peforms placement of the current network using Capo\n" );
fprintf( pErr, " a Capo binary should be present in the same directory\n" );
fprintf( pErr, " (if plotting, the Gnuplot binary should also be present)\n" );
fprintf( pErr, " -h : print the command usage\n" );
fprintf( pErr, " <com> : a Capo command\n" );
fprintf( pErr, " Example 1: capo\n" );
fprintf( pErr, " (performs placement with default options)\n" );
fprintf( pErr, " Example 2: capo -AR <aspec_ratio> -WS <whitespace_percentage> -save\n" );
fprintf( pErr, " (specifies the aspect ratio [default = 1.0] and\n" );
fprintf( pErr, " the whitespace percentage [0%%; 100%%) [default = 15%%])\n" );
fprintf( pErr, " Example 3: capo -plot <base_fileName>\n" );
fprintf( pErr, " (produces <base_fileName.plt> and visualize it using Gnuplot)\n" );
fprintf( pErr, " Example 4: capo -help\n" );
fprintf( pErr, " (prints the default usage message of the Capo binary)\n" );
fprintf( pErr, " Please refer to the Capo webpage for additional information:\n" );
fprintf( pErr, " http://vlsicad.eecs.umich.edu/BK/PDtools/\n" );
return 1; // error exit
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -42,6 +42,9 @@
Abc_Ntk_t * Io_Read( char * pFileName, int fCheck )
{
Abc_Ntk_t * pNtk, * pTemp;
// extern int s_TotalNodes;
// extern int s_TotalChanges;
// s_TotalNodes = s_TotalChanges = 0;
// set the new network
if ( Extra_FileNameCheckExtension( pFileName, "blif" ) )
pNtk = Io_ReadBlif( pFileName, fCheck );

View File

@ -136,7 +136,7 @@ Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
Abc_ObjSetData( pNode, Abc_SopCreateNor(pNtk->pManFunc, nNames) );
else if ( strcmp(pType, "XOR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateXor(pNtk->pManFunc, nNames) );
else if ( strcmp(pType, "NXOR") == 0 )
else if ( strcmp(pType, "NXOR") == 0 || strcmp(pType, "XNOR") == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateNxor(pNtk->pManFunc, nNames) );
else if ( strncmp(pType, "BUF", 3) == 0 )
Abc_ObjSetData( pNode, Abc_SopCreateBuf(pNtk->pManFunc) );

View File

@ -23,6 +23,8 @@
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static Abc_Ntk_t * s_pNtk = NULL;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@ -57,15 +59,51 @@ int Io_WriteCnf( Abc_Ntk_t * pNtk, char * pFileName )
fprintf( stdout, "Io_WriteCnf(): Currently can only process the miter for combinational circuits.\n" );
return 0;
}
if ( Abc_NtkNodeNum(pNtk) == 0 )
{
fprintf( stdout, "The network has no logic nodes. No CNF file is generaled.\n" );
return 0;
}
// create solver with clauses
pSat = Abc_NtkMiterSatCreate( pNtk );
pSat = Abc_NtkMiterSatCreate( pNtk, 0 );
if ( pSat == NULL )
{
fprintf( stdout, "The problem is trivially UNSAT. No CNF file is generated.\n" );
return 1;
}
// write the clauses
s_pNtk = pNtk;
Asat_SolverWriteDimacs( pSat, pFileName, 0, 0, 1 );
s_pNtk = NULL;
// free the solver
solver_delete( pSat );
return 1;
}
/**Function*************************************************************
Synopsis [Output the mapping of PIs into variable numbers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Io_WriteCnfOutputPiMapping( FILE * pFile, int incrementVars )
{
extern Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk );
Abc_Ntk_t * pNtk = s_pNtk;
Vec_Int_t * vCiIds;
Abc_Obj_t * pObj;
int i;
vCiIds = Abc_NtkGetCiSatVarNums( pNtk );
fprintf( pFile, "c PI variable numbers: <PI_name> <SAT_var_number>\n" );
Abc_NtkForEachCi( pNtk, pObj, i )
fprintf( pFile, "c %s %d\n", Abc_ObjName(pObj), Vec_IntEntry(vCiIds, i) + (int)(incrementVars > 0) );
Vec_IntFree( vCiIds );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///

View File

@ -412,7 +412,13 @@ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesSho
// transform logic functions from BDD to SOP
if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) )
Abc_NtkBddToSop(pNtk, 0);
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return;
}
}
// mark the nodes from the set
Vec_PtrForEachEntry( vNodes, pNode, i )

View File

@ -120,8 +120,8 @@ void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost )
if ( Abc_ObjFanoutNum( Abc_NtkConst1(pNtk) ) > 0 )
Io_WriteListEdge( pFile, Abc_NtkConst1(pNtk) );
// write the PO edges
Abc_NtkForEachCi( pNtk, pObj, i )
// write the PI edges
Abc_NtkForEachPi( pNtk, pObj, i )
Io_WriteListEdge( pFile, pObj );
// write the internal nodes
@ -132,7 +132,7 @@ void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost )
if ( fUseHost )
Io_WriteListHost( pFile, pNtk );
else
Abc_NtkForEachCo( pNtk, pObj, i )
Abc_NtkForEachPo( pNtk, pObj, i )
Io_WriteListEdge( pFile, pObj );
fprintf( pFile, "\n" );
@ -157,12 +157,13 @@ void Io_WriteListEdge( FILE * pFile, Abc_Obj_t * pObj )
fprintf( pFile, "%-10s > ", Abc_ObjName(pObj) );
Abc_ObjForEachFanout( pObj, pFanout, i )
{
fprintf( pFile, " %s ([%s_to_%s] = %d)", Abc_ObjName(pFanout), Abc_ObjName(pObj), Abc_ObjName(pFanout), Seq_ObjFanoutL(pObj, pFanout) );
if ( i == Abc_ObjFanoutNum(pObj) - 1 )
fprintf( pFile, "." );
else
fprintf( pFile, " %s", Abc_ObjName(pFanout) );
fprintf( pFile, " ([%s_to_", Abc_ObjName(pObj) );
fprintf( pFile, "%s] = %d)", Abc_ObjName(pFanout), Seq_ObjFanoutL(pObj, pFanout) );
if ( i != Abc_ObjFanoutNum(pObj) - 1 )
fprintf( pFile, "," );
}
fprintf( pFile, "." );
fprintf( pFile, "\n" );
}
@ -186,22 +187,19 @@ void Io_WriteListHost( FILE * pFile, Abc_Ntk_t * pNtk )
{
fprintf( pFile, "%-10s > ", Abc_ObjName(pObj) );
fprintf( pFile, " %s ([%s_to_%s] = %d)", "HOST", Abc_ObjName(pObj), "HOST", 0 );
if ( i == Abc_NtkPoNum(pNtk) - 1 )
fprintf( pFile, "." );
else
fprintf( pFile, "," );
fprintf( pFile, "." );
fprintf( pFile, "\n" );
}
fprintf( pFile, "\n" );
fprintf( pFile, "%-10s > ", "HOST" );
Abc_NtkForEachPi( pNtk, pObj, i )
{
fprintf( pFile, " %s ([%s_to_%s] = %d)", Abc_ObjName(pObj), "HOST", Abc_ObjName(pObj), 0 );
if ( i == Abc_NtkPiNum(pNtk) - 1 )
fprintf( pFile, "." );
else
fprintf( pFile, " %s", Abc_ObjName(pObj) );
fprintf( pFile, " ([%s_to_%s] = %d)", "HOST", Abc_ObjName(pObj), 0 );
if ( i != Abc_NtkPiNum(pNtk) - 1 )
fprintf( pFile, "," );
}
fprintf( pFile, "." );
fprintf( pFile, "\n" );
}

View File

@ -81,6 +81,7 @@ extern FILE * Abc_FrameReadErr( Abc_Frame_t * p );
extern bool Abc_FrameReadMode( Abc_Frame_t * p );
extern bool Abc_FrameSetMode( Abc_Frame_t * p, bool fNameMode );
extern void Abc_FrameRestart( Abc_Frame_t * p );
extern bool Abc_FrameShowProgress( Abc_Frame_t * p );
extern void Abc_FrameSetCurrentNetwork( Abc_Frame_t * p, Abc_Ntk_t * pNet );
extern void Abc_FrameSwapCurrentAndBackup( Abc_Frame_t * p );

View File

@ -111,9 +111,12 @@ Abc_Frame_t * Abc_FrameAllocate()
// set the starting step
p->nSteps = 1;
p->fBatchMode = 0;
p->fProgress = 1;
// initialize decomposition manager
define_cube_size(20);
set_espresso_flags();
// initialize the trace manager
// Abc_HManStart();
return p;
}
@ -132,6 +135,7 @@ Abc_Frame_t * Abc_FrameAllocate()
void Abc_FrameDeallocate( Abc_Frame_t * p )
{
extern void undefine_cube_size();
// Abc_HManStop();
undefine_cube_size();
if ( p->pManDec ) Dec_ManStop( p->pManDec );
if ( p->dd ) Extra_StopManager( p->dd );
@ -155,6 +159,22 @@ void Abc_FrameRestart( Abc_Frame_t * p )
{
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
bool Abc_FrameShowProgress( Abc_Frame_t * p )
{
return p->fProgress;
}
/**Function*************************************************************

View File

@ -55,6 +55,7 @@ struct Abc_Frame_t_
int nSteps; // the counter of different network processed
int fAutoexac; // marks the autoexec mode
int fBatchMode; // are we invoked in batch mode?
int fProgress; // shows progress bars
// output streams
FILE * Out;
FILE * Err;

View File

@ -358,7 +358,7 @@ int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int
// solve the miter
clk = clock();
// RetValue = Abc_NtkMiterSat_OldAndRusty( pNtkCnf, 30, 0 );
RetValue = Abc_NtkMiterSat( pNtkCnf, 500000, 50000000, 0 );
RetValue = Abc_NtkMiterSat( pNtkCnf, 500000, 50000000, 0, 0 );
if ( fVerbose )
if ( clock() - clk > 100 )
{

View File

@ -613,7 +613,7 @@ void Seq_MapCanonicizeTruthTables( Abc_Ntk_t * pNtk )
if ( pList == NULL )
continue;
for ( pCut = pList->pNext; pCut; pCut = pCut->pNext )
Cut_TruthCanonicize( pCut );
Cut_TruthNCanonicize( pCut );
}
}

View File

@ -107,7 +107,13 @@ Abc_Ntk_t * Seq_NtkRetimeDerive( Abc_Ntk_t * pNtk, int fVerbose )
// transform logic functions from BDD to SOP
if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) )
Abc_NtkBddToSop(pNtk, 0);
{
if ( !Abc_NtkBddToSop(pNtk, 0) )
{
printf( "Converting to SOPs has failed.\n" );
return NULL;
}
}
// start the network
pNtkNew = Abc_NtkAlloc( ABC_NTK_SEQ, ABC_FUNC_AIG );

View File

@ -73,7 +73,7 @@ void Pga_MappingMatches( Pga_Man_t * p, int Mode )
continue;
// get the cuts
clk = clock();
pList = Abc_NodeGetCutsRecursive( p->pManCut, pObj, 0 );
pList = Abc_NodeGetCutsRecursive( p->pManCut, pObj, 0, 0 );
p->timeCuts += clock() - clk;
// match the node
Pga_MappingMatchNode( p, pObj->Id, pList, Mode );

View File

@ -293,6 +293,8 @@ extern char * Extra_TimeStamp();
extern char * Extra_StringAppend( char * pStrGiven, char * pStrAdd );
extern unsigned Extra_ReadBinary( char * Buffer );
extern void Extra_PrintBinary( FILE * pFile, unsigned Sign[], int nBits );
extern int Extra_ReadHexadecimal( unsigned Sign[], char * pString, int nVars );
extern void Extra_PrintHexadecimal( FILE * pFile, unsigned Sign[], int nVars );
extern void Extra_PrintHex( FILE * pFile, unsigned uTruth, int nVars );
extern void Extra_PrintSymbols( FILE * pFile, char Char, int nTimes, int fPrintNewLine );
@ -390,30 +392,68 @@ extern void Extra_ProgressBarStop( ProgressBar * p );
extern void Extra_ProgressBarUpdate_int( ProgressBar * p, int nItemsCur, char * pString );
static inline void Extra_ProgressBarUpdate( ProgressBar * p, int nItemsCur, char * pString )
{ if ( nItemsCur < *((int*)p) ) return; Extra_ProgressBarUpdate_int(p, nItemsCur, pString); }
{ if ( p && nItemsCur < *((int*)p) ) return; Extra_ProgressBarUpdate_int(p, nItemsCur, pString); }
/*=== extraUtilIntVec.c ================================================================*/
/*=== extraUtilTruth.c ================================================================*/
typedef struct Extra_IntVec_t_ Extra_IntVec_t;
extern Extra_IntVec_t * Extra_IntVecAlloc( int nCap );
extern Extra_IntVec_t * Extra_IntVecAllocArray( int * pArray, int nSize );
extern Extra_IntVec_t * Extra_IntVecAllocArrayCopy( int * pArray, int nSize );
extern Extra_IntVec_t * Extra_IntVecDup( Extra_IntVec_t * pVec );
extern Extra_IntVec_t * Extra_IntVecDupArray( Extra_IntVec_t * pVec );
extern void Extra_IntVecFree( Extra_IntVec_t * p );
extern void Extra_IntVecFill( Extra_IntVec_t * p, int nSize, int Entry );
extern int * Extra_IntVecReleaseArray( Extra_IntVec_t * p );
extern int * Extra_IntVecReadArray( Extra_IntVec_t * p );
extern int Extra_IntVecReadSize( Extra_IntVec_t * p );
extern int Extra_IntVecReadEntry( Extra_IntVec_t * p, int i );
extern int Extra_IntVecReadEntryLast( Extra_IntVec_t * p );
extern void Extra_IntVecWriteEntry( Extra_IntVec_t * p, int i, int Entry );
extern void Extra_IntVecGrow( Extra_IntVec_t * p, int nCapMin );
extern void Extra_IntVecShrink( Extra_IntVec_t * p, int nSizeNew );
extern void Extra_IntVecClear( Extra_IntVec_t * p );
extern void Extra_IntVecPush( Extra_IntVec_t * p, int Entry );
extern int Extra_IntVecPop( Extra_IntVec_t * p );
extern void Extra_IntVecSort( Extra_IntVec_t * p );
static inline int Extra_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
static inline int Extra_WordCountOnes( unsigned uWord )
{
uWord = (uWord & 0x55555555) + ((uWord>>1) & 0x55555555);
uWord = (uWord & 0x33333333) + ((uWord>>2) & 0x33333333);
uWord = (uWord & 0x0F0F0F0F) + ((uWord>>4) & 0x0F0F0F0F);
uWord = (uWord & 0x00FF00FF) + ((uWord>>8) & 0x00FF00FF);
return (uWord & 0x0000FFFF) + (uWord>>16);
}
static inline int Extra_TruthIsEqual( unsigned * pIn0, unsigned * pIn1, int nVars )
{
int w;
for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
if ( pIn0[w] != pIn1[w] )
return 0;
return 1;
}
static inline void Extra_TruthCopy( unsigned * pOut, unsigned * pIn, int nVars )
{
int w;
for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
pOut[w] = pIn[w];
}
static inline void Extra_TruthNot( unsigned * pOut, unsigned * pIn, int nVars )
{
int w;
for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
pOut[w] = ~pIn[w];
}
static inline void Extra_TruthAnd( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
{
int w;
for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
pOut[w] = pIn0[w] & pIn1[w];
}
static inline void Extra_TruthNand( unsigned * pOut, unsigned * pIn0, unsigned * pIn1, int nVars )
{
int w;
for ( w = Extra_TruthWordNum(nVars)-1; w >= 0; w-- )
pOut[w] = ~(pIn0[w] & pIn1[w]);
}
extern void Extra_TruthSwapAdjacentVars( unsigned * pOut, unsigned * pIn, int nVars, int Start );
extern void Extra_TruthStretch( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase );
extern void Extra_TruthShrink( unsigned * pOut, unsigned * pIn, int nVars, int nVarsAll, unsigned Phase );
extern DdNode * Extra_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars );
extern int Extra_TruthVarInSupport( unsigned * pTruth, int nVars, int iVar );
extern int Extra_TruthSupportSize( unsigned * pTruth, int nVars );
extern int Extra_TruthSupport( unsigned * pTruth, int nVars );
extern void Extra_TruthCofactor0( unsigned * pTruth, int nVars, int iVar );
extern void Extra_TruthCofactor1( unsigned * pTruth, int nVars, int iVar );
extern void Extra_TruthCombine( unsigned * pOut, unsigned * pCof0, unsigned * pCof1, int nVars, int iVar );
extern void Extra_TruthChangePhase( unsigned * pTruth, int nVars, int iVar );
extern int Extra_TruthMinCofSuppOverlap( unsigned * pTruth, int nVars, int * pVarMin );
extern int Extra_TruthCountOnes( unsigned * pTruth, int nVars );
extern void Extra_TruthCountOnesInCofs( unsigned * pTruth, int nVars, short * pStore );
extern unsigned Extra_TruthHash( unsigned * pIn, int nWords );
extern unsigned Extra_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars, char * pCanonPerm, short * pStore );
/*=== extraUtilUtil.c ================================================================*/

View File

@ -318,6 +318,65 @@ void Extra_PrintBinary( FILE * pFile, unsigned Sign[], int nBits )
// fprintf( pFile, "\n" );
}
/**Function*************************************************************
Synopsis [Reads the hex unsigned into the bit-string.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Extra_ReadHexadecimal( unsigned Sign[], char * pString, int nVars )
{
int nDigits, Digit, k, c;
Sign[0] = 0;
// write the number into the file
nDigits = (1 << nVars) / 4;
for ( k = 0; k < nDigits; k++ )
{
c = nDigits-1-k;
if ( pString[c] >= '0' && pString[c] <= '9' )
Digit = pString[c] - '0';
else if ( pString[c] >= 'A' && pString[c] <= 'F' )
Digit = pString[c] - 'A' + 10;
else if ( pString[c] >= 'a' && pString[c] <= 'f' )
Digit = pString[c] - 'a' + 10;
else { assert( 0 ); return 0; }
Sign[k/8] |= ( (Digit & 15) << ((k%8) * 4) );
}
return 1;
}
/**Function*************************************************************
Synopsis [Prints the hex unsigned into a file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Extra_PrintHexadecimal( FILE * pFile, unsigned Sign[], int nVars )
{
int nDigits, Digit, k;
// write the number into the file
nDigits = (1 << nVars) / 4;
for ( k = nDigits - 1; k >= 0; k-- )
{
Digit = ((Sign[k/8] >> ((k%8) * 4)) & 15);
if ( Digit < 10 )
fprintf( pFile, "%d", Digit );
else
fprintf( pFile, "%c", 'a' + Digit-10 );
}
// fprintf( pFile, "\n" );
}
/**Function*************************************************************
Synopsis [Prints the hex unsigned into a file.]

View File

@ -58,6 +58,10 @@ static void Extra_ProgressBarClean( ProgressBar * p );
ProgressBar * Extra_ProgressBarStart( FILE * pFile, int nItemsTotal )
{
ProgressBar * p;
extern int Abc_FrameShowProgress( void * p );
extern void * Abc_FrameGetGlobalFrame();
if ( !Abc_FrameShowProgress(Abc_FrameGetGlobalFrame()) ) return NULL;
p = ALLOC( ProgressBar, 1 );
memset( p, 0, sizeof(ProgressBar) );
p->pFile = pFile;
@ -82,6 +86,7 @@ ProgressBar * Extra_ProgressBarStart( FILE * pFile, int nItemsTotal )
***********************************************************************/
void Extra_ProgressBarUpdate_int( ProgressBar * p, int nItemsCur, char * pString )
{
if ( p == NULL ) return;
if ( nItemsCur < p->nItemsNext )
return;
if ( nItemsCur > p->nItemsTotal )
@ -107,6 +112,7 @@ void Extra_ProgressBarUpdate_int( ProgressBar * p, int nItemsCur, char * pString
***********************************************************************/
void Extra_ProgressBarStop( ProgressBar * p )
{
if ( p == NULL ) return;
Extra_ProgressBarClean( p );
FREE( p );
}
@ -125,6 +131,7 @@ void Extra_ProgressBarStop( ProgressBar * p )
void Extra_ProgressBarShow( ProgressBar * p, char * pString )
{
int i;
if ( p == NULL ) return;
if ( pString )
fprintf( p->pFile, "%s ", pString );
for ( i = (pString? strlen(pString) + 1 : 0); i < p->posCur; i++ )
@ -151,6 +158,7 @@ void Extra_ProgressBarShow( ProgressBar * p, char * pString )
void Extra_ProgressBarClean( ProgressBar * p )
{
int i;
if ( p == NULL ) return;
for ( i = 0; i <= p->posTotal; i++ )
fprintf( p->pFile, " " );
fprintf( p->pFile, "\r" );

File diff suppressed because it is too large Load Diff

View File

@ -10,4 +10,5 @@ SRC += src/misc/extra/extraBddAuto.c \
src/misc/extra/extraUtilMisc.c \
src/misc/extra/extraUtilProgress.c \
src/misc/extra/extraUtilReader.c \
src/misc/extra/extraUtilTruth.c \
src/misc/extra/extraUtilUtil.c

View File

@ -446,6 +446,33 @@ static inline void Vec_IntPush( Vec_Int_t * p, int Entry )
p->pArray[p->nSize++] = Entry;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_IntPushFirst( Vec_Int_t * p, int Entry )
{
int i;
if ( p->nSize == p->nCap )
{
if ( p->nCap < 16 )
Vec_IntGrow( p, 16 );
else
Vec_IntGrow( p, 2 * p->nCap );
}
p->nSize++;
for ( i = p->nSize - 1; i >= 1; i-- )
p->pArray[i] = p->pArray[i-1];
p->pArray[0] = Entry;
}
/**Function*************************************************************
Synopsis []

View File

@ -121,6 +121,28 @@ static inline Vec_Vec_t * Vec_VecStart( int nSize )
return p;
}
/**Function*************************************************************
Synopsis [Allocates a vector with the given capacity.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_VecExpand( Vec_Vec_t * p, int Level )
{
int i;
if ( p->nSize >= Level + 1 )
return;
Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 );
for ( i = p->nSize; i <= Level; i++ )
p->pArray[i] = Vec_PtrAlloc( 0 );
p->nSize = Level + 1;
}
/**Function*************************************************************
Synopsis []

View File

@ -59,8 +59,10 @@ struct Cut_ParamsStruct_t_
int fFilter; // filter dominated cuts
int fSeq; // compute sequential cuts
int fDrop; // drop cuts on the fly
int fMulti; // compute factor-cuts
int fDag; // compute only DAG cuts
int fTree; // compute only tree cuts
int fRecord; // record the cut computation flow
int fFancy; // perform fancy computations
int fVerbose; // the verbosiness flag
};
@ -117,8 +119,9 @@ extern void Cut_ManPrintStats( Cut_Man_t * p );
extern void Cut_ManPrintStatsToFile( Cut_Man_t * p, char * pFileName, int TimeTotal );
extern void Cut_ManSetFanoutCounts( Cut_Man_t * p, Vec_Int_t * vFanCounts );
extern int Cut_ManReadVarsMax( Cut_Man_t * p );
extern void Cut_ManIncrementDagNodes( Cut_Man_t * p );
/*=== cutNode.c ==========================================================*/
extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv );
extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode );
extern Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes );
extern Cut_Cut_t * Cut_NodeUnionCutsSeq( Cut_Man_t * p, Vec_Int_t * vNodes, int CutSetNum, int fFirst );
/*=== cutSeq.c ==========================================================*/
@ -135,7 +138,13 @@ extern void Cut_OracleNodeSetTriv( Cut_Oracle_t * p, int Node );
extern Cut_Cut_t * Cut_OracleComputeCuts( Cut_Oracle_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1 );
extern void Cut_OracleTryDroppingCuts( Cut_Oracle_t * p, int Node );
/*=== cutTruth.c ==========================================================*/
extern void Cut_TruthCanonicize( Cut_Cut_t * pCut );
extern void Cut_TruthNCanonicize( Cut_Cut_t * pCut );
/*=== cutPre22.c ==========================================================*/
extern void Cut_CellPrecompute();
extern void Cut_CellLoad();
extern int Cut_CellIsRunning();
extern void Cut_CellDumpToFile();
extern int Cut_CellTruthLookup( unsigned * pTruth, int nVars );
#ifdef __cplusplus
}

View File

@ -65,13 +65,13 @@ struct Cut_ManStruct_t_
Cut_Cut_t * pStore1[2];
Cut_Cut_t * pCompareOld;
Cut_Cut_t * pCompareNew;
unsigned * puTemp[4];
// record of the cut computation
Vec_Int_t * vNodeCuts; // the number of cuts for each node
Vec_Int_t * vNodeStarts; // the number of the starting cut of each node
Vec_Int_t * vCutPairs; // the pairs of parent cuts for each cut
// statistics
int nCutsCur;
int nCutsMulti;
int nCutsAlloc;
int nCutsDealloc;
int nCutsPeak;
@ -79,8 +79,8 @@ struct Cut_ManStruct_t_
int nCutsFilter;
int nCutsLimit;
int nNodes;
int nNodesMulti;
int nNodesMulti0;
int nNodesDag;
int nNodesNoCuts;
// runtime
int timeMerge;
int timeUnion;
@ -130,7 +130,7 @@ extern void Cut_CutPrintMerge( Cut_Cut_t * pCut, Cut_Cut_t * pCut
/*=== cutMerge.c ==========================================================*/
extern Cut_Cut_t * Cut_CutMergeTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 );
/*=== cutNode.c ==========================================================*/
extern void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fCompl0, int fCompl1, Cut_Cut_t * pList0, Cut_Cut_t * pList1, int fTriv );
extern void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fCompl0, int fCompl1, Cut_Cut_t * pList0, Cut_Cut_t * pList1, int fTriv, int TreeCode );
extern int Cut_CutListVerify( Cut_Cut_t * pList );
/*=== cutTable.c ==========================================================*/
extern Cut_HashTable_t * Cut_TableStart( int Size );
@ -139,7 +139,8 @@ extern int Cut_TableLookup( Cut_HashTable_t * pTable, Cut_Cut_t
extern void Cut_TableClear( Cut_HashTable_t * pTable );
extern int Cut_TableReadTime( Cut_HashTable_t * pTable );
/*=== cutTruth.c ==========================================================*/
extern void Cut_TruthCompute( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 );
extern void Cut_TruthComputeOld( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 );
extern void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 );
#endif

View File

@ -61,22 +61,30 @@ Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams )
Vec_PtrFill( p->vCutsOld, pParams->nIdsMax, NULL );
p->vCutsTemp = Vec_PtrAlloc( pParams->nCutSet );
Vec_PtrFill( p->vCutsTemp, pParams->nCutSet, NULL );
if ( pParams->fTruth && pParams->nVarsMax > 5 )
{
pParams->fTruth = 0;
printf( "Skipping computation of truth tables for sequential cuts with more than 5 inputs.\n" );
}
}
assert( !pParams->fTruth || pParams->nVarsMax <= 5 );
// entry size
p->EntrySize = sizeof(Cut_Cut_t) + pParams->nVarsMax * sizeof(int);
if ( pParams->fTruth )
{
if ( pParams->nVarsMax > 8 )
if ( pParams->nVarsMax > 14 )
{
pParams->fTruth = 0;
printf( "Skipping computation of truth table for more than 8 inputs.\n" );
printf( "Skipping computation of truth table for more than %d inputs.\n", 14 );
}
else
{
p->nTruthWords = Cut_TruthWords( pParams->nVarsMax );
p->EntrySize += p->nTruthWords * sizeof(unsigned);
}
p->puTemp[0] = ALLOC( unsigned, 4 * p->nTruthWords );
p->puTemp[1] = p->puTemp[0] + p->nTruthWords;
p->puTemp[2] = p->puTemp[1] + p->nTruthWords;
p->puTemp[3] = p->puTemp[2] + p->nTruthWords;
}
// enable cut computation recording
if ( pParams->fRecord )
@ -120,6 +128,7 @@ void Cut_ManStop( Cut_Man_t * p )
if ( p->vNodeCuts ) Vec_IntFree( p->vNodeCuts );
if ( p->vNodeStarts ) Vec_IntFree( p->vNodeStarts );
if ( p->vCutPairs ) Vec_IntFree( p->vCutPairs );
if ( p->puTemp[0] ) free( p->puTemp[0] );
Extra_MmFixedStop( p->pMmCuts, 0 );
free( p );
@ -153,15 +162,10 @@ void Cut_ManPrintStats( Cut_Man_t * p )
printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsCur-p->nCutsTriv))/p->nNodes );
printf( "The cut size = %8d bytes.\n", p->EntrySize );
printf( "Peak memory = %8.2f Mb.\n", (float)p->nCutsPeak * p->EntrySize / (1<<20) );
if ( p->pParams->fMulti )
{
printf( "Factor-cut computation statistics:\n" );
printf( "Total nodes = %8d.\n", p->nNodes );
printf( "Factor nodes = %8d.\n", p->nNodesMulti );
printf( "Factor nodes 0 = %8d.\n", p->nNodesMulti0 );
printf( "Factor cuts = %8d.\n", p->nCutsMulti );
printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsMulti))/(p->nNodesMulti-p->nNodesMulti0) );
}
printf( "DAG nodes = %8d.\n", p->nNodesDag );
printf( "Tree nodes = %8d.\n", p->nNodes - p->nNodesDag );
printf( "Nodes w/o cuts = %8d.\n", p->nNodesNoCuts );
PRT( "Merge ", p->timeMerge );
PRT( "Union ", p->timeUnion );
PRT( "Filter", p->timeFilter );
@ -229,6 +233,22 @@ int Cut_ManReadVarsMax( Cut_Man_t * p )
return p->pParams->nVarsMax;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_ManIncrementDagNodes( Cut_Man_t * p )
{
p->nNodesDag++;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -277,7 +277,7 @@ static inline int Cut_CutProcessTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t
}
// compute the truth table
if ( p->pParams->fTruth )
Cut_TruthCompute( pCut, pCut0, pCut1, p->fCompl0, p->fCompl1 );
Cut_TruthCompute( p, pCut, pCut0, pCut1, p->fCompl0, p->fCompl1 );
// add to the list
Cut_ListAdd( pSuperList, pCut );
// return status (0 if okay; 1 if exceeded the limit)
@ -295,7 +295,7 @@ static inline int Cut_CutProcessTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t
SeeAlso []
***********************************************************************/
Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv )
Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode )
{
Cut_List_t Super, * pSuper = &Super;
Cut_Cut_t * pList, * pCut;
@ -312,7 +312,7 @@ Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1,
// compute the cuts
clk = clock();
Cut_ListStart( pSuper );
Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, Cut_NodeReadCutsNew(p, Node0), Cut_NodeReadCutsNew(p, Node1), fTriv );
Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, Cut_NodeReadCutsNew(p, Node0), Cut_NodeReadCutsNew(p, Node1), fTriv, TreeCode );
pList = Cut_ListFinish( pSuper );
p->timeMerge += clock() - clk;
// verify the result of cut computation
@ -351,9 +351,9 @@ p->timeMerge += clock() - clk;
SeeAlso []
***********************************************************************/
void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fCompl0, int fCompl1, Cut_Cut_t * pList0, Cut_Cut_t * pList1, int fTriv )
void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fCompl0, int fCompl1, Cut_Cut_t * pList0, Cut_Cut_t * pList1, int fTriv, int TreeCode )
{
Cut_Cut_t * pStop0, * pStop1, * pTemp0, * pTemp1;
Cut_Cut_t * pStop0, * pStop1, * pTemp0, * pTemp1, * pStore0, * pStore1;
int i, nCutsOld, Limit;
// start with the elementary cut
if ( fTriv )
@ -375,6 +375,19 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
// set temporary variables
p->fCompl0 = fCompl0;
p->fCompl1 = fCompl1;
// if tree cuts are computed, make sure only the unit cuts propagate over the DAG nodes
if ( TreeCode & 1 )
{
assert( pList0->nLeaves == 1 );
pStore0 = pList0->pNext;
pList0->pNext = NULL;
}
if ( TreeCode & 2 )
{
assert( pList1->nLeaves == 1 );
pStore1 = pList1->pNext;
pList1->pNext = NULL;
}
// find the point in the list where the max-var cuts begin
Cut_ListForEachCut( pList0, pStop0 )
if ( pStop0->nLeaves == (unsigned)Limit )
@ -386,8 +399,10 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
// small by small
Cut_ListForEachCutStop( pList0, pTemp0, pStop0 )
Cut_ListForEachCutStop( pList1, pTemp1, pStop1 )
{
if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) )
return;
goto Quits;
}
// small by large
Cut_ListForEachCutStop( pList0, pTemp0, pStop0 )
Cut_ListForEachCut( pStop1, pTemp1 )
@ -395,7 +410,7 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
if ( (pTemp0->uSign & pTemp1->uSign) != pTemp0->uSign )
continue;
if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) )
return;
goto Quits;
}
// small by large
Cut_ListForEachCutStop( pList1, pTemp1, pStop1 )
@ -404,7 +419,7 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
if ( (pTemp0->uSign & pTemp1->uSign) != pTemp1->uSign )
continue;
if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) )
return;
goto Quits;
}
// large by large
Cut_ListForEachCut( pStop0, pTemp0 )
@ -419,15 +434,15 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC
if ( i < Limit )
continue;
if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) )
return;
goto Quits;
}
if ( fTriv )
{
p->nCutsMulti += p->nCutsCur - nCutsOld;
p->nNodesMulti++;
if ( p->nCutsCur == nCutsOld )
p->nNodesMulti0++;
}
if ( p->nNodeCuts == 0 )
p->nNodesNoCuts++;
Quits:
if ( TreeCode & 1 )
pList0->pNext = pStore0;
if ( TreeCode & 2 )
pList1->pNext = pStore1;
}
/**Function*************************************************************

View File

@ -366,7 +366,7 @@ Cut_Cut_t * Cut_OracleComputeCuts( Cut_Oracle_t * p, int Node, int Node0, int No
ppTail = &pCut->pNext;
// compute the truth table
if ( p->pParams->fTruth )
Cut_TruthCompute( pCut, pCut0, pCut1, fCompl0, fCompl1 );
Cut_TruthComputeOld( pCut, pCut0, pCut1, fCompl0, fCompl1 );
}
*ppTail = NULL;

983
src/opt/cut/cutPre22.c Normal file
View File

@ -0,0 +1,983 @@
/**CFile****************************************************************
FileName [cutPre22.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Precomputes truth tables for the 2x2 macro cell.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: cutPre22.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "cutInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define CUT_CELL_MVAR 9
typedef struct Cut_Cell_t_ Cut_Cell_t;
typedef struct Cut_CMan_t_ Cut_CMan_t;
struct Cut_Cell_t_
{
Cut_Cell_t * pNext; // pointer to the next cell in the table
Cut_Cell_t * pNextVar; // pointer to the next cell of this support size
Cut_Cell_t * pParent; // pointer to the cell used to derive this one
int nUsed; // the number of times the cell is used
char Box[4]; // functions in the boxes
unsigned nVars : 4; // the number of variables
unsigned CrossBar0 : 4; // the variable set equal
unsigned CrossBar1 : 4; // the variable set equal
unsigned CrossBarPhase : 2; // the phase of the cross bar (0, 1, or 2)
unsigned CanonPhase : 18; // the canonical phase
char CanonPerm[CUT_CELL_MVAR+3]; // semicanonical permutation
short Store[2*CUT_CELL_MVAR]; // minterm counts in the cofactors
unsigned uTruth[1<<(CUT_CELL_MVAR-5)]; // the current truth table
};
struct Cut_CMan_t_
{
// storage for canonical cells
Extra_MmFixed_t * pMem;
st_table * tTable;
Cut_Cell_t * pSameVar[CUT_CELL_MVAR+1];
// elementary truth tables
unsigned uInputs[CUT_CELL_MVAR][1<<(CUT_CELL_MVAR-5)];
// temporary truth tables
unsigned uTemp1[22][1<<(CUT_CELL_MVAR-5)];
unsigned uTemp2[22][1<<(CUT_CELL_MVAR-5)];
unsigned uTemp3[22][1<<(CUT_CELL_MVAR-5)];
unsigned uFinal[1<<(CUT_CELL_MVAR-5)];
unsigned puAux[1<<(CUT_CELL_MVAR-5)];
// statistical variables
int nTotal;
int nGood;
int nVarCounts[CUT_CELL_MVAR+1];
int nSymGroups[CUT_CELL_MVAR+1];
int nSymGroupsE[CUT_CELL_MVAR+1];
int timeCanon;
int timeSupp;
int timeTable;
int nCellFound;
int nCellNotFound;
};
// NP-classes of functions of 3 variables (22)
static char * s_NP3[22] = {
" 0\n", // 00 const 0 // 0 vars
" 1\n", // 01 const 1 // 0 vars
"1 1\n", // 02 a // 1 vars
"11 1\n", // 03 ab // 2 vars
"11 0\n", // 04 (ab)' // 2 vars
"10 1\n01 1\n", // 05 a<+>b // 2 vars
"111 1\n", // 06 0s abc // 3 vars
"111 0\n", // 07 (abc)' //
"11- 1\n1-1 1\n", // 08 1p a(b+c) //
"11- 0\n1-1 0\n", // 09 (a(b+c))' //
"111 1\n100 1\n010 1\n001 1\n", // 10 2s a<+>b<+>c //
"10- 0\n1-0 0\n011 0\n", // 11 3p a<+>bc //
"101 1\n110 1\n", // 12 4p a(b<+>c) //
"101 0\n110 0\n", // 13 (a(b<+>c))' //
"11- 1\n1-1 1\n-11 1\n", // 14 5s ab+bc+ac //
"111 1\n000 1\n", // 15 6s abc+a'b'c' //
"111 0\n000 0\n", // 16 (abc+a'b'c')' //
"11- 1\n-11 1\n0-1 1\n", // 17 7 ab+bc+a'c //
"011 1\n101 1\n110 1\n", // 18 8s a'bc+ab'c+abc' //
"011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')' //
"100 1\n-11 1\n", // 20 9p ab'c'+bc //
"100 0\n-11 0\n" // 21 (ab'c'+bc)' //
};
// NP-classes of functions of 3 variables (22)
static char * s_NP3Names[22] = {
" const 0 ",
" const 1 ",
" a ",
" ab ",
" (ab)' ",
" a<+>b ",
"0s abc ",
" (abc)' ",
"1p a(b+c) ",
" (a(b+c))' ",
"2s a<+>b<+>c ",
"3p a<+>bc ",
"4p a(b<+>c) ",
" (a(b<+>c))' ",
"5s ab+bc+ac ",
"6s abc+a'b'c' ",
" (abc+a'b'c')' ",
"7 ab+bc+a'c ",
"8s a'bc+ab'c+abc' ",
" (a'bc+ab'c+abc')' ",
"9p ab'c'+bc ",
" (ab'c'+bc)' "
};
// the number of variables in each function
static int s_NP3VarNums[22] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
// NPN classes of functions of exactly 3 inputs (10)
static int s_NPNe3[10] = { 6, 8, 10, 11, 12, 14, 15, 17, 18, 20 };
// NPN classes of functions of exactly 3 inputs that are symmetric (5)
static int s_NPNe3s[10] = { 6, 10, 14, 15, 18 };
// NPN classes of functions of exactly 3 inputs (4)
static int s_NPNe3p[10] = { 8, 11, 12, 20 };
static Cut_CMan_t * Cut_CManStart();
static void Cut_CManStop( Cut_CMan_t * p );
static void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type );
static void Cut_CellCanonicize( Cut_CMan_t * p, Cut_Cell_t * pCell );
static int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell );
static void Cut_CellSuppMin( Cut_Cell_t * pCell );
static void Cut_CellCrossBar( Cut_Cell_t * pCell );
static Cut_CMan_t * s_pCMan = NULL;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Start the precomputation manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_CellLoad()
{
FILE * pFile;
char * pFileName = "cells22_daomap_iwls.txt";
char pString[1000];
Cut_CMan_t * p;
Cut_Cell_t * pCell;
int Length; //, i;
pFile = fopen( pFileName, "r" );
if ( pFile == NULL )
{
printf( "Cannot open file \"%s\".\n", pFileName );
return;
}
// start the manager
p = Cut_CManStart();
// load truth tables
while ( fgets(pString, 1000, pFile) )
{
Length = strlen(pString);
pString[Length--] = 0;
if ( Length == 0 )
continue;
// derive the cell
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
memset( pCell, 0, sizeof(Cut_Cell_t) );
pCell->nVars = Extra_Base2Log(Length*4);
pCell->nUsed = 1;
// Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
Extra_ReadHexadecimal( pCell->uTruth, pString, pCell->nVars );
Cut_CellSuppMin( pCell );
/*
// set the elementary permutation
for ( i = 0; i < (int)pCell->nVars; i++ )
pCell->CanonPerm[i] = i;
// canonicize
pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
*/
// add to the table
p->nTotal++;
if ( !Cut_CellTableLookup( p, pCell ) ) // new cell
p->nGood++;
}
printf( "Read %d cells from file \"%s\". Added %d cells to the table.\n", p->nTotal, pFileName, p->nGood );
fclose( pFile );
// return p;
}
/**Function*************************************************************
Synopsis [Precomputes truth tables for the 2x2 macro cell.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_CellPrecompute()
{
Cut_CMan_t * p;
Cut_Cell_t * pCell, * pTemp;
int i1, i2, i3, i, j, k, c, clk = clock(), clk2 = clock();
p = Cut_CManStart();
// precompute truth tables
for ( i = 0; i < 22; i++ )
Cut_CellTruthElem( p->uInputs[0], p->uInputs[1], p->uInputs[2], p->uTemp1[i], 9, i );
for ( i = 0; i < 22; i++ )
Cut_CellTruthElem( p->uInputs[3], p->uInputs[4], p->uInputs[5], p->uTemp2[i], 9, i );
for ( i = 0; i < 22; i++ )
Cut_CellTruthElem( p->uInputs[6], p->uInputs[7], p->uInputs[8], p->uTemp3[i], 9, i );
/*
if ( k == 8 && ((i1 == 6 && i2 == 14 && i3 == 20) || (i1 == 20 && i2 == 6 && i3 == 14)) )
{
Extra_PrintBinary( stdout, &pCell->CanonPhase, pCell->nVars+1 ); printf( " : " );
for ( i = 0; i < pCell->nVars; i++ )
printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars );
printf( "\n" );
}
*/
/*
// go through symmetric roots
for ( k = 0; k < 5; k++ )
for ( i1 = 0; i1 < 22; i1++ )
for ( i2 = i1; i2 < 22; i2++ )
for ( i3 = i2; i3 < 22; i3++ )
{
// derive the cell
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
memset( pCell, 0, sizeof(Cut_Cell_t) );
pCell->nVars = 9;
pCell->Box[0] = s_NPNe3s[k];
pCell->Box[1] = i1;
pCell->Box[2] = i2;
pCell->Box[3] = i3;
// fill in the truth table
Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3s[k] );
// canonicize
Cut_CellCanonicize( pCell );
// add to the table
p->nTotal++;
if ( Cut_CellTableLookup( p, pCell ) ) // already exists
Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
else
p->nGood++;
}
// go through partially symmetric roots
for ( k = 0; k < 4; k++ )
for ( i1 = 0; i1 < 22; i1++ )
for ( i2 = 0; i2 < 22; i2++ )
for ( i3 = i2; i3 < 22; i3++ )
{
// derive the cell
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
memset( pCell, 0, sizeof(Cut_Cell_t) );
pCell->nVars = 9;
pCell->Box[0] = s_NPNe3p[k];
pCell->Box[1] = i1;
pCell->Box[2] = i2;
pCell->Box[3] = i3;
// fill in the truth table
Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3p[k] );
// canonicize
Cut_CellCanonicize( pCell );
// add to the table
p->nTotal++;
if ( Cut_CellTableLookup( p, pCell ) ) // already exists
Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
else
p->nGood++;
}
// go through non-symmetric functions
for ( i1 = 0; i1 < 22; i1++ )
for ( i2 = 0; i2 < 22; i2++ )
for ( i3 = 0; i3 < 22; i3++ )
{
// derive the cell
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
memset( pCell, 0, sizeof(Cut_Cell_t) );
pCell->nVars = 9;
pCell->Box[0] = 17;
pCell->Box[1] = i1;
pCell->Box[2] = i2;
pCell->Box[3] = i3;
// fill in the truth table
Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, 17 );
// canonicize
Cut_CellCanonicize( pCell );
// add to the table
p->nTotal++;
if ( Cut_CellTableLookup( p, pCell ) ) // already exists
Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
else
p->nGood++;
}
*/
// go through non-symmetric functions
for ( k = 0; k < 10; k++ )
for ( i1 = 0; i1 < 22; i1++ )
for ( i2 = 0; i2 < 22; i2++ )
for ( i3 = 0; i3 < 22; i3++ )
{
// derive the cell
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
memset( pCell, 0, sizeof(Cut_Cell_t) );
pCell->nVars = 9;
pCell->Box[0] = s_NPNe3[k];
pCell->Box[1] = i1;
pCell->Box[2] = i2;
pCell->Box[3] = i3;
// set the elementary permutation
for ( i = 0; i < (int)pCell->nVars; i++ )
pCell->CanonPerm[i] = i;
// fill in the truth table
Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3[k] );
// minimize the support
Cut_CellSuppMin( pCell );
// canonicize
pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
// add to the table
p->nTotal++;
if ( Cut_CellTableLookup( p, pCell ) ) // already exists
Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
else
{
p->nGood++;
p->nVarCounts[pCell->nVars]++;
if ( pCell->nVars )
for ( i = 0; i < (int)pCell->nVars-1; i++ )
{
if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
continue;
// i and i+1 can be symmetric
// find the end of this group
for ( j = i+1; j < (int)pCell->nVars; j++ )
if ( pCell->Store[2*i] != pCell->Store[2*j] )
break;
if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
p->nSymGroupsE[j-i]++;
else
p->nSymGroups[j-i]++;
i = j - 1;
}
/*
if ( pCell->nVars == 3 )
{
Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
for ( i = 0; i < (int)pCell->nVars; i++ )
printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
printf( "\n" );
}
*/
}
}
printf( "BASIC: Total = %d. Good = %d. Entry = %d. ", p->nTotal, p->nGood, sizeof(Cut_Cell_t) );
PRT( "Time", clock() - clk );
printf( "Cells: " );
for ( i = 0; i <= 9; i++ )
printf( "%d=%d ", i, p->nVarCounts[i] );
printf( "\nDiffs: " );
for ( i = 0; i <= 9; i++ )
printf( "%d=%d ", i, p->nSymGroups[i] );
printf( "\nEquals: " );
for ( i = 0; i <= 9; i++ )
printf( "%d=%d ", i, p->nSymGroupsE[i] );
printf( "\n" );
// continue adding new cells using support
for ( k = CUT_CELL_MVAR; k > 3; k-- )
{
for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
for ( i1 = 0; i1 < k; i1++ )
for ( i2 = i1+1; i2 < k; i2++ )
for ( c = 0; c < 3; c++ )
{
// derive the cell
pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem );
memset( pCell, 0, sizeof(Cut_Cell_t) );
pCell->nVars = pTemp->nVars;
pCell->pParent = pTemp;
// set the elementary permutation
for ( i = 0; i < (int)pCell->nVars; i++ )
pCell->CanonPerm[i] = i;
// fill in the truth table
Extra_TruthCopy( pCell->uTruth, pTemp->uTruth, pTemp->nVars );
// create the cross-bar
pCell->CrossBar0 = i1;
pCell->CrossBar1 = i2;
pCell->CrossBarPhase = c;
Cut_CellCrossBar( pCell );
// minimize the support
//clk2 = clock();
Cut_CellSuppMin( pCell );
//p->timeSupp += clock() - clk2;
// canonicize
//clk2 = clock();
pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
//p->timeCanon += clock() - clk2;
// add to the table
//clk2 = clock();
p->nTotal++;
if ( Cut_CellTableLookup( p, pCell ) ) // already exists
Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell );
else
{
p->nGood++;
p->nVarCounts[pCell->nVars]++;
for ( i = 0; i < (int)pCell->nVars-1; i++ )
{
if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric
continue;
// i and i+1 can be symmetric
// find the end of this group
for ( j = i+1; j < (int)pCell->nVars; j++ )
if ( pCell->Store[2*i] != pCell->Store[2*j] )
break;
if ( pCell->Store[2*i] == pCell->Store[2*i+1] )
p->nSymGroupsE[j-i]++;
else
p->nSymGroups[j-i]++;
i = j - 1;
}
/*
if ( pCell->nVars == 3 )
{
Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" );
for ( i = 0; i < (int)pCell->nVars; i++ )
printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] );
printf( "\n" );
}
*/
}
//p->timeTable += clock() - clk2;
}
printf( "VAR %d: Total = %d. Good = %d. Entry = %d. ", k, p->nTotal, p->nGood, sizeof(Cut_Cell_t) );
PRT( "Time", clock() - clk );
printf( "Cells: " );
for ( i = 0; i <= 9; i++ )
printf( "%d=%d ", i, p->nVarCounts[i] );
printf( "\nDiffs: " );
for ( i = 0; i <= 9; i++ )
printf( "%d=%d ", i, p->nSymGroups[i] );
printf( "\nEquals: " );
for ( i = 0; i <= 9; i++ )
printf( "%d=%d ", i, p->nSymGroupsE[i] );
printf( "\n" );
}
// printf( "\n" );
PRT( "Supp ", p->timeSupp );
PRT( "Canon", p->timeCanon );
PRT( "Table", p->timeTable );
// Cut_CManStop( p );
}
/**Function*************************************************************
Synopsis [Check the table.]
Description [Returns 1 if such a truth table already exists.]
SideEffects []
SeeAlso []
***********************************************************************/
int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell )
{
Cut_Cell_t ** pSlot, * pTemp;
unsigned Hash;
Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum( pCell->nVars ) );
if ( !st_find_or_add( p->tTable, (char *)Hash, (char ***)&pSlot ) )
*pSlot = NULL;
for ( pTemp = *pSlot; pTemp; pTemp = pTemp->pNext )
{
if ( pTemp->nVars != pCell->nVars )
continue;
if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
return 1;
}
// the entry is new
pCell->pNext = *pSlot;
*pSlot = pCell;
// add it to the variable support list
pCell->pNextVar = p->pSameVar[pCell->nVars];
p->pSameVar[pCell->nVars] = pCell;
return 0;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_CellSuppMin( Cut_Cell_t * pCell )
{
static unsigned uTemp[1<<(CUT_CELL_MVAR-5)];
unsigned * pIn, * pOut, * pTemp;
int i, k, Counter, Temp;
// go backward through the support variables and remove redundant
for ( k = pCell->nVars - 1; k >= 0; k-- )
if ( !Extra_TruthVarInSupport(pCell->uTruth, pCell->nVars, k) )
{
// shift all the variables above this one
Counter = 0;
pIn = pCell->uTruth; pOut = uTemp;
for ( i = k; i < (int)pCell->nVars - 1; i++ )
{
Extra_TruthSwapAdjacentVars( pOut, pIn, pCell->nVars, i );
pTemp = pIn; pIn = pOut; pOut = pTemp;
// swap the support vars
Temp = pCell->CanonPerm[i];
pCell->CanonPerm[i] = pCell->CanonPerm[i+1];
pCell->CanonPerm[i+1] = Temp;
Counter++;
}
// return the function back into its place
if ( Counter & 1 )
Extra_TruthCopy( pOut, pIn, pCell->nVars );
// remove one variable
pCell->nVars--;
// Extra_PrintBinary( stdout, pCell->uTruth, (1<<pCell->nVars) ); printf( "\n" );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_CellCrossBar( Cut_Cell_t * pCell )
{
static unsigned uTemp0[1<<(CUT_CELL_MVAR-5)];
static unsigned uTemp1[1<<(CUT_CELL_MVAR-5)];
Extra_TruthCopy( uTemp0, pCell->uTruth, pCell->nVars );
Extra_TruthCopy( uTemp1, pCell->uTruth, pCell->nVars );
if ( pCell->CanonPhase == 0 )
{
Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
}
else if ( pCell->CanonPhase == 1 )
{
Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar0 );
Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 );
Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar0 );
Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 );
}
else if ( pCell->CanonPhase == 2 )
{
Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 );
Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar1 );
Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 );
Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar1 );
}
else assert( 0 );
Extra_TruthCombine( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type )
{
int nWords = Extra_TruthWordNum( nVars );
int i;
assert( Type < 22 );
switch ( Type )
{
// " 0\n", // 00 const 0
case 0:
for ( i = 0; i < nWords; i++ )
pOut[i] = 0;
return;
// " 1\n", // 01 const 1
case 1:
for ( i = 0; i < nWords; i++ )
pOut[i] = 0xFFFFFFFF;
return;
// "1 1\n", // 02 a
case 2:
for ( i = 0; i < nWords; i++ )
pOut[i] = InA[i];
return;
// "11 1\n", // 03 ab
case 3:
for ( i = 0; i < nWords; i++ )
pOut[i] = InA[i] & InB[i];
return;
// "11 0\n", // 04 (ab)'
case 4:
for ( i = 0; i < nWords; i++ )
pOut[i] = ~(InA[i] & InB[i]);
return;
// "10 1\n01 1\n", // 05 a<+>b
case 5:
for ( i = 0; i < nWords; i++ )
pOut[i] = InA[i] ^ InB[i];
return;
// "111 1\n", // 06 + abc
case 6:
for ( i = 0; i < nWords; i++ )
pOut[i] = InA[i] & InB[i] & InC[i];
return;
// "111 0\n", // 07 (abc)'
case 7:
for ( i = 0; i < nWords; i++ )
pOut[i] = ~(InA[i] & InB[i] & InC[i]);
return;
// "11- 1\n1-1 1\n", // 08 + a(b+c)
case 8:
for ( i = 0; i < nWords; i++ )
pOut[i] = InA[i] & (InB[i] | InC[i]);
return;
// "11- 0\n1-1 0\n", // 09 (a(b+c))'
case 9:
for ( i = 0; i < nWords; i++ )
pOut[i] = ~(InA[i] & (InB[i] | InC[i]));
return;
// "111 1\n100 1\n010 1\n001 1\n", // 10 + a<+>b<+>c
case 10:
for ( i = 0; i < nWords; i++ )
pOut[i] = InA[i] ^ InB[i] ^ InC[i];
return;
// "10- 0\n1-0 0\n011 0\n", // 11 + a<+>bc
case 11:
for ( i = 0; i < nWords; i++ )
pOut[i] = InA[i] ^ (InB[i] & InC[i]);
return;
// "101 1\n110 1\n", // 12 + a(b<+>c)
case 12:
for ( i = 0; i < nWords; i++ )
pOut[i] = InA[i] & (InB[i] ^ InC[i]);
return;
// "101 0\n110 0\n", // 13 (a(b<+>c))'
case 13:
for ( i = 0; i < nWords; i++ )
pOut[i] = ~(InA[i] & (InB[i] ^ InC[i]));
return;
// "11- 1\n1-1 1\n-11 1\n", // 14 + ab+bc+ac
case 14:
for ( i = 0; i < nWords; i++ )
pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (InA[i] & InC[i]);
return;
// "111 1\n000 1\n", // 15 + abc+a'b'c'
case 15:
for ( i = 0; i < nWords; i++ )
pOut[i] = (InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]);
return;
// "111 0\n000 0\n", // 16 (abc+a'b'c')'
case 16:
for ( i = 0; i < nWords; i++ )
pOut[i] = ~((InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]));
return;
// "11- 1\n-11 1\n0-1 1\n", // 17 + ab+bc+a'c
case 17:
for ( i = 0; i < nWords; i++ )
pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (~InA[i] & InC[i]);
return;
// "011 1\n101 1\n110 1\n", // 18 + a'bc+ab'c+abc'
case 18:
for ( i = 0; i < nWords; i++ )
pOut[i] = (~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]);
return;
// "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')'
case 19:
for ( i = 0; i < nWords; i++ )
pOut[i] = ~((~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]));
return;
// "100 1\n-11 1\n", // 20 + ab'c'+bc
case 20:
for ( i = 0; i < nWords; i++ )
pOut[i] = (InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]);
return;
// "100 0\n-11 0\n" // 21 (ab'c'+bc)'
case 21:
for ( i = 0; i < nWords; i++ )
pOut[i] = ~((InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]));
return;
}
}
/**Function*************************************************************
Synopsis [Start the precomputation manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Cut_CMan_t * Cut_CManStart()
{
Cut_CMan_t * p;
int i, k;
// start the manager
assert( sizeof(unsigned) == 4 );
p = ALLOC( Cut_CMan_t, 1 );
memset( p, 0, sizeof(Cut_CMan_t) );
// start the table and the memory manager
p->tTable = st_init_table(st_ptrcmp,st_ptrhash);
p->pMem = Extra_MmFixedStart( sizeof(Cut_Cell_t) );
// set elementary truth tables
for ( k = 0; k < CUT_CELL_MVAR; k++ )
for ( i = 0; i < (1<<CUT_CELL_MVAR); i++ )
if ( i & (1 << k) )
p->uInputs[k][i/32] |= (1 << (i%32));
s_pCMan = p;
return p;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_CManStop( Cut_CMan_t * p )
{
st_free_table( p->tTable );
Extra_MmFixedStop( p->pMem, 0 );
free( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Cut_CellIsRunning()
{
return s_pCMan != NULL;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_CellDumpToFile()
{
FILE * pFile;
Cut_CMan_t * p = s_pCMan;
Cut_Cell_t * pTemp;
char * pFileName = "celllib22.txt";
int NumUsed[10][5] = {{0}};
int BoxUsed[22][5] = {{0}};
int i, k, Counter;
int clk = clock();
if ( p == NULL )
{
printf( "Cut_CellDumpToFile: Cell manager is not defined.\n" );
return;
}
// count the number of cells used
for ( k = CUT_CELL_MVAR; k >= 0; k-- )
{
for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
{
if ( pTemp->nUsed == 0 )
NumUsed[k][0]++;
else if ( pTemp->nUsed < 10 )
NumUsed[k][1]++;
else if ( pTemp->nUsed < 100 )
NumUsed[k][2]++;
else if ( pTemp->nUsed < 1000 )
NumUsed[k][3]++;
else
NumUsed[k][4]++;
for ( i = 0; i < 4; i++ )
if ( pTemp->nUsed == 0 )
BoxUsed[ pTemp->Box[i] ][0]++;
else if ( pTemp->nUsed < 10 )
BoxUsed[ pTemp->Box[i] ][1]++;
else if ( pTemp->nUsed < 100 )
BoxUsed[ pTemp->Box[i] ][2]++;
else if ( pTemp->nUsed < 1000 )
BoxUsed[ pTemp->Box[i] ][3]++;
else
BoxUsed[ pTemp->Box[i] ][4]++;
}
}
printf( "Functions found = %10d. Functions not found = %10d.\n", p->nCellFound, p->nCellNotFound );
for ( k = 0; k <= CUT_CELL_MVAR; k++ )
{
printf( "%3d : ", k );
for ( i = 0; i < 5; i++ )
printf( "%8d ", NumUsed[k][i] );
printf( "\n" );
}
printf( "Box usage:\n" );
for ( k = 0; k < 22; k++ )
{
printf( "%3d : ", k );
for ( i = 0; i < 5; i++ )
printf( "%8d ", BoxUsed[k][i] );
printf( " %s", s_NP3Names[k] );
printf( "\n" );
}
pFile = fopen( pFileName, "w" );
if ( pFile == NULL )
{
printf( "Cut_CellDumpToFile: Cannout open output file.\n" );
return;
}
Counter = 0;
for ( k = 0; k <= CUT_CELL_MVAR; k++ )
{
for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar )
if ( pTemp->nUsed > 0 )
{
Extra_PrintHexadecimal( pFile, pTemp->uTruth, (k <= 5? 5 : k) );
fprintf( pFile, "\n" );
Counter++;
}
fprintf( pFile, "\n" );
}
fclose( pFile );
printf( "Library composed of %d functions is written into file \"%s\". ", Counter, pFileName );
PRT( "Time", clock() - clk );
}
/**Function*************************************************************
Synopsis [Looks up if the given function exists in the hash table.]
Description [If the function exists, returns 1, meaning that it can be
implemented using two levels of 3-input LUTs. If the function does not
exist, return 0.]
SideEffects []
SeeAlso []
***********************************************************************/
int Cut_CellTruthLookup( unsigned * pTruth, int nVars )
{
Cut_CMan_t * p = s_pCMan;
Cut_Cell_t * pTemp;
Cut_Cell_t Cell, * pCell = &Cell;
unsigned Hash;
int i;
// cell manager is not defined
if ( p == NULL )
{
printf( "Cut_CellTruthLookup: Cell manager is not defined.\n" );
return 0;
}
// canonicize
memset( pCell, 0, sizeof(Cut_Cell_t) );
pCell->nVars = nVars;
Extra_TruthCopy( pCell->uTruth, pTruth, nVars );
Cut_CellSuppMin( pCell );
// set the elementary permutation
for ( i = 0; i < (int)pCell->nVars; i++ )
pCell->CanonPerm[i] = i;
// canonicize
pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store );
// check if the cell exists
Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum(pCell->nVars) );
if ( st_lookup( p->tTable, (char *)Hash, (char **)&pTemp ) )
{
for ( ; pTemp; pTemp = pTemp->pNext )
{
if ( pTemp->nVars != pCell->nVars )
continue;
if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) )
{
pTemp->nUsed++;
p->nCellFound++;
return 1;
}
}
}
p->nCellNotFound++;
return 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -109,9 +109,9 @@ void Cut_NodeComputeCutsSeq( Cut_Man_t * p, int Node, int Node0, int Node1, int
// merge the old and the new
clk = clock();
Cut_ListStart( pSuper );
Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[0], p->pStore1[1], 0 );
Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[0], 0 );
Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[1], fTriv );
Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[0], p->pStore1[1], 0, 0 );
Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[0], 0, 0 );
Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[1], fTriv, 0 );
pListNew = Cut_ListFinish( pSuper );
p->timeMerge += clock() - clk;

View File

@ -20,17 +20,27 @@
#include "cutInt.h"
/*
Truth tables computed in this package are represented as bit-strings
stored in the cut data structure. Cuts of any number of inputs have
the truth table with 2^k bits, where k is the max number of cut inputs.
*/
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
extern int nTotal = 0;
extern int nGood = 0;
extern int nEqual = 0;
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs truth table computation.]
Synopsis [Computes the stretching phase of the cut w.r.t. the merged cut.]
Description []
@ -56,6 +66,48 @@ static inline unsigned Cut_TruthPhase( Cut_Cut_t * pCut, Cut_Cut_t * pCut1 )
return uPhase;
}
/**Function*************************************************************
Synopsis [Performs truth table computation.]
Description [This procedure cannot be used while recording oracle
because it will overwrite Num0 and Num1.]
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_TruthNCanonicize( Cut_Cut_t * pCut )
{
unsigned uTruth;
unsigned * uCanon2;
char * pPhases2;
assert( pCut->nVarsMax < 6 );
// get the direct truth table
uTruth = *Cut_CutReadTruth(pCut);
// compute the direct truth table
Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 );
// uCanon[0] = uCanon2[0];
// uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0];
// uPhases[0] = pPhases2[0];
pCut->uCanon0 = uCanon2[0];
pCut->Num0 = pPhases2[0];
// get the complemented truth table
uTruth = ~*Cut_CutReadTruth(pCut);
// compute the direct truth table
Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 );
// uCanon[0] = uCanon2[0];
// uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0];
// uPhases[0] = pPhases2[0];
pCut->uCanon1 = uCanon2[0];
pCut->Num1 = pPhases2[0];
}
/**Function*************************************************************
Synopsis [Performs truth table computation.]
@ -67,7 +119,7 @@ static inline unsigned Cut_TruthPhase( Cut_Cut_t * pCut, Cut_Cut_t * pCut1 )
SeeAlso []
***********************************************************************/
void Cut_TruthCompute( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 )
void Cut_TruthComputeOld( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 )
{
static unsigned uTruth0[8], uTruth1[8];
int nTruthWords = Cut_TruthWords( pCut->nVarsMax );
@ -111,44 +163,56 @@ void Cut_TruthCompute( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, i
Synopsis [Performs truth table computation.]
Description [This procedure cannot be used while recording oracle
because it will overwrite Num0 and Num1.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Cut_TruthCanonicize( Cut_Cut_t * pCut )
void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 )
{
unsigned uTruth;
unsigned * uCanon2;
char * pPhases2;
assert( pCut->nVarsMax < 6 );
// permute the first table
if ( fCompl0 )
Extra_TruthNot( p->puTemp[0], Cut_CutReadTruth(pCut0), pCut->nVarsMax );
else
Extra_TruthCopy( p->puTemp[0], Cut_CutReadTruth(pCut0), pCut->nVarsMax );
Extra_TruthStretch( p->puTemp[2], p->puTemp[0], pCut0->nLeaves, pCut->nVarsMax, Cut_TruthPhase(pCut, pCut0) );
// permute the second table
if ( fCompl1 )
Extra_TruthNot( p->puTemp[1], Cut_CutReadTruth(pCut1), pCut->nVarsMax );
else
Extra_TruthCopy( p->puTemp[1], Cut_CutReadTruth(pCut1), pCut->nVarsMax );
Extra_TruthStretch( p->puTemp[3], p->puTemp[1], pCut1->nLeaves, pCut->nVarsMax, Cut_TruthPhase(pCut, pCut1) );
// produce the resulting table
if ( pCut->fCompl )
Extra_TruthNand( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax );
else
Extra_TruthAnd( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax );
// quit if no fancy computation is needed
if ( !p->pParams->fFancy )
return;
// get the direct truth table
uTruth = *Cut_CutReadTruth(pCut);
// count the total number of truth tables computed
nTotal++;
// compute the direct truth table
Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 );
// uCanon[0] = uCanon2[0];
// uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0];
// uPhases[0] = pPhases2[0];
pCut->uCanon0 = uCanon2[0];
pCut->Num0 = pPhases2[0];
// MAPPING INTO ALTERA 6-2 LOGIC BLOCKS
// call this procedure to find the minimum number of common variables in the cofactors
// if this number is less or equal than 3, the cut can be implemented using the 6-2 logic block
// if ( Extra_TruthMinCofSuppOverlap( Cut_CutReadTruth(pCut), pCut->nVarsMax, NULL ) <= 3 )
// nGood++;
// get the complemented truth table
uTruth = ~*Cut_CutReadTruth(pCut);
// compute the direct truth table
Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 );
// uCanon[0] = uCanon2[0];
// uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0];
// uPhases[0] = pPhases2[0];
pCut->uCanon1 = uCanon2[0];
pCut->Num1 = pPhases2[0];
// MAPPING INTO ACTEL 2x2 CELLS
// call this procedure to see if a semi-canonical form can be found in the lookup table
// (if it exists, then a two-level 3-input LUT implementation of the cut exists)
// Before this procedure is called, cell manager should be defined by calling
// Cut_CellLoad (make sure file "cells22_daomap_iwls.txt" is available in the working dir)
if ( Cut_CellIsRunning() && pCut->nVarsMax <= 9 )
nGood += Cut_CellTruthLookup( Cut_CutReadTruth(pCut), pCut->nVarsMax );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -4,5 +4,6 @@ SRC += src/opt/cut/cutApi.c \
src/opt/cut/cutMerge.c \
src/opt/cut/cutNode.c \
src/opt/cut/cutOracle.c \
src/opt/cut/cutPre22.c \
src/opt/cut/cutSeq.c \
src/opt/cut/cutTruth.c

View File

@ -66,7 +66,7 @@ int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int
Required = fUpdateLevel? Abc_NodeReadRequiredLevel(pNode) : ABC_INFINITY;
// get the node's cuts
clk = clock();
pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0 );
pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0, 0 );
assert( pCut != NULL );
p->timeCut += clock() - clk;

View File

@ -95,7 +95,7 @@ static inline int Aig_WordCountOnes( unsigned val )
val = (val & 0x33333333) + ((val>>2) & 0x33333333);
val = (val & 0x0F0F0F0F) + ((val>>4) & 0x0F0F0F0F);
val = (val & 0x00FF00FF) + ((val>>8) & 0x00FF00FF);
return (val & 0x0000FFFF) + (val>>8);
return (val & 0x0000FFFF) + (val>>16);
}
/**Function*************************************************************

View File

@ -41,6 +41,7 @@ static inline int lit_sign(lit l) { return (l & 1); }
static void Asat_ClauseWriteDimacs( FILE * pFile, clause * pC, bool fIncrement );
extern void Io_WriteCnfOutputPiMapping( FILE * pFile, int incrementVars );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@ -77,6 +78,7 @@ void Asat_SolverWriteDimacs( solver * p, char * pFileName, lit* assumptionsBegin
return;
}
fprintf( pFile, "c CNF generated by ABC on %s\n", Extra_TimeStamp() );
// Io_WriteCnfOutputPiMapping( pFile, incrementVars );
fprintf( pFile, "p cnf %d %d\n", p->size, nClauses );
// write the original clauses
@ -161,6 +163,31 @@ int * solver_get_model( solver * p, int * pVars, int nVars )
return pModel;
}
/**Function*************************************************************
Synopsis [Writes the given clause in a file in DIMACS format.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Asat_SatPrintStats( FILE * pFile, solver * p )
{
printf( "Start = %4d. Conf = %6d. Dec = %6d. Prop = %7d. Insp = %8d.\n",
(int)p->solver_stats.starts,
(int)p->solver_stats.conflicts,
(int)p->solver_stats.decisions,
(int)p->solver_stats.propagations,
(int)p->solver_stats.inspects );
printf( "Total runtime = %7.2f sec. Var select = %7.2f sec. Var update = %7.2f sec.\n",
(float)(p->timeTotal)/(float)(CLOCKS_PER_SEC),
(float)(p->timeSelect)/(float)(CLOCKS_PER_SEC),
(float)(p->timeUpdate)/(float)(CLOCKS_PER_SEC) );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

514
src/sat/asat/jfront.c Normal file
View File

@ -0,0 +1,514 @@
/**CFile****************************************************************
FileName [jfront.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [C-language MiniSat solver.]
Synopsis [Implementation of J-frontier.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: jfront.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
***********************************************************************/
#include <stdio.h>
#include <assert.h>
#include "solver.h"
#include "extra.h"
#include "vec.h"
/*
At any time during the solving process, the J-frontier is the set of currently
unassigned variables, each of which has at least one fanin/fanout variable that
is currently assigned. In the context of a CNF-based solver, default decisions
based on variable activity are modified to choose the most active variable among
those currently on the J-frontier.
*/
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// variable on the J-frontier
typedef struct Asat_JVar_t_ Asat_JVar_t;
struct Asat_JVar_t_
{
unsigned int Num; // variable number
unsigned int nRefs; // the number of adjacent assigned vars
unsigned int Prev; // the previous variable
unsigned int Next; // the next variable
unsigned int nFans; // the number of fanins/fanouts
unsigned int Fans[0]; // the fanin/fanout variables
};
// the J-frontier as a ring of variables
// (ring is used instead of list because it allows to control the insertion point)
typedef struct Asat_JRing_t_ Asat_JRing_t;
struct Asat_JRing_t_
{
Asat_JVar_t * pRoot; // the pointer to the root
int nItems; // the number of variables in the ring
};
// the J-frontier manager
struct Asat_JMan_t_
{
solver * pSat; // the SAT solver
Asat_JRing_t rVars; // the ring of variables
Vec_Ptr_t * vVars; // the pointers to variables
Extra_MmFlex_t * pMem; // the memory manager for variables
};
// getting hold of the given variable
static inline Asat_JVar_t * Asat_JManVar( Asat_JMan_t * p, int Num ) { return !Num? NULL : Vec_PtrEntry(p->vVars, Num); }
static inline Asat_JVar_t * Asat_JVarPrev( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return Asat_JManVar(p, pVar->Prev); }
static inline Asat_JVar_t * Asat_JVarNext( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return Asat_JManVar(p, pVar->Next); }
//The solver can communicate to the variable order the following parts:
//- the array of current assignments (pSat->pAssigns)
//- the array of variable activities (pSat->pdActivity)
//- the array of variables currently in the cone
//- the array of arrays of variables adjacent to each other
static inline int Asat_JVarIsInBoundary( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return pVar->Next > 0; }
static inline int Asat_JVarIsAssigned( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return p->pSat->assigns[pVar->Num] != l_Undef; }
//static inline int Asat_JVarIsUsedInCone( Asat_JMan_t * p, int Var ) { return p->pSat->vVarsUsed->pArray[i]; }
// manipulating the ring of variables
static void Asat_JRingAddLast( Asat_JMan_t * p, Asat_JVar_t * pVar );
static void Asat_JRingRemove( Asat_JMan_t * p, Asat_JVar_t * pVar );
// iterator through the entries in J-boundary
#define Asat_JRingForEachEntry( p, pVar, pNext ) \
for ( pVar = p->rVars.pRoot, \
pNext = pVar? Asat_JVarNext(p, pVar) : NULL; \
pVar; \
pVar = (pNext != p->rVars.pRoot)? pNext : NULL, \
pNext = pVar? Asat_JVarNext(p, pVar) : NULL )
// iterator through the adjacent variables
#define Asat_JVarForEachFanio( p, pVar, pFan, i ) \
for ( i = 0; (i < pVar->nFans) && (((pFan) = Asat_JManVar(p, pVar->Fans[i])), 1); i++ )
extern void Asat_JManAssign( Asat_JMan_t * p, int Var );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Start the J-frontier.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Asat_JMan_t * Asat_JManStart( solver * pSat, void * pCircuit )
{
Vec_Vec_t * vCircuit = pCircuit;
Asat_JMan_t * p;
Asat_JVar_t * pVar;
Vec_Int_t * vConnect;
int i, nBytes, Entry, k;
// make sure the number of variables is less than sizeof(unsigned int)
assert( Vec_VecSize(vCircuit) < (1 << 16) );
assert( Vec_VecSize(vCircuit) == pSat->size );
// allocate the manager
p = ALLOC( Asat_JMan_t, 1 );
memset( p, 0, sizeof(Asat_JMan_t) );
p->pSat = pSat;
p->pMem = Extra_MmFlexStart();
// fill in the variables
p->vVars = Vec_PtrAlloc( Vec_VecSize(vCircuit) );
for ( i = 0; i < Vec_VecSize(vCircuit); i++ )
{
vConnect = Vec_VecEntry( vCircuit, i );
nBytes = sizeof(Asat_JVar_t) + sizeof(int) * Vec_IntSize(vConnect);
nBytes = sizeof(void *) * (nBytes / sizeof(void *) + ((nBytes % sizeof(void *)) != 0));
pVar = (Asat_JVar_t *)Extra_MmFlexEntryFetch( p->pMem, nBytes );
memset( pVar, 0, nBytes );
pVar->Num = i;
// add fanins/fanouts
pVar->nFans = Vec_IntSize( vConnect );
Vec_IntForEachEntry( vConnect, Entry, k )
pVar->Fans[k] = Entry;
// add the variable
Vec_PtrPush( p->vVars, pVar );
}
// set the current assignments
Vec_PtrForEachEntryStart( p->vVars, pVar, i, 1 )
{
// if ( !Asat_JVarIsUsedInCone(p, pVar) )
// continue;
// skip assigned vars, vars in the boundary, and vars not used in the cone
if ( Asat_JVarIsAssigned(p, pVar) )
Asat_JManAssign( p, pVar->Num );
}
pSat->pJMan = p;
return p;
}
/**Function*************************************************************
Synopsis [Stops the J-frontier.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Asat_JManStop( solver * pSat )
{
Asat_JMan_t * p = pSat->pJMan;
if ( p == NULL )
return;
pSat->pJMan = NULL;
Extra_MmFlexStop( p->pMem, 0 );
Vec_PtrFree( p->vVars );
free( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Asat_JManCheck( Asat_JMan_t * p )
{
Asat_JVar_t * pVar, * pNext, * pFan;
// Msat_IntVec_t * vRound;
// int * pRound, nRound;
// int * pVars, nVars, i, k;
int i, k;
int Counter = 0;
// go through all the variables in the boundary
Asat_JRingForEachEntry( p, pVar, pNext )
{
assert( !Asat_JVarIsAssigned(p, pVar) );
// go though all the variables in the neighborhood
// and check that it is true that there is least one assigned
// vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVar->Num );
// nRound = Msat_IntVecReadSize( vRound );
// pRound = Msat_IntVecReadArray( vRound );
// for ( i = 0; i < nRound; i++ )
Asat_JVarForEachFanio( p, pVar, pFan, i )
{
// if ( !Asat_JVarIsUsedInCone(p, pFan) )
// continue;
if ( Asat_JVarIsAssigned(p, pFan) )
break;
}
// assert( i != pVar->nFans );
// if ( i == pVar->nFans )
// return 0;
if ( i == pVar->nFans )
Counter++;
}
if ( Counter > 0 )
printf( "%d(%d) ", Counter, p->rVars.nItems );
// we may also check other unassigned variables in the cone
// to make sure that if they are not in J-boundary,
// then they do not have an assigned neighbor
// nVars = Msat_IntVecReadSize( p->pSat->vConeVars );
// pVars = Msat_IntVecReadArray( p->pSat->vConeVars );
// for ( i = 0; i < nVars; i++ )
Vec_PtrForEachEntry( p->vVars, pVar, i )
{
// assert( Asat_JVarIsUsedInCone(p, pVar) );
// skip assigned vars, vars in the boundary, and vars not used in the cone
if ( Asat_JVarIsAssigned(p, pVar) || Asat_JVarIsInBoundary(p, pVar) )
continue;
// make sure, it does not have assigned neighbors
// vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVars[i] );
// nRound = Msat_IntVecReadSize( vRound );
// pRound = Msat_IntVecReadArray( vRound );
// for ( i = 0; i < nRound; i++ )
Asat_JVarForEachFanio( p, pVar, pFan, k )
{
// if ( !Asat_JVarIsUsedInCone(p, pFan) )
// continue;
if ( Asat_JVarIsAssigned(p, pFan) )
break;
}
// assert( k == pVar->nFans );
// if ( k != pVar->nFans )
// return 0;
}
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Asat_JManAssign( Asat_JMan_t * p, int Var )
{
// Msat_IntVec_t * vRound;
Asat_JVar_t * pVar, * pFan;
int i, clk = clock();
// make sure the variable is in the boundary
assert( Var < Vec_PtrSize(p->vVars) );
// if it is not in the boundary (initial decision, random decision), do not remove
pVar = Asat_JManVar( p, Var );
if ( Asat_JVarIsInBoundary( p, pVar ) )
Asat_JRingRemove( p, pVar );
// add to the boundary those neighbors that are (1) unassigned, (2) not in boundary
// because for them we know that there is a variable (Var) which is assigned
// vRound = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[Var];
// for ( i = 0; i < vRound->nSize; i++ )
Asat_JVarForEachFanio( p, pVar, pFan, i )
{
// if ( !Asat_JVarIsUsedInCone(p, pFan) )
// continue;
pFan->nRefs++;
if ( Asat_JVarIsAssigned(p, pFan) || Asat_JVarIsInBoundary(p, pFan) )
continue;
Asat_JRingAddLast( p, pFan );
}
//timeSelect += clock() - clk;
// Asat_JManCheck( p );
p->pSat->timeUpdate += clock() - clk;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Asat_JManUnassign( Asat_JMan_t * p, int Var )
{
// Msat_IntVec_t * vRound, * vRound2;
Asat_JVar_t * pVar, * pFan;
int i, clk = clock();//, k
// make sure the variable is not in the boundary
assert( Var < Vec_PtrSize(p->vVars) );
pVar = Asat_JManVar( p, Var );
assert( !Asat_JVarIsInBoundary( p, pVar ) );
// go through its neigbors - if one of them is assigned add this var
// add to the boundary those neighbors that are not there already
// this will also get rid of variable outside of the current cone
// because they are unassigned in Msat_SolverPrepare()
// vRound = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[Var];
// for ( i = 0; i < vRound->nSize; i++ )
// if ( Asat_JVarIsAssigned(p, vRound->pArray[i]) )
// break;
// if ( i != vRound->nSize )
// Asat_JRingAddLast( &p->rVars, &p->pVars[Var] );
if ( pVar->nRefs != 0 )
Asat_JRingAddLast( p, pVar );
/*
// unassigning a variable may lead to its adjacents dropping from the boundary
for ( i = 0; i < vRound->nSize; i++ )
if ( Asat_JVarIsInBoundary(p, vRound->pArray[i]) )
{ // the neighbor is in the J-boundary (and unassigned)
assert( !Asat_JVarIsAssigned(p, vRound->pArray[i]) );
vRound2 = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[vRound->pArray[i]];
// go through its neighbors and determine if there is at least one assigned
for ( k = 0; k < vRound2->nSize; k++ )
if ( Asat_JVarIsAssigned(p, vRound2->pArray[k]) )
break;
if ( k == vRound2->nSize ) // there is no assigned vars, delete this one
Asat_JRingRemove( &p->rVars, &p->pVars[vRound->pArray[i]] );
}
*/
Asat_JVarForEachFanio( p, pVar, pFan, i )
{
// if ( !Asat_JVarIsUsedInCone(p, pFan) )
// continue;
assert( pFan->nRefs > 0 );
pFan->nRefs--;
if ( !Asat_JVarIsInBoundary(p, pFan) )
continue;
// the neighbor is in the J-boundary (and unassigned)
assert( !Asat_JVarIsAssigned(p, pFan) );
// if there is no assigned vars, delete this one
if ( pFan->nRefs == 0 )
Asat_JRingRemove( p, pFan );
}
//timeSelect += clock() - clk;
// Asat_JManCheck( p );
p->pSat->timeUpdate += clock() - clk;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Asat_JManSelect( Asat_JMan_t * p )
{
Asat_JVar_t * pVar, * pNext, * pVarBest;
double * pdActs = p->pSat->activity;
double dfActBest;
int clk = clock();
pVarBest = NULL;
dfActBest = -1.0;
Asat_JRingForEachEntry( p, pVar, pNext )
{
if ( dfActBest <= pdActs[pVar->Num] )//+ 0.00001 )
{
dfActBest = pdActs[pVar->Num];
pVarBest = pVar;
}
}
//timeSelect += clock() - clk;
//timeAssign += clock() - clk;
//if ( pVarBest && pVarBest->Num % 1000 == 0 )
//printf( "%d ", p->rVars.nItems );
// Asat_JManCheck( p );
p->pSat->timeSelect += clock() - clk;
if ( pVarBest )
{
// assert( Asat_JVarIsUsedInCone(p, pVarBest) );
return pVarBest->Num;
}
return var_Undef;
}
/**Function*************************************************************
Synopsis [Adds node to the end of the ring.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Asat_JRingAddLast( Asat_JMan_t * p, Asat_JVar_t * pVar )
{
Asat_JRing_t * pRing = &p->rVars;
//printf( "adding %d\n", pVar->Num );
// check that the node is not in a ring
assert( pVar->Prev == 0 );
assert( pVar->Next == 0 );
// if the ring is empty, make the node point to itself
pRing->nItems++;
if ( pRing->pRoot == NULL )
{
pRing->pRoot = pVar;
// pVar->pPrev = pVar;
pVar->Prev = pVar->Num;
// pVar->pNext = pVar;
pVar->Next = pVar->Num;
return;
}
// if the ring is not empty, add it as the last entry
// pVar->pPrev = pRing->pRoot->pPrev;
pVar->Prev = pRing->pRoot->Prev;
// pVar->pNext = pRing->pRoot;
pVar->Next = pRing->pRoot->Num;
// pVar->pPrev->pNext = pVar;
Asat_JVarPrev(p, pVar)->Next = pVar->Num;
// pVar->pNext->pPrev = pVar;
Asat_JVarNext(p, pVar)->Prev = pVar->Num;
// move the root so that it points to the new entry
// pRing->pRoot = pRing->pRoot->pPrev;
pRing->pRoot = Asat_JVarPrev(p, pRing->pRoot);
}
/**Function*************************************************************
Synopsis [Removes the node from the ring.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Asat_JRingRemove( Asat_JMan_t * p, Asat_JVar_t * pVar )
{
Asat_JRing_t * pRing = &p->rVars;
//printf( "removing %d\n", pVar->Num );
// check that the var is in a ring
assert( pVar->Prev );
assert( pVar->Next );
pRing->nItems--;
if ( pRing->nItems == 0 )
{
assert( pRing->pRoot == pVar );
// pVar->pPrev = NULL;
pVar->Prev = 0;
// pVar->pNext = NULL;
pVar->Next = 0;
pRing->pRoot = NULL;
return;
}
// move the root if needed
if ( pRing->pRoot == pVar )
// pRing->pRoot = pVar->pNext;
pRing->pRoot = Asat_JVarNext(p, pVar);
// move the root to the next entry after pVar
// this way all the additions to the list will be traversed first
// pRing->pRoot = pVar->pNext;
pRing->pRoot = Asat_JVarPrev(p, pVar);
// delete the node
// pVar->pPrev->pNext = pVar->pNext;
Asat_JVarPrev(p, pVar)->Next = Asat_JVarNext(p, pVar)->Num;
// pVar->pNext->pPrev = pVar->pPrev;
Asat_JVarNext(p, pVar)->Prev = Asat_JVarPrev(p, pVar)->Num;
// pVar->pPrev = NULL;
pVar->Prev = 0;
// pVar->pNext = NULL;
pVar->Next = 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1,3 +1,4 @@
SRC += src/sat/asat/added.c \
src/sat/asat/asatmem.c \
src/sat/asat/jfront.c \
src/sat/asat/solver.c

View File

@ -121,6 +121,7 @@ static inline void vec_remove(vec* v, void* e)
static inline void order_update(solver* s, int v) // updateorder
{
// int clk = clock();
int* orderpos = s->orderpos;
double* activity = s->activity;
int* heap = (int*)vec_begin(&s->order);
@ -138,6 +139,7 @@ static inline void order_update(solver* s, int v) // updateorder
}
heap[i] = x;
orderpos[x] = i;
// s->timeUpdate += clock() - clk;
}
static inline void order_assigned(solver* s, int v)
@ -146,16 +148,19 @@ static inline void order_assigned(solver* s, int v)
static inline void order_unassigned(solver* s, int v) // undoorder
{
// int clk = clock();
int* orderpos = s->orderpos;
if (orderpos[v] == -1){
orderpos[v] = vec_size(&s->order);
vec_push(&s->order,(void*)v);
order_update(s,v);
}
// s->timeUpdate += clock() - clk;
}
static int order_select(solver* s, float random_var_freq) // selectvar
{
// int clk = clock();
int* heap;
double* activity;
int* orderpos;
@ -215,9 +220,15 @@ static int order_select(solver* s, float random_var_freq) // selectvar
return next;
}
// s->timeSelect += clock() - clk;
return var_Undef;
}
// J-frontier
extern void Asat_JManAssign( Asat_JMan_t * p, int Var );
extern void Asat_JManUnassign( Asat_JMan_t * p, int Var );
extern int Asat_JManSelect( Asat_JMan_t * p );
//=================================================================================================
// Activity functions:
@ -236,7 +247,7 @@ static inline void act_var_bump(solver* s, int v) {
//printf("bump %d %f\n", v-1, activity[v]);
if (s->orderpos[v] != -1)
if ( s->pJMan == NULL && s->orderpos[v] != -1 )
order_update(s,v);
}
@ -422,7 +433,10 @@ static inline bool enqueue(solver* s, lit l, clause* from)
reasons[v] = from;
s->trail[s->qtail++] = l;
order_assigned(s, v);
if ( s->pJMan )
Asat_JManAssign( s->pJMan, v );
else
order_assigned(s, v);
return 1;
}
}
@ -460,8 +474,12 @@ static inline void solver_canceluntil(solver* s, int level) {
reasons[x] = (clause*)0;
}
for (c = s->qhead-1; c >= bound; c--)
order_unassigned(s,lit_var(trail[c]));
if ( s->pJMan )
for (c = s->qtail-1; c >= bound; c--)
Asat_JManUnassign( s->pJMan, lit_var(trail[c]) );
else
for (c = s->qhead-1; c >= bound; c--)
order_unassigned( s, lit_var(trail[c]) );
s->qhead = s->qtail = bound;
vec_resize(&s->trail_lim,level);
@ -803,7 +821,7 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts)
int* levels = s->levels;
double var_decay = 0.95;
double clause_decay = 0.999;
double random_var_freq = 0.02;
double random_var_freq = 0.0;//0.02;
int conflictC = 0;
vec learnt_clause;
@ -872,7 +890,10 @@ static lbool solver_search(solver* s, int nof_conflicts, int nof_learnts)
// New variable decision:
s->solver_stats.decisions++;
next = order_select(s,(float)random_var_freq);
if ( s->pJMan )
next = Asat_JManSelect( s->pJMan );
else
next = order_select(s,(float)random_var_freq);
if (next == var_Undef){
// Model found:
@ -953,7 +974,10 @@ solver* solver_new(void)
#else
s->pMem = Asat_MmStepStart( 10 );
#endif
s->pJMan = NULL;
s->timeTotal = clock();
s->timeSelect = 0;
s->timeUpdate = 0;
return s;
}
@ -998,6 +1022,7 @@ void solver_delete(solver* s)
free(s->tags );
}
if ( s->pJMan ) Asat_JManStop( s );
free(s);
}
@ -1155,6 +1180,7 @@ bool solver_solve(solver* s, lit* begin, lit* end, int nConfLimit, int nImpLimit
printf("==============================================================================\n");
solver_canceluntil(s,0);
s->timeTotal = clock() - s->timeTotal;
return status;
}

View File

@ -64,6 +64,8 @@ static inline lit toLitCond (int v, int c) { return v + v + (int)(c != 0); }
//=================================================================================================
// Public interface:
typedef struct Asat_JMan_t_ Asat_JMan_t;
struct solver_t;
typedef struct solver_t solver;
@ -82,6 +84,12 @@ extern int solver_nclauses(solver* s);
extern void Asat_SolverWriteDimacs( solver * pSat, char * pFileName,
lit* assumptionsBegin, lit* assumptionsEnd,
int incrementVars);
extern void Asat_SatPrintStats( FILE * pFile, solver * p );
// J-frontier support
extern Asat_JMan_t * Asat_JManStart( solver * pSat, void * vCircuit );
extern void Asat_JManStop( solver * pSat );
struct stats_t
{
@ -143,7 +151,13 @@ struct solver_t
// the memory manager
Asat_MmStep_t * pMem;
// J-frontier
Asat_JMan_t * pJMan;
stats solver_stats;
int timeTotal;
int timeSelect;
int timeUpdate;
};
#ifdef __cplusplus

View File

@ -17,6 +17,7 @@
***********************************************************************/
#include "abc.h"
#include "fraig.h"
#include "csat_apis.h"
////////////////////////////////////////////////////////////////////////
@ -105,6 +106,8 @@ ABC_Manager ABC_InitManager()
***********************************************************************/
void ABC_ReleaseManager( ABC_Manager mng )
{
CSAT_Target_ResultT * p_res = ABC_Get_Target_Result( mng,0 );
ABC_TargetResFree(p_res);
if ( mng->tNode2Name ) stmm_free_table( mng->tNode2Name );
if ( mng->tName2Node ) stmm_free_table( mng->tName2Node );
if ( mng->pMmNames ) Extra_MmFlexStop( mng->pMmNames, 0 );
@ -536,6 +539,7 @@ void ABC_AnalyzeTargets( ABC_Manager mng )
***********************************************************************/
enum CSAT_StatusT ABC_Solve( ABC_Manager mng )
{
Prove_Params_t Params, * pParams = &Params;
int RetValue, i;
// check if the target network is available
@ -544,9 +548,16 @@ enum CSAT_StatusT ABC_Solve( ABC_Manager mng )
// try to prove the miter using a number of techniques
if ( mng->mode )
RetValue = Abc_NtkMiterSat( mng->pTarget, mng->nConfLimit, mng->nImpLimit, 0 );
RetValue = Abc_NtkMiterSat( mng->pTarget, mng->nConfLimit, mng->nImpLimit, 0, 0 );
else
RetValue = Abc_NtkMiterProve( &mng->pTarget, mng->nConfLimit, mng->nImpLimit, 1, 1, 0 );
{
// set default parameters for CEC
Prove_ParamsSetDefault( pParams );
// set infinite resource limit for the final mitering
pParams->nMiteringLimitLast = ABC_INFINITY;
// call the checker
RetValue = Abc_NtkMiterProve( &mng->pTarget, pParams );
}
// analyze the result
mng->pResult = ABC_TargetResAlloc( Abc_NtkCiNum(mng->pTarget) );
@ -658,6 +669,14 @@ void ABC_TargetResFree( CSAT_Target_ResultT * p )
{
if ( p == NULL )
return;
if( p->names )
{
int i = 0;
for ( i = 0; i < p->no_sig; i++ )
{
FREE(p->names[i]);
}
}
FREE( p->names );
FREE( p->values );
free( p );

View File

@ -41,6 +41,7 @@ typedef struct Fraig_NodeVecStruct_t_ Fraig_NodeVec_t;
typedef struct Fraig_HashTableStruct_t_ Fraig_HashTable_t;
typedef struct Fraig_ParamsStruct_t_ Fraig_Params_t;
typedef struct Fraig_PatternsStruct_t_ Fraig_Patterns_t;
typedef struct Prove_ParamsStruct_t_ Prove_Params_t;
struct Fraig_ParamsStruct_t_
{
@ -61,6 +62,31 @@ struct Fraig_ParamsStruct_t_
int fInternal; // is set to 1 for internal fraig calls
};
struct Prove_ParamsStruct_t_
{
// general parameters
int fUseFraiging; // enables fraiging
int fUseRewriting; // enables rewriting
int fUseBdds; // enables BDD construction when other methods fail
int fVerbose; // prints verbose stats
// iterations
int nItersMax; // the number of iterations
// mitering
int nMiteringLimitStart; // starting mitering limit
float nMiteringLimitMulti; // multiplicative coefficient to increase the limit in each iteration
// rewriting
int nRewritingLimitStart; // the number of rewriting iterations
float nRewritingLimitMulti; // multiplicative coefficient to increase the limit in each iteration
// fraiging
int nFraigingLimitStart; // starting backtrack(conflict) limit
float nFraigingLimitMulti; // multiplicative coefficient to increase the limit in each iteration
// last-gasp BDD construction
int nBddSizeLimit; // the number of BDD nodes when construction is aborted
int fBddReorder; // enables dynamic BDD variable reordering
// last-gasp mitering
int nMiteringLimitLast; // final mitering limit
};
////////////////////////////////////////////////////////////////////////
/// GLOBAL VARIABLES ///
////////////////////////////////////////////////////////////////////////
@ -155,6 +181,7 @@ extern Fraig_Node_t * Fraig_NodeMux( Fraig_Man_t * p, Fraig_Node_t * pNode,
extern void Fraig_NodeSetChoice( Fraig_Man_t * pMan, Fraig_Node_t * pNodeOld, Fraig_Node_t * pNodeNew );
/*=== fraigMan.c =============================================================*/
extern void Prove_ParamsSetDefault( Prove_Params_t * pParams );
extern void Fraig_ParamsSetDefault( Fraig_Params_t * pParams );
extern void Fraig_ParamsSetDefaultFull( Fraig_Params_t * pParams );
extern Fraig_Man_t * Fraig_ManCreate( Fraig_Params_t * pParams );

View File

@ -65,7 +65,7 @@ int Fraig_ManReadPatternNumDynamic( Fraig_Man_t * p ) {
// returns the number of dynamic patterns proved useful to distinquish some FRAIG nodes (this number is more than 0 after the first garbage collection of patterns)
int Fraig_ManReadPatternNumDynamicFiltered( Fraig_Man_t * p ) { return p->iPatsPerm; }
// returns the number of times FRAIG package timed out
int Fraig_ManReadSatFails( Fraig_Man_t * p ) { return p->nSatFails; }
int Fraig_ManReadSatFails( Fraig_Man_t * p ) { return p->nSatFailsReal; }
/**Function*************************************************************

View File

@ -189,7 +189,8 @@ struct Fraig_ManStruct_t_
int nSatCalls; // the number of times equivalence checking was called
int nSatProof; // the number of times a proof was found
int nSatCounter; // the number of times a counter example was found
int nSatFails; // the number of times the SAT solver failed to complete
int nSatFails; // the number of times the SAT solver failed to complete due to resource limit or prediction
int nSatFailsReal; // the number of times the SAT solver failed to complete due to resource limit
int nSatCallsImp; // the number of times equivalence checking was called
int nSatProofImp; // the number of times a proof was found
@ -243,8 +244,9 @@ struct Fraig_NodeStruct_t_
unsigned fMark3 : 1; // the mark used for traversals
unsigned fFeedUse : 1; // the presence of the variable in the feedback
unsigned fFeedVal : 1; // the value of the variable in the feedback
unsigned fFailTfo : 1; // the node is in the TFO of the failed SAT run
unsigned nFanouts : 2; // the indicator of fanouts (none, one, or many)
unsigned nOnes : 21; // the number of 1's in the random sim info
unsigned nOnes : 20; // the number of 1's in the random sim info
// the children of the node
Fraig_Node_t * p1; // the first child

View File

@ -29,6 +29,42 @@ int timeAssign;
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Sets the default parameters of the package.]
Description [This set of parameters is tuned for equivalence checking.]
SideEffects []
SeeAlso []
***********************************************************************/
void Prove_ParamsSetDefault( Prove_Params_t * pParams )
{
// general parameters
pParams->fUseFraiging = 1; // enables fraiging
pParams->fUseRewriting = 1; // enables rewriting
pParams->fUseBdds = 1; // enables BDD construction when other methods fail
pParams->fVerbose = 0; // prints verbose stats
// iterations
pParams->nItersMax = 6; // the number of iterations
// mitering
pParams->nMiteringLimitStart = 1000; // starting mitering limit
pParams->nMiteringLimitMulti = 2.0; // multiplicative coefficient to increase the limit in each iteration
// rewriting
pParams->nRewritingLimitStart = 3; // the number of rewriting iterations
pParams->nRewritingLimitMulti = 1.0; // multiplicative coefficient to increase the limit in each iteration
// fraiging
pParams->nFraigingLimitStart = 2; // starting backtrack(conflict) limit
pParams->nFraigingLimitMulti = 8.0; // multiplicative coefficient to increase the limit in each iteration
// last-gasp BDD construction
pParams->nBddSizeLimit = 1000000; // the number of BDD nodes when construction is aborted
pParams->fBddReorder = 1; // enables dynamic BDD variable reordering
// last-gasp mitering
pParams->nMiteringLimitLast = 1000000; // final mitering limit
}
/**Function*************************************************************
Synopsis [Sets the default parameters of the package.]
@ -271,8 +307,8 @@ void Fraig_ManPrintStats( Fraig_Man_t * p )
(sizeof(Fraig_Node_t) + sizeof(unsigned)*(p->nWordsRand + p->nWordsDyna) /*+ p->nSuppWords*sizeof(unsigned)*/))/(1<<20);
printf( "Words: Random = %d. Dynamic = %d. Used = %d. Memory = %0.2f Mb.\n",
p->nWordsRand, p->nWordsDyna, p->iWordPerm, nMemory );
printf( "Proof = %d. Counter-example = %d. Fail = %d. Zero = %d.\n",
p->nSatProof, p->nSatCounter, p->nSatFails, p->nSatZeros );
printf( "Proof = %d. Counter-example = %d. Fail = %d. FailReal = %d. Zero = %d.\n",
p->nSatProof, p->nSatCounter, p->nSatFails, p->nSatFailsReal, p->nSatZeros );
printf( "Nodes: Final = %d. Total = %d. Mux = %d. (Exor = %d.) ClaVars = %d.\n",
Fraig_CountNodes(p,0), p->vNodes->nSize, Fraig_ManCountMuxes(p), Fraig_ManCountExors(p), p->nVarsClauses );
if ( p->pSat ) Msat_SolverPrintStats( p->pSat );

View File

@ -176,6 +176,7 @@ Fraig_Node_t * Fraig_NodeCreate( Fraig_Man_t * p, Fraig_Node_t * p1, Fraig_Node_
// compute the level of this node
pNode->Level = 1 + FRAIG_MAX(Fraig_Regular(p1)->Level, Fraig_Regular(p2)->Level);
pNode->fInv = Fraig_NodeIsSimComplement(p1) & Fraig_NodeIsSimComplement(p2);
pNode->fFailTfo = Fraig_Regular(p1)->fFailTfo | Fraig_Regular(p2)->fFailTfo;
// derive the simulation info
clk = clock();

View File

@ -22,7 +22,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// The 1,000 smallest prime numbers used to compute the hash value
// The 1,024 smallest prime numbers used to compute the hash value
// http://www.math.utah.edu/~alfeld/math/primelist.html
int s_FraigPrimes[FRAIG_MAX_PRIMES] = { 2, 3, 5,
7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
@ -93,7 +93,9 @@ int s_FraigPrimes[FRAIG_MAX_PRIMES] = { 2, 3, 5,
7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603,
7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723,
7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873,
7877, 7879, 7883, 7901, 7907, 7919 };
7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009,
8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123,
8147, 8161 };
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///

View File

@ -17,6 +17,7 @@
***********************************************************************/
#include "fraigInt.h"
#include "math.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@ -304,6 +305,20 @@ int Fraig_NodeIsEquivalent( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t *
assert( !Fraig_IsComplement(pOld) );
assert( pNew != pOld );
// if at least one of the nodes is a failed node, perform adjustments:
// if the backtrack limit is small, simply skip this node
// if the backtrack limit is > 10, take the quare root of the limit
if ( nBTLimit > 0 && (pOld->fFailTfo || pNew->fFailTfo) )
{
p->nSatFails++;
// return 0;
// if ( nBTLimit > 10 )
// nBTLimit /= 10;
if ( nBTLimit <= 10 )
return 0;
nBTLimit = (int)sqrt(nBTLimit);
}
p->nSatCalls++;
// make sure the solver is allocated and has enough variables
@ -394,13 +409,27 @@ PRT( "time", clock() - clk );
// record the counter example
Fraig_FeedBack( p, Msat_SolverReadModelArray(p->pSat), p->vVarsInt, pOld, pNew );
// if ( pOld->fFailTfo || pNew->fFailTfo )
// printf( "*" );
// printf( "s(%d)", pNew->Level );
p->nSatCounter++;
return 0;
}
else // if ( RetValue1 == MSAT_UNKNOWN )
{
p->time3 += clock() - clk;
p->nSatFails++;
// if ( pOld->fFailTfo || pNew->fFailTfo )
// printf( "*" );
// printf( "T(%d)", pNew->Level );
// mark the node as the failed node
if ( pOld != p->pConst1 )
pOld->fFailTfo = 1;
pNew->fFailTfo = 1;
// p->nSatFails++;
p->nSatFailsReal++;
return 0;
}
@ -454,17 +483,34 @@ PRT( "time", clock() - clk );
// record the counter example
Fraig_FeedBack( p, Msat_SolverReadModelArray(p->pSat), p->vVarsInt, pOld, pNew );
p->nSatCounter++;
// if ( pOld->fFailTfo || pNew->fFailTfo )
// printf( "*" );
// printf( "s(%d)", pNew->Level );
return 0;
}
else // if ( RetValue1 == MSAT_UNKNOWN )
{
p->time3 += clock() - clk;
p->nSatFails++;
// if ( pOld->fFailTfo || pNew->fFailTfo )
// printf( "*" );
// printf( "T(%d)", pNew->Level );
// mark the node as the failed node
pOld->fFailTfo = 1;
pNew->fFailTfo = 1;
// p->nSatFails++;
p->nSatFailsReal++;
return 0;
}
// return SAT proof
p->nSatProof++;
// if ( pOld->fFailTfo || pNew->fFailTfo )
// printf( "*" );
// printf( "u(%d)", pNew->Level );
return 1;
}

View File

@ -38,7 +38,7 @@ struct Msat_OrderVar_t_
{
Msat_OrderVar_t * pNext;
Msat_OrderVar_t * pPrev;
int Num;
int Num;
};
// the ring of variables data structure (J-boundary)
@ -170,7 +170,8 @@ int Msat_OrderCheck( Msat_Order_t * p )
Msat_OrderVar_t * pVar, * pNext;
Msat_IntVec_t * vRound;
int * pRound, nRound;
int * pVars, nVars, i;
int * pVars, nVars, i, k;
int Counter = 0;
// go through all the variables in the boundary
Msat_OrderRingForEachEntry( p->rVars.pRoot, pVar, pNext )
@ -188,10 +189,14 @@ int Msat_OrderCheck( Msat_Order_t * p )
if ( Msat_OrderVarIsAssigned(p, pRound[i]) )
break;
}
assert( i != nRound );
if ( i != nRound )
return 0;
// assert( i != nRound );
// if ( i == nRound )
// return 0;
if ( i == nRound )
Counter++;
}
if ( Counter > 0 )
printf( "%d(%d) ", Counter, p->rVars.nItems );
// we may also check other unassigned variables in the cone
// to make sure that if they are not in J-boundary,
@ -209,16 +214,16 @@ int Msat_OrderCheck( Msat_Order_t * p )
vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVars[i] );
nRound = Msat_IntVecReadSize( vRound );
pRound = Msat_IntVecReadArray( vRound );
for ( i = 0; i < nRound; i++ )
for ( k = 0; k < nRound; k++ )
{
if ( !Msat_OrderVarIsUsedInCone(p, pRound[i]) )
if ( !Msat_OrderVarIsUsedInCone(p, pRound[k]) )
continue;
if ( Msat_OrderVarIsAssigned(p, pRound[i]) )
if ( Msat_OrderVarIsAssigned(p, pRound[k]) )
break;
}
assert( i == nRound );
if ( i == nRound )
return 0;
// assert( k == nRound );
// if ( k != nRound )
// return 0;
}
return 1;
}
@ -256,7 +261,7 @@ int Msat_OrderVarSelect( Msat_Order_t * p )
Msat_OrderVar_t * pVar, * pNext, * pVarBest;
double * pdActs = p->pSat->pdActivity;
double dfActBest;
int clk = clock();
// int clk = clock();
pVarBest = NULL;
dfActBest = -1.0;
@ -268,12 +273,13 @@ int Msat_OrderVarSelect( Msat_Order_t * p )
pVarBest = pVar;
}
}
timeSelect += clock() - clk;
timeAssign += clock() - clk;
//timeSelect += clock() - clk;
//timeAssign += clock() - clk;
//if ( pVarBest && pVarBest->Num % 1000 == 0 )
//printf( "%d ", p->rVars.nItems );
// Msat_OrderCheck( p );
if ( pVarBest )
{
assert( Msat_OrderVarIsUsedInCone(p, pVarBest->Num) );
@ -296,7 +302,7 @@ timeAssign += clock() - clk;
void Msat_OrderVarAssigned( Msat_Order_t * p, int Var )
{
Msat_IntVec_t * vRound;
int i, clk = clock();
int i;//, clk = clock();
// make sure the variable is in the boundary
assert( Var < p->nVarsAlloc );
@ -316,7 +322,7 @@ void Msat_OrderVarAssigned( Msat_Order_t * p, int Var )
continue;
Msat_OrderRingAddLast( &p->rVars, &p->pVars[vRound->pArray[i]] );
}
timeSelect += clock() - clk;
//timeSelect += clock() - clk;
// Msat_OrderCheck( p );
}
@ -334,7 +340,7 @@ timeSelect += clock() - clk;
void Msat_OrderVarUnassigned( Msat_Order_t * p, int Var )
{
Msat_IntVec_t * vRound, * vRound2;
int i, k, clk = clock();
int i, k;//, clk = clock();
// make sure the variable is not in the boundary
assert( Var < p->nVarsAlloc );
@ -363,7 +369,7 @@ void Msat_OrderVarUnassigned( Msat_Order_t * p, int Var )
if ( k == vRound2->nSize ) // there is no assigned vars, delete this one
Msat_OrderRingRemove( &p->rVars, &p->pVars[vRound->pArray[i]] );
}
timeSelect += clock() - clk;
//timeSelect += clock() - clk;
// Msat_OrderCheck( p );
}
@ -450,7 +456,7 @@ void Msat_OrderRingRemove( Msat_OrderRing_t * pRing, Msat_OrderVar_t * pVar )
pRing->pRoot = pVar->pNext;
// move the root to the next entry after pVar
// this way all the additions to the list will be traversed first
// pRing->pRoot = pVar->pNext;
// pRing->pRoot = pVar->pPrev;
// delete the node
pVar->pPrev->pNext = pVar->pNext;
pVar->pNext->pPrev = pVar->pPrev;

View File

@ -1,28 +1,18 @@
Minor things:
- add required time support
- clean end-of-line markers (CR is more preferable than CR-LF)
- mysterious Mac problem (fixed?)
- mysterious Solaris problem (fixed)
- QR's compilation problems
- mysterious Mac problem
- prevent node name clash between PO and internal names (i.e. [484])
- add the output of ABC version/platform in the output files
- fix gcc compiler warnings
- update CVS regularly
- add the output of ABC version/platform in the output files
- fix gcc compiler warnings
Major things:
- substantially improving performance of FRAIGing
(used in equivalence checking and lossless synthesis)
- developing a new (much more efficient and faster) AIG rewriting package
- developing a new (more efficient and faster) AIG rewriting package
- implementing additional rewriting options for delay optimization
@ -31,7 +21,7 @@ on-demand cut computation currenlty available as a stand-alone command "cut"
- experimenting with yield-aware standard-cell mapping
- developing a hybrid mapper for arbitrary programmable macrocell
- developing a mapper for arbitrary programmable macrocell
architecture specified using a configuration file (this mapper should work
for both cell-evalution and mainstream FPGA mapping)