summaryrefslogtreecommitdiffstats
path: root/src/base/abci
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/abci')
-rw-r--r--src/base/abci/abc.c4058
-rw-r--r--src/base/abci/abcAttach.c405
-rw-r--r--src/base/abci/abcBalance.c239
-rw-r--r--src/base/abci/abcCollapse.c147
-rw-r--r--src/base/abci/abcCut.c190
-rw-r--r--src/base/abci/abcDsd.c539
-rw-r--r--src/base/abci/abcFpga.c267
-rw-r--r--src/base/abci/abcFraig.c586
-rw-r--r--src/base/abci/abcFxu.c259
-rw-r--r--src/base/abci/abcMap.c689
-rw-r--r--src/base/abci/abcMiter.c600
-rw-r--r--src/base/abci/abcNtbdd.c402
-rw-r--r--src/base/abci/abcPrint.c505
-rw-r--r--src/base/abci/abcReconv.c742
-rw-r--r--src/base/abci/abcRefactor.c354
-rw-r--r--src/base/abci/abcRenode.c609
-rw-r--r--src/base/abci/abcRewrite.c184
-rw-r--r--src/base/abci/abcSat.c252
-rw-r--r--src/base/abci/abcStrash.c287
-rw-r--r--src/base/abci/abcSweep.c607
-rw-r--r--src/base/abci/abcSymm.c221
-rw-r--r--src/base/abci/abcTiming.c755
-rw-r--r--src/base/abci/abcUnreach.c336
-rw-r--r--src/base/abci/abcVerify.c311
-rw-r--r--src/base/abci/abc_.c47
-rw-r--r--src/base/abci/module.make24
26 files changed, 13615 insertions, 0 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
new file mode 100644
index 00000000..30047d23
--- /dev/null
+++ b/src/base/abci/abc.c
@@ -0,0 +1,4058 @@
+/**CFile****************************************************************
+
+ FileName [abc.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Command file.]
+
+ 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"
+#include "mainInt.h"
+#include "fraig.h"
+#include "fxu.h"
+#include "cut.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static int Abc_CommandPrintStats ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrintIo ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrintLatch ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrintFanio ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrintLevel ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrintSupport ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandPrintSymms ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandShowBdd ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandShowCut ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandShowAig ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandCollapse ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandStrash ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandBalance ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRenode ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandCleanup ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSweep ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandFastExtract ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandDisjoint ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+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_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandFrames ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSop ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandBdd ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandMuxes ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSat ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandExtSeqDcs ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandOneOutput ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandOneNode ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandShortNames ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandCut ( 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 );
+static int Abc_CommandFraigTrust ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandFraigStore ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandFraigRestore ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandFraigClean ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandFraigSweep ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandUnmap ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAttach ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSuperChoice ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandFpga ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandSeq ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRetime ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandCec ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_Init( Abc_Frame_t * pAbc )
+{
+ Cmd_CommandAdd( pAbc, "Printing", "print_stats", Abc_CommandPrintStats, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_io", Abc_CommandPrintIo, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_latch", Abc_CommandPrintLatch, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_fanio", Abc_CommandPrintFanio, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_factor", Abc_CommandPrintFactor, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_level", Abc_CommandPrintLevel, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_supp", Abc_CommandPrintSupport, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "print_symm", Abc_CommandPrintSymms, 0 );
+
+ Cmd_CommandAdd( pAbc, "Printing", "show_bdd", Abc_CommandShowBdd, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "show_cut", Abc_CommandShowCut, 0 );
+ Cmd_CommandAdd( pAbc, "Printing", "show_aig", Abc_CommandShowAig, 0 );
+
+ Cmd_CommandAdd( pAbc, "Synthesis", "collapse", Abc_CommandCollapse, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "strash", Abc_CommandStrash, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "balance", Abc_CommandBalance, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "renode", Abc_CommandRenode, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "cleanup", Abc_CommandCleanup, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "sweep", Abc_CommandSweep, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "fx", Abc_CommandFastExtract, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "dsd", Abc_CommandDisjoint, 1 );
+
+ Cmd_CommandAdd( pAbc, "Synthesis", "rewrite", Abc_CommandRewrite, 1 );
+ Cmd_CommandAdd( pAbc, "Synthesis", "refactor", Abc_CommandRefactor, 1 );
+
+ Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "miter", Abc_CommandMiter, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "frames", Abc_CommandFrames, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "sop", Abc_CommandSop, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "bdd", Abc_CommandBdd, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "muxes", Abc_CommandMuxes, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "sat", Abc_CommandSat, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "ext_seq_dcs", Abc_CommandExtSeqDcs, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "one_output", Abc_CommandOneOutput, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "one_node", Abc_CommandOneNode, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "short_names", Abc_CommandShortNames, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "cut", Abc_CommandCut, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "test", Abc_CommandTest, 0 );
+
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig", Abc_CommandFraig, 1 );
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig_trust", Abc_CommandFraigTrust, 1 );
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig_store", Abc_CommandFraigStore, 0 );
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig_restore", Abc_CommandFraigRestore, 1 );
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig_clean", Abc_CommandFraigClean, 0 );
+ Cmd_CommandAdd( pAbc, "Fraiging", "fraig_sweep", Abc_CommandFraigSweep, 1 );
+
+ Cmd_CommandAdd( pAbc, "SC mapping", "map", Abc_CommandMap, 1 );
+ Cmd_CommandAdd( pAbc, "SC mapping", "unmap", Abc_CommandUnmap, 1 );
+ Cmd_CommandAdd( pAbc, "SC mapping", "attach", Abc_CommandAttach, 1 );
+ Cmd_CommandAdd( pAbc, "SC mapping", "sc", Abc_CommandSuperChoice, 1 );
+
+ Cmd_CommandAdd( pAbc, "FPGA mapping", "fpga", Abc_CommandFpga, 1 );
+
+ Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 );
+ Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 );
+
+ Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 );
+ Cmd_CommandAdd( pAbc, "Verification", "sec", Abc_CommandSec, 0 );
+
+// Rwt_Man4ExploreStart();
+// Map_Var3Print();
+// Map_Var4Test();
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_End()
+{
+ Abc_NtkFraigStoreClean();
+// Rwt_Man4ExplorePrint();
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandPrintStats( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ bool fShort;
+ int c;
+ int fFactor;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set the defaults
+ fShort = 1;
+ fFactor = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "sfh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 's':
+ fShort ^= 1;
+ break;
+ case 'f':
+ fFactor ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( Abc_FrameReadErr(pAbc), "Empty network\n" );
+ return 1;
+ }
+ Abc_NtkPrintStats( pOut, pNtk, fFactor );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_stats [-fh]\n" );
+ fprintf( pErr, "\t prints the network statistics and\n" );
+ fprintf( pErr, "\t-f : toggles printing the literal count in the factored forms [default = %s]\n", fFactor? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandPrintIo( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pNode;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( argc > util_optind + 1 )
+ {
+ fprintf( pErr, "Wrong number of auguments.\n" );
+ goto usage;
+ }
+
+ if ( argc == util_optind + 1 )
+ {
+ pNode = Abc_NtkFindNode( pNtk, argv[util_optind] );
+ if ( pNode == NULL )
+ {
+ fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] );
+ return 1;
+ }
+ Abc_NodePrintFanio( pOut, pNode );
+ return 0;
+ }
+ // print the nodes
+ Abc_NtkPrintIo( pOut, pNtk );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_io [-h] <node>\n" );
+ fprintf( pErr, "\t prints the PIs/POs or fanins/fanouts of a node\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\tnode : the node to print fanins/fanouts\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandPrintLatch( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ // print the nodes
+ Abc_NtkPrintLatch( pOut, pNtk );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_latch [-h]\n" );
+ fprintf( pErr, "\t prints information about latches\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandPrintFanio( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // print the nodes
+ Abc_NtkPrintFanio( pOut, pNtk );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_fanio [-h]\n" );
+ fprintf( pErr, "\t prints the statistics about fanins/fanouts of all nodes\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandPrintFactor( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pNode;
+ int c;
+ int fUseRealNames;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fUseRealNames = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "nh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'n':
+ fUseRealNames ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsSopLogic(pNtk) )
+ {
+ fprintf( pErr, "Printing factored forms can be done for SOP networks.\n" );
+ return 1;
+ }
+
+ if ( argc > util_optind + 1 )
+ {
+ fprintf( pErr, "Wrong number of auguments.\n" );
+ goto usage;
+ }
+
+ if ( argc == util_optind + 1 )
+ {
+ pNode = Abc_NtkFindNode( pNtk, argv[util_optind] );
+ if ( pNode == NULL )
+ {
+ fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] );
+ return 1;
+ }
+ Abc_NodePrintFactor( pOut, pNode, fUseRealNames );
+ return 0;
+ }
+ // print the nodes
+ Abc_NtkPrintFactor( pOut, pNtk, fUseRealNames );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_factor [-nh] <node>\n" );
+ fprintf( pErr, "\t prints the factored forms of nodes\n" );
+ fprintf( pErr, "\t-n : toggles real/dummy fanin names [default = %s]\n", fUseRealNames? "real": "dummy" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\tnode : (optional) one node to consider\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandPrintLevel( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pNode;
+ int c;
+ int fProfile;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fProfile = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ph" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'p':
+ fProfile ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !fProfile && !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "This command works only for AIGs.\n" );
+ return 1;
+ }
+
+ if ( argc > util_optind + 1 )
+ {
+ fprintf( pErr, "Wrong number of auguments.\n" );
+ goto usage;
+ }
+
+ if ( argc == util_optind + 1 )
+ {
+ pNode = Abc_NtkFindNode( pNtk, argv[util_optind] );
+ if ( pNode == NULL )
+ {
+ fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] );
+ return 1;
+ }
+ Abc_NodePrintLevel( pOut, pNode );
+ return 0;
+ }
+ // process all COs
+ Abc_NtkPrintLevel( pOut, pNtk, fProfile );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_level [-ph] <node>\n" );
+ fprintf( pErr, "\t prints information about node level and cone size\n" );
+ fprintf( pErr, "\t-p : toggles printing level profile [default = %s]\n", fProfile? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\tnode : (optional) one node to consider\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandPrintSupport( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Vec_Ptr_t * vSuppFun;
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ extern Vec_Ptr_t * Sim_ComputeFunSupp( Abc_Ntk_t * pNtk );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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_NtkIsComb(pNtk) )
+ {
+ fprintf( pErr, "This command works only for combinational networks.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "This command works only for AIGs.\n" );
+ return 1;
+ }
+ vSuppFun = Sim_ComputeFunSupp( pNtk );
+ free( vSuppFun->pArray[0] );
+ Vec_PtrFree( vSuppFun );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_supp [-h]\n" );
+ fprintf( pErr, "\t prints the supports of the CO nodes\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fUseBdds;
+ int fNaive;
+ int fVerbose;
+ extern void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fUseBdds = 0;
+ fNaive = 0;
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "bnvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'b':
+ fUseBdds ^= 1;
+ break;
+ case 'n':
+ fNaive ^= 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_NtkIsComb(pNtk) )
+ {
+ fprintf( pErr, "This command works only for combinational networks.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "This command works only for AIGs.\n" );
+ return 1;
+ }
+ Abc_NtkSymmetries( pNtk, fUseBdds, fNaive, fVerbose );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: print_symm [-nbvh]\n" );
+ fprintf( pErr, "\t computes symmetries of the PO functions\n" );
+ fprintf( pErr, "\t-b : enable efficient BDD-based computation [default = %s].\n", fUseBdds? "yes": "no" );
+ fprintf( pErr, "\t-n : enable naive BDD-based computation [default = %s].\n", fNaive? "yes": "no" );
+ fprintf( pErr, "\t-v : enable verbose output [default = %s].\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pNode;
+ int c;
+ extern void Abc_NodeShowBdd( Abc_Obj_t * pNode );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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_NtkIsBddLogic(pNtk) )
+ {
+ fprintf( pErr, "Visualizing BDDs can only be done for logic BDD networks.\n" );
+ return 1;
+ }
+
+ if ( argc != util_optind + 1 )
+ {
+ fprintf( pErr, "Wrong number of auguments.\n" );
+ goto usage;
+ }
+
+ pNode = Abc_NtkFindNode( pNtk, argv[util_optind] );
+ if ( pNode == NULL )
+ {
+ fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] );
+ return 1;
+ }
+ Abc_NodeShowBdd( pNode );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: show_bdd [-h] <node>\n" );
+ fprintf( pErr, " visualizes the BDD of a node using DOT and GSVIEW\n" );
+#ifdef WIN32
+ fprintf( pErr, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" );
+ fprintf( pErr, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" );
+#endif
+ fprintf( pErr, "\tnode : the node to consider\n");
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandShowCut( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ Abc_Obj_t * pNode;
+ int c;
+ int nNodeSizeMax;
+ int nConeSizeMax;
+ extern void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nNodeSizeMax = 10;
+ nConeSizeMax = ABC_INFINITY;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "NCh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'N':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nNodeSizeMax = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nNodeSizeMax < 0 )
+ goto usage;
+ break;
+ case 'C':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nConeSizeMax = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nConeSizeMax < 0 )
+ goto usage;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "Visualizing cuts only works for AIGs.\n" );
+ return 1;
+ }
+ if ( argc != util_optind + 1 )
+ {
+ fprintf( pErr, "Wrong number of auguments.\n" );
+ goto usage;
+ }
+
+ pNode = Abc_NtkFindNode( pNtk, argv[util_optind] );
+ if ( pNode == NULL )
+ {
+ fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] );
+ return 1;
+ }
+ Abc_NodeShowCut( pNode, nNodeSizeMax, nConeSizeMax );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: show_cut [-N num] [-C num] [-h] <node>\n" );
+ fprintf( pErr, " visualizes the cut of a node using DOT and GSVIEW\n" );
+#ifdef WIN32
+ fprintf( pErr, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" );
+ fprintf( pErr, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" );
+#endif
+ fprintf( pErr, "\t-N num : the max size of the cut to be computed [default = %d]\n", nNodeSizeMax );
+ fprintf( pErr, "\t-C num : the max support of the containing cone [default = %d]\n", nConeSizeMax );
+ fprintf( pErr, "\tnode : the node to consider\n");
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ extern void Abc_NtkShowAig( Abc_Ntk_t * pNtk );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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, "Visualizing AIG can only be done for AIGs.\n" );
+ return 1;
+ }
+ Abc_NtkShowAig( pNtk );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: show_aig [-h]\n" );
+ fprintf( pErr, " visualizes the AIG with choices using DOT and GSVIEW\n" );
+#ifdef WIN32
+ fprintf( pErr, " \"dot.exe\" and \"gsview32.exe\" should be set in the paths\n" );
+ fprintf( pErr, " (\"gsview32.exe\" may be in \"C:\\Program Files\\Ghostgum\\gsview\\\")\n" );
+#endif
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "Can only collapse a logic network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( Abc_NtkIsStrash(pNtk) )
+ pNtkRes = Abc_NtkCollapse( pNtk, 1 );
+ else
+ {
+ pNtk = Abc_NtkStrash( pNtk, 0, 0 );
+ pNtkRes = Abc_NtkCollapse( pNtk, 1 );
+ Abc_NtkDelete( pNtk );
+ }
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Collapsing has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: collapse [-h]\n" );
+ fprintf( pErr, "\t collapses the network by constructing global BDDs\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandStrash( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int fAllNodes;
+ int fCleanup;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fAllNodes = 0;
+ fCleanup = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ach" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'a':
+ fAllNodes ^= 1;
+ break;
+ case 'c':
+ fCleanup ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkStrash( pNtk, fAllNodes, fCleanup );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Strashing has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: strash [-ach]\n" );
+ fprintf( pErr, "\t transforms combinational logic into an AIG\n" );
+ fprintf( pErr, "\t-a : toggles between using all nodes and DFS nodes [default = %s]\n", fAllNodes? "all": "DFS" );
+ fprintf( pErr, "\t-c : toggles cleanup to remove the dagling AIG nodes [default = %s]\n", fCleanup? "all": "DFS" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes, * pNtkTemp;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( Abc_NtkIsStrash(pNtk) )
+ {
+ pNtkRes = Abc_NtkBalance( pNtk, fDuplicate );
+ }
+ else
+ {
+ pNtkTemp = Abc_NtkStrash( pNtk, 0, 0 );
+ if ( pNtkTemp == NULL )
+ {
+ fprintf( pErr, "Strashing before balancing has failed.\n" );
+ return 1;
+ }
+ pNtkRes = Abc_NtkBalance( pNtkTemp, fDuplicate );
+ Abc_NtkDelete( pNtkTemp );
+ }
+
+ // check if balancing worked
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Balancing has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: balance [-dh]\n" );
+ fprintf( pErr, "\t transforms the current network into a well-balanced AIG\n" );
+ fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int nThresh, nFaninMax, c;
+ int fCnf;
+ int fMulti;
+ int fSimple;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nThresh = 1;
+ nFaninMax = 20;
+ fCnf = 0;
+ fMulti = 0;
+ fSimple = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "TFmcsh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'T':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nThresh = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nThresh < 0 )
+ goto usage;
+ break;
+ case 'F':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nFaninMax = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nFaninMax < 0 )
+ goto usage;
+ break;
+ case 'c':
+ fCnf ^= 1;
+ break;
+ case 'm':
+ fMulti ^= 1;
+ break;
+ case 's':
+ fSimple ^= 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, "Cannot renode a network that is not an AIG.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkRenode( pNtk, nThresh, nFaninMax, fCnf, fMulti, fSimple );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Renoding has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: renode [-T num] [-F num] [-cmsh]\n" );
+ fprintf( pErr, "\t transforms an AIG into a logic network by creating larger nodes\n" );
+ fprintf( pErr, "\t-F num : the maximum fanin size after renoding [default = %d]\n", nFaninMax );
+ fprintf( pErr, "\t-T num : the threshold for AIG node duplication [default = %d]\n", nThresh );
+ fprintf( pErr, "\t (an AIG node is the root of a new node after renoding\n" );
+ fprintf( pErr, "\t if doing so prevents duplication of more than %d AIG nodes,\n", nThresh );
+ fprintf( pErr, "\t that is, if [(numFanouts(Node)-1) * size(MFFC(Node))] > %d)\n", nThresh );
+ fprintf( pErr, "\t-m : creates multi-input AND graph [default = %s]\n", fMulti? "yes": "no" );
+ fprintf( pErr, "\t-s : creates a simple AIG (no renoding) [default = %s]\n", fSimple? "yes": "no" );
+ fprintf( pErr, "\t-c : performs renoding to derive the CNF [default = %s]\n", fCnf? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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, "Cleanup cannot be performed on the AIG.\n" );
+ return 1;
+ }
+ // modify the current network
+ Abc_NtkCleanup( pNtk, 0 );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: cleanup [-h]\n" );
+ fprintf( pErr, "\t removes dangling nodes\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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_NtkIsSopLogic(pNtk) && !Abc_NtkIsBddLogic(pNtk) )
+ {
+ fprintf( pErr, "Sweep cannot be performed on an AIG or a mapped network (unmap it first).\n" );
+ return 1;
+ }
+ // modify the current network
+ Abc_NtkSweep( pNtk, 0 );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: sweep [-h]\n" );
+ fprintf( pErr, "\t removes dangling nodes; propagates constant, buffers, inverters\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Abc_Ntk_t * pNtk;
+ FILE * pOut, * pErr;
+ Fxu_Data_t * p = NULL;
+ int c;
+ extern bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p );
+ extern void Abc_NtkFxuFreeInfo( Fxu_Data_t * p );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // allocate the structure
+ p = ALLOC( Fxu_Data_t, 1 );
+ memset( p, 0, sizeof(Fxu_Data_t) );
+ // set the defaults
+ p->nPairsMax = 30000;
+ p->nNodesExt = 10000;
+ p->fOnlyS = 0;
+ p->fOnlyD = 0;
+ p->fUse0 = 0;
+ p->fUseCompl = 1;
+ p->fVerbose = 0;
+ util_getopt_reset();
+ while ( (c = util_getopt(argc, argv, "LNsdzcvh")) != EOF )
+ {
+ switch (c)
+ {
+ case 'L':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ p->nPairsMax = atoi(argv[util_optind]);
+ util_optind++;
+ if ( p->nPairsMax < 0 )
+ goto usage;
+ break;
+ case 'N':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ p->nNodesExt = atoi(argv[util_optind]);
+ util_optind++;
+ if ( p->nNodesExt < 0 )
+ goto usage;
+ break;
+ case 's':
+ p->fOnlyS ^= 1;
+ break;
+ case 'd':
+ p->fOnlyD ^= 1;
+ break;
+ case 'z':
+ p->fUse0 ^= 1;
+ break;
+ case 'c':
+ p->fUseCompl ^= 1;
+ break;
+ case 'v':
+ p->fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ Abc_NtkFxuFreeInfo( p );
+ return 1;
+ }
+
+ if ( Abc_NtkNodeNum(pNtk) == 0 )
+ {
+ fprintf( pErr, "The network does not have internal nodes.\n" );
+ Abc_NtkFxuFreeInfo( p );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsLogic(pNtk) )
+ {
+ fprintf( pErr, "Fast extract can only be applied to a logic network.\n" );
+ Abc_NtkFxuFreeInfo( p );
+ return 1;
+ }
+
+
+ // the nodes to be merged are linked into the special linked list
+ Abc_NtkFastExtract( pNtk, p );
+ Abc_NtkFxuFreeInfo( p );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fx [-N num] [-L num] [-sdzcvh]\n");
+ fprintf( pErr, "\t performs unate fast extract on the current network\n");
+ fprintf( pErr, "\t-N num : the maximum number of divisors to extract [default = %d]\n", p->nNodesExt );
+ fprintf( pErr, "\t-L num : the maximum number of cube pairs to consider [default = %d]\n", p->nPairsMax );
+ fprintf( pErr, "\t-s : use only single-cube divisors [default = %s]\n", p->fOnlyS? "yes": "no" );
+ fprintf( pErr, "\t-d : use only double-cube divisors [default = %s]\n", p->fOnlyD? "yes": "no" );
+ fprintf( pErr, "\t-z : use zero-weight divisors [default = %s]\n", p->fUse0? "yes": "no" );
+ fprintf( pErr, "\t-c : use complement in the binary case [default = %s]\n", p->fUseCompl? "yes": "no" );
+ fprintf( pErr, "\t-v : print verbose information [default = %s]\n", p->fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ Abc_NtkFxuFreeInfo( p );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandDisjoint( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes, * pNtkNew;
+ int fGlobal, fRecursive, fVerbose, fPrint, fShort, c;
+
+ extern Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort );
+ extern int Abc_NtkDsdLocal( Abc_Ntk_t * pNtk, bool fVerbose, bool fRecursive );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fGlobal = 1;
+ fRecursive = 0;
+ fVerbose = 0;
+ fPrint = 0;
+ fShort = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "grvpsh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'g':
+ fGlobal ^= 1;
+ break;
+ case 'r':
+ fRecursive ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'p':
+ fPrint ^= 1;
+ break;
+ case 's':
+ fShort ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( fGlobal )
+ {
+// fprintf( stdout, "Performing DSD of global functions of the network.\n" );
+ // get the new network
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ pNtkNew = Abc_NtkStrash( pNtk, 0, 0 );
+ pNtkRes = Abc_NtkDsdGlobal( pNtkNew, fVerbose, fPrint, fShort );
+ Abc_NtkDelete( pNtkNew );
+ }
+ else
+ {
+ pNtkRes = Abc_NtkDsdGlobal( pNtk, fVerbose, fPrint, fShort );
+ }
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Global DSD has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ }
+ else if ( fRecursive )
+ {
+ if ( !Abc_NtkIsBddLogic( pNtk ) )
+ {
+ fprintf( pErr, "This command is only applicable to logic BDD networks.\n" );
+ return 1;
+ }
+ fprintf( stdout, "Performing recursive DSD and MUX decomposition of local functions.\n" );
+ if ( !Abc_NtkDsdLocal( pNtk, fVerbose, fRecursive ) )
+ fprintf( pErr, "Recursive DSD has failed.\n" );
+ }
+ else
+ {
+ if ( !Abc_NtkIsBddLogic( pNtk ) )
+ {
+ fprintf( pErr, "This command is only applicable to logic BDD networks.\n" );
+ return 1;
+ }
+ fprintf( stdout, "Performing simple non-recursive DSD of local functions.\n" );
+ if ( !Abc_NtkDsdLocal( pNtk, fVerbose, fRecursive ) )
+ fprintf( pErr, "Simple DSD of local functions has failed.\n" );
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: dsd [-grvpsh]\n" );
+ fprintf( pErr, "\t decomposes the network using disjoint-support decomposition\n" );
+ fprintf( pErr, "\t-g : toggle DSD of global and local functions [default = %s]\n", fGlobal? "global": "local" );
+ fprintf( pErr, "\t-r : toggle recursive DSD/MUX and simple DSD [default = %s]\n", fRecursive? "recursive DSD/MUX": "simple DSD" );
+ fprintf( pErr, "\t-v : prints DSD statistics and runtime [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-p : prints DSD structure to the standard output [default = %s]\n", fPrint? "yes": "no" );
+ fprintf( pErr, "\t-s : use short PI names when printing DSD structure [default = %s]\n", fShort? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ bool fPrecompute;
+ bool fUseZeros;
+ bool fVerbose;
+ // external functions
+ extern void Rwr_Precompute();
+ extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUseZeros, int fVerbose );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fPrecompute = 0;
+ fUseZeros = 0;
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "xzvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'x':
+ fPrecompute ^= 1;
+ break;
+ case 'z':
+ fUseZeros ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( fPrecompute )
+ {
+ Rwr_Precompute();
+ return 0;
+ }
+
+ 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.\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_NtkRewrite( pNtk, fUseZeros, fVerbose ) )
+ {
+ fprintf( pErr, "Rewriting has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: rewrite [-zvh]\n" );
+ fprintf( pErr, "\t performs technology-independent rewriting of the AIG\n" );
+ fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "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*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int nNodeSizeMax;
+ int nConeSizeMax;
+ bool fUseZeros;
+ bool fUseDcs;
+ bool fVerbose;
+ extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUseZeros, bool fUseDcs, bool fVerbose );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nNodeSizeMax = 10;
+ nConeSizeMax = 16;
+ fUseZeros = 0;
+ fUseDcs = 0;
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "NCzdvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'N':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nNodeSizeMax = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nNodeSizeMax < 0 )
+ goto usage;
+ break;
+ case 'C':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nConeSizeMax = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nConeSizeMax < 0 )
+ goto usage;
+ break;
+ case 'z':
+ fUseZeros ^= 1;
+ break;
+ case 'd':
+ fUseDcs ^= 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.\n" );
+ return 1;
+ }
+ if ( Abc_NtkGetChoiceNum(pNtk) )
+ {
+ fprintf( pErr, "AIG resynthesis cannot be applied to AIGs with choice nodes.\n" );
+ return 1;
+ }
+
+ if ( fUseDcs && nNodeSizeMax >= nConeSizeMax )
+ {
+ fprintf( pErr, "For don't-care to work, containing cone should be larger than collapsed node.\n" );
+ return 1;
+ }
+
+ // modify the current network
+ if ( !Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUseZeros, fUseDcs, fVerbose ) )
+ {
+ fprintf( pErr, "Refactoring has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: refactor [-N num] [-C num] [-zdvh]\n" );
+ fprintf( pErr, "\t performs technology-independent refactoring of the AIG\n" );
+ fprintf( pErr, "\t-N num : the max support of the collapsed node [default = %d]\n", nNodeSizeMax );
+ fprintf( pErr, "\t-C num : the max support of the containing cone [default = %d]\n", nConeSizeMax );
+ fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "yes": "no" );
+ fprintf( pErr, "\t-d : toggle using don't-cares [default = %s]\n", fUseDcs? "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*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandLogic( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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_NtkIsNetlist( pNtk ) )
+ {
+ fprintf( pErr, "This command is only applicable to netlists.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkNetlistToLogic( pNtk );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Converting to a logic network has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: logic [-h]\n" );
+ fprintf( pErr, "\t transforms a netlist into a logic network\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtk1, * pNtk2, * pNtkRes;
+ int fDelete1, fDelete2;
+ char ** pArgvNew;
+ int nArgcNew;
+ int c;
+ int fCheck;
+ int fComb;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fComb = 1;
+ fCheck = 1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'c':
+ fComb ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ pArgvNew = argv + util_optind;
+ nArgcNew = argc - util_optind;
+ if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
+ return 1;
+
+ // compute the miter
+ pNtkRes = Abc_NtkMiter( pNtk1, pNtk2, fComb );
+ if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
+ if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
+
+ // get the new network
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Miter computation has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: miter [-ch] <file1> <file2>\n" );
+ fprintf( pErr, "\t computes the miter of the two circuits\n" );
+ fprintf( pErr, "\t-c : computes combinational miter (latches as POs) [default = %s]\n", fComb? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
+ fprintf( pErr, "\tfile2 : (optional) the file with the second network\n");
+ fprintf( pErr, "\t if no files are given, uses the current network and its spec\n");
+ fprintf( pErr, "\t if one file is given, uses the current network and the file\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandFrames( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkTemp, * pNtkRes;
+ int fInitial;
+ int nFrames;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fInitial = 0;
+ nFrames = 5;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "Fih" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'F':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nFrames = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nFrames < 0 )
+ goto usage;
+ break;
+ case 'i':
+ fInitial ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ pNtkTemp = Abc_NtkStrash( pNtk, 0, 0 );
+ pNtkRes = Abc_NtkFrames( pNtkTemp, nFrames, fInitial );
+ Abc_NtkDelete( pNtkTemp );
+ }
+ else
+ pNtkRes = Abc_NtkFrames( pNtk, nFrames, fInitial );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Unrolling the network has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: frames [-F num] [-ih]\n" );
+ fprintf( pErr, "\t unrolls the network for a number of time frames\n" );
+ fprintf( pErr, "\t-F num : the number of frames to unroll [default = %d]\n", nFrames );
+ fprintf( pErr, "\t-i : toggles initializing the first frame [default = %s]\n", fInitial? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( !Abc_NtkIsBddLogic(pNtk) )
+ {
+ fprintf( pErr, "Converting to SOP is possible when node functions are BDDs.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkBddToSop( pNtk ) )
+ {
+ fprintf( pErr, "Converting to SOP has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: sop [-h]\n" );
+ fprintf( pErr, "\t converts node functions from BDD to SOP\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandBdd( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( !Abc_NtkIsSopLogic(pNtk) )
+ {
+ fprintf( pErr, "Converting to BDD is possible when node functions are SOPs.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkSopToBdd( pNtk ) )
+ {
+ fprintf( pErr, "Converting to BDD has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: bdd [-h]\n" );
+ fprintf( pErr, "\t converts node functions from SOP to BDD\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandMuxes( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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_NtkIsBddLogic(pNtk) )
+ {
+ fprintf( pErr, "Only a BDD logic network can be converted to MUXes.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkBddToMuxes( pNtk );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Converting to MUXes has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: muxes [-h]\n" );
+ fprintf( pErr, "\t converts the current network by a network derived by\n" );
+ fprintf( pErr, "\t replacing all nodes by DAGs isomorphic to the local BDDs\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fVerbose;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( Abc_NtkLatchNum(pNtk) > 0 )
+ {
+ fprintf( stdout, "Currently can only solve the miter for combinational circuits.\n" );
+ return 0;
+ }
+ if ( !Abc_NtkIsLogic(pNtk) )
+ {
+ fprintf( stdout, "This command can only be applied to logic network.\n" );
+ return 0;
+ }
+ if ( Abc_NtkIsMappedLogic(pNtk) )
+ Abc_NtkUnmap(pNtk);
+ if ( Abc_NtkIsSopLogic(pNtk) )
+ Abc_NtkSopToBdd(pNtk);
+
+ if ( Abc_NtkMiterSat( pNtk, fVerbose ) )
+ printf( "The miter is satisfiable.\n" );
+ else
+ printf( "The miter is unsatisfiable.\n" );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: sat [-vh]\n" );
+ fprintf( pErr, "\t solves the miter\n" );
+ fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandExtSeqDcs( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fVerbose;
+ extern int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNet, bool fVerbose );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( Abc_NtkLatchNum(pNtk) == 0 )
+ {
+ fprintf( stdout, "The current network has no latches.\n" );
+ return 0;
+ }
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( stdout, "This command works only for AIGs.\n" );
+ return 0;
+ }
+ if ( !Abc_NtkExtractSequentialDcs( pNtk, fVerbose ) )
+ {
+ fprintf( stdout, "Extracting sequential don't-cares has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: ext_seq_dcs [-vh]\n" );
+ fprintf( pErr, "\t create EXDC network using unreachable states\n" );
+ fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandOneOutput( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ Abc_Obj_t * pNode;
+ int c;
+ int fUseAllCis;
+ int Output;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fUseAllCis = 0;
+ Output = -1;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "Oah" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'O':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-O\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ Output = atoi(argv[util_optind]);
+ util_optind++;
+ if ( Output < 0 )
+ goto usage;
+ break;
+ case 'a':
+ fUseAllCis ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "Currently can only be applied to the logic network or an AIG.\n" );
+ return 1;
+ }
+
+ if ( argc > util_optind + 1 )
+ {
+ fprintf( pErr, "Wrong number of auguments.\n" );
+ goto usage;
+ }
+
+ if ( argc == util_optind + 1 )
+ {
+ pNode = Abc_NtkFindCo( pNtk, argv[util_optind] );
+ if ( pNode == NULL )
+ {
+ fprintf( pErr, "Cannot find CO node \"%s\".\n", argv[util_optind] );
+ return 1;
+ }
+ pNtkRes = Abc_NtkSplitOutput( pNtk, pNode, fUseAllCis );
+ }
+ else
+ {
+ if ( Output == -1 )
+ {
+ fprintf( pErr, "The output is not specified.\n" );
+ return 1;
+ }
+ if ( Output >= Abc_NtkCoNum(pNtk) )
+ {
+ fprintf( pErr, "The 0-based output number (%d) is larger than the number of outputs (%d).\n", Output, Abc_NtkCoNum(pNtk) );
+ return 1;
+ }
+ pNtkRes = Abc_NtkSplitOutput( pNtk, Abc_NtkCo(pNtk,Output), fUseAllCis );
+ }
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Splitting one output has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: one_output [-O num] [-ah] <name>\n" );
+ fprintf( pErr, "\t replaces the current network by the logic cone of one output\n" );
+ fprintf( pErr, "\t-a : toggle writing all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\t-O num : (optional) the 0-based number of the output\n");
+ fprintf( pErr, "\tname : (optional) the name of the output\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandOneNode( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ Abc_Obj_t * pNode;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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_NtkIsLogic(pNtk) )
+ {
+ fprintf( pErr, "Currently can only be applied to a logic network.\n" );
+ return 1;
+ }
+
+ if ( argc != util_optind + 1 )
+ {
+ fprintf( pErr, "Wrong number of auguments.\n" );
+ goto usage;
+ }
+
+ pNode = Abc_NtkFindNode( pNtk, argv[util_optind] );
+ if ( pNode == NULL )
+ {
+ fprintf( pErr, "Cannot find node \"%s\".\n", argv[util_optind] );
+ return 1;
+ }
+
+ pNtkRes = Abc_NtkSplitNode( pNtk, pNode );
+// pNtkRes = Abc_NtkDeriveFromBdd( pNtk->pManFunc, pNode->pData, NULL, NULL );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Splitting one node has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: one_node [-h] <name>\n" );
+ fprintf( pErr, "\t replaces the current network by the network composed of one node\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\tname : the node name\n");
+ return 1;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ Abc_NtkShortNames( pNtk );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: short_names [-h]\n" );
+ fprintf( pErr, "\t replaces PI/PO/latch names by short char strings\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ Cut_Params_t Params, * pParams = &Params;
+ Cut_Man_t * pCutMan;
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ extern Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ pParams->nVarsMax = 5; // the max cut size ("k" of the k-feasible cuts)
+ pParams->nKeepMax = 250; // the max number of cuts kept at a node
+ pParams->fTruth = 1; // compute truth tables
+ pParams->fHash = 0; // hash cuts to detect unique
+ pParams->fFilter = 0; // filter dominated cuts
+ pParams->fSeq = 0; // compute sequential cuts
+ pParams->fDrop = 0; // drop cuts on the fly
+ pParams->fVerbose = 0; // the verbosiness flag
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "KMtrfsdvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'K':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-K\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pParams->nVarsMax = atoi(argv[util_optind]);
+ util_optind++;
+ if ( pParams->nVarsMax < 0 )
+ goto usage;
+ break;
+ case 'M':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-M\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pParams->nKeepMax = atoi(argv[util_optind]);
+ util_optind++;
+ if ( pParams->nKeepMax < 0 )
+ goto usage;
+ break;
+ case 't':
+ pParams->fTruth ^= 1;
+ break;
+ case 'r':
+ pParams->fHash ^= 1;
+ break;
+ case 'f':
+ pParams->fFilter ^= 1;
+ break;
+ case 's':
+ pParams->fSeq ^= 1;
+ break;
+ case 'd':
+ pParams->fDrop ^= 1;
+ break;
+ case 'v':
+ pParams->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, "Cut computation is available only for AIGs.\n" );
+ return 1;
+ }
+ pCutMan = Abc_NtkCuts( pNtk, pParams );
+ Cut_ManPrintStats( pCutMan );
+ Cut_ManStop( pCutMan );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: cut [-K num] [-M num] [-trfsdvh]\n" );
+ fprintf( pErr, "\t computes k-feasible cuts for the AIG\n" );
+ fprintf( pErr, "\t-K num : max number of leaves (4 <= num <= 6) [default = %d]\n", 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-r : toggle reduction by hashing [default = %s]\n", pParams->fHash? "yes": "no" );
+ fprintf( pErr, "\t-f : toggle filtering by dominance [default = %s]\n", pParams->fFilter? "yes": "no" );
+ fprintf( pErr, "\t-s : toggle sequential cut computation [default = %s]\n", pParams->fSeq? "yes": "no" );
+ fprintf( pErr, "\t-d : toggle dropping when fanouts are done [default = %s]\n", pParams->fDrop? "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;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ // run the command
+ pNtkRes = Abc_NtkMiterForCofactors( pNtk, 0, 0, -1 );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Command has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: test [-h]\n" );
+ fprintf( pErr, "\t testbench for new procedures\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ char Buffer[100];
+ Fraig_Params_t Params, * pParams = &Params;
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int fAllNodes;
+ int c;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fAllNodes = 0;
+ pParams->nPatsRand = 2048; // the number of words of random simulation info
+ pParams->nPatsDyna = 2048; // the number of words of dynamic simulation info
+ pParams->nBTLimit = 99; // the max number of backtracks to perform
+ pParams->fFuncRed = 1; // performs only one level hashing
+ pParams->fFeedBack = 1; // enables solver feedback
+ pParams->fDist1Pats = 1; // enables distance-1 patterns
+ pParams->fDoSparse = 0; // performs equiv tests for sparse functions
+ pParams->fChoicing = 0; // enables recording structural choices
+ pParams->fTryProve = 0; // tries to solve the final miter
+ pParams->fVerbose = 0; // the verbosiness flag
+ pParams->fVerboseP = 0; // the verbosiness flag
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "RDBrscpvah" ) ) != EOF )
+ {
+ switch ( c )
+ {
+
+ case 'R':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-R\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pParams->nPatsRand = atoi(argv[util_optind]);
+ util_optind++;
+ if ( pParams->nPatsRand < 0 )
+ goto usage;
+ break;
+ case 'D':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-D\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pParams->nPatsDyna = atoi(argv[util_optind]);
+ util_optind++;
+ if ( pParams->nPatsDyna < 0 )
+ goto usage;
+ break;
+ case 'B':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-B\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pParams->nBTLimit = atoi(argv[util_optind]);
+ util_optind++;
+ if ( pParams->nBTLimit < 0 )
+ goto usage;
+ break;
+
+ case 'r':
+ pParams->fFuncRed ^= 1;
+ break;
+ case 's':
+ pParams->fDoSparse ^= 1;
+ break;
+ case 'c':
+ pParams->fChoicing ^= 1;
+ break;
+ case 'p':
+ pParams->fTryProve ^= 1;
+ break;
+ case 'v':
+ pParams->fVerbose ^= 1;
+ break;
+ case 'a':
+ fAllNodes ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "Can only fraig a logic network or an AIG.\n" );
+ return 1;
+ }
+
+ // report the proof
+ pParams->fVerboseP = pParams->fTryProve;
+
+ // get the new network
+ if ( Abc_NtkIsStrash(pNtk) )
+ pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes );
+ else
+ {
+ pNtk = Abc_NtkStrash( pNtk, fAllNodes, !fAllNodes );
+ pNtkRes = Abc_NtkFraig( pNtk, &Params, fAllNodes );
+ Abc_NtkDelete( pNtk );
+ }
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Fraiging has failed.\n" );
+ return 1;
+ }
+
+ if ( pParams->fTryProve ) // report the result
+ Abc_NtkMiterReport( pNtkRes );
+
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ sprintf( Buffer, "%d", pParams->nBTLimit );
+ fprintf( pErr, "usage: fraig [-R num] [-D num] [-B num] [-rscpvah]\n" );
+ fprintf( pErr, "\t transforms a logic network into a functionally reduced AIG\n" );
+ fprintf( pErr, "\t-R num : number of random patterns (127 < num < 32769) [default = %d]\n", pParams->nPatsRand );
+ fprintf( pErr, "\t-D num : number of systematic patterns (127 < num < 32769) [default = %d]\n", pParams->nPatsDyna );
+ fprintf( pErr, "\t-B num : number of backtracks for one SAT problem [default = %s]\n", pParams->nBTLimit==-1? "infinity" : Buffer );
+ fprintf( pErr, "\t-r : toggle functional reduction [default = %s]\n", pParams->fFuncRed? "yes": "no" );
+ fprintf( pErr, "\t-s : toggle considering sparse functions [default = %s]\n", pParams->fDoSparse? "yes": "no" );
+ fprintf( pErr, "\t-c : toggle accumulation of choices [default = %s]\n", pParams->fChoicing? "yes": "no" );
+ fprintf( pErr, "\t-p : toggle proving the final miter [default = %s]\n", pParams->fTryProve? "yes": "no" );
+ fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", pParams->fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-a : toggle between all nodes and DFS nodes [default = %s]\n", fAllNodes? "all": "dfs" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandFraigTrust( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkFraigTrust( pNtk );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Fraiging in the trust mode has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fraig_trust [-h]\n" );
+ fprintf( pErr, "\t transforms the current network into an AIG assuming it is FRAIG with choices\n" );
+// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandFraigStore( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( !Abc_NtkFraigStore( pNtk ) )
+ {
+ fprintf( pErr, "Fraig storing has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fraig_store [-h]\n" );
+ fprintf( pErr, "\t saves the current network in the AIG database\n" );
+// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandFraigRestore( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkFraigRestore();
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Fraig restoring has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fraig_restore [-h]\n" );
+ fprintf( pErr, "\t makes the current network by fraiging the AIG database\n" );
+// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandFraigClean( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fDuplicate;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fDuplicate = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'd':
+ fDuplicate ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ Abc_NtkFraigStoreClean();
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fraig_clean [-h]\n" );
+ fprintf( pErr, "\t cleans the internal FRAIG storage\n" );
+// fprintf( pErr, "\t-d : toggle duplication of logic [default = %s]\n", fDuplicate? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fUseInv;
+ int fVerbose;
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fUseInv = 1;
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "ivh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'i':
+ fUseInv ^= 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, "Cannot sweep AIGs (use \"fraig\").\n" );
+ return 1;
+ }
+ if ( !Abc_NtkIsLogic(pNtk) )
+ {
+ fprintf( pErr, "Transform the current network into a logic network.\n" );
+ return 1;
+ }
+ // modify the current network
+ if ( !Abc_NtkFraigSweep( pNtk, fUseInv, fVerbose ) )
+ {
+ fprintf( pErr, "Sweeping has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fraig_sweep [-vh]\n" );
+ fprintf( pErr, "\t performs technology-dependent sweep\n" );
+// fprintf( pErr, "\t-i : toggle using inverter for complemented nodes [default = %s]\n", fUseInv? "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;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ char Buffer[100];
+ double DelayTarget;
+ int fRecovery;
+ int fSweep;
+ int fSwitching;
+ int fVerbose;
+ int c;
+ extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fSwitching, int fVerbose );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ DelayTarget =-1;
+ fRecovery = 1;
+ fSweep = 1;
+ fSwitching = 0;
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "Daspvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'D':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-D\" should be followed by a floating point number.\n" );
+ goto usage;
+ }
+ DelayTarget = (float)atof(argv[util_optind]);
+ util_optind++;
+ if ( DelayTarget <= 0.0 )
+ goto usage;
+ break;
+ case 'a':
+ fRecovery ^= 1;
+ break;
+ case 's':
+ fSweep ^= 1;
+ break;
+ case 'p':
+ fSwitching ^= 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) )
+ {
+ pNtk = Abc_NtkStrash( pNtk, 0, 0 );
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Strashing before mapping has failed.\n" );
+ return 1;
+ }
+ pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 );
+ Abc_NtkDelete( pNtkRes );
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Balancing before mapping has failed.\n" );
+ return 1;
+ }
+ fprintf( pOut, "The network was strashed and balanced before mapping.\n" );
+ // get the new network
+ pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fSwitching, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ Abc_NtkDelete( pNtk );
+ fprintf( pErr, "Mapping has failed.\n" );
+ return 1;
+ }
+ Abc_NtkDelete( pNtk );
+ }
+ else
+ {
+ // get the new network
+ pNtkRes = Abc_NtkMap( pNtk, DelayTarget, fRecovery, fSwitching, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Mapping has failed.\n" );
+ return 1;
+ }
+ }
+
+ if ( fSweep )
+ Abc_NtkFraigSweep( pNtkRes, 0, 0 );
+
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ if ( DelayTarget == -1 )
+ sprintf( Buffer, "not used" );
+ else
+ sprintf( Buffer, "%.3f", DelayTarget );
+ fprintf( pErr, "usage: map [-D num] [-aspvh]\n" );
+ fprintf( pErr, "\t performs standard cell mapping of the current network\n" );
+ fprintf( pErr, "\t-D num : sets the global required times [default = %s]\n", Buffer );
+ fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" );
+ fprintf( pErr, "\t-s : toggles sweep after mapping [default = %s]\n", fSweep? "yes": "no" );
+ fprintf( pErr, "\t-p : optimizes power by minimizing switching activity [default = %s]\n", fSwitching? "yes": "no" );
+ fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandUnmap( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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_NtkHasMapping(pNtk) )
+ {
+ fprintf( pErr, "Cannot unmap the network that is not mapped.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( !Abc_NtkUnmap( pNtk ) )
+ {
+ fprintf( pErr, "Unmapping has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: unmap [-h]\n" );
+ fprintf( pErr, "\t replaces the library gates by the logic nodes represented using SOPs\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAttach( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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_NtkIsSopLogic(pNtk) )
+ {
+ fprintf( pErr, "Can only attach gates if the nodes have SOP representations.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( !Abc_NtkAttach( pNtk ) )
+ {
+ fprintf( pErr, "Attaching gates has failed.\n" );
+ return 1;
+ }
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: attach [-h]\n" );
+ fprintf( pErr, "\t replaces the SOP functions by the gates from the library\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSuperChoice( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( 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, "Works only for the AIG representation.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkSuperChoice( pNtk );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Superchoicing has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: sc [-h]\n" );
+ fprintf( pErr, "\t performs superchoicing\n" );
+ fprintf( pErr, "\t (accumulate: \"r file.blif; rsup; b; sc; f -ac; wb file_sc.blif\")\n" );
+ fprintf( pErr, "\t (map without supergate library: \"r file_sc.blif; ft; map\")\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ int fRecovery;
+ int fSwitching;
+ int fVerbose;
+ extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fSwitching, int fVerbose );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fRecovery = 1;
+ fSwitching = 0;
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "apvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'a':
+ fRecovery ^= 1;
+ break;
+ case 'p':
+ fSwitching ^= 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) )
+ {
+ // strash and balance the network
+ pNtk = Abc_NtkStrash( pNtk, 0, 0 );
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Strashing before FPGA mapping has failed.\n" );
+ return 1;
+ }
+ pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 );
+ Abc_NtkDelete( pNtkRes );
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Balancing before FPGA mapping has failed.\n" );
+ return 1;
+ }
+ fprintf( pOut, "The network was strashed and balanced before FPGA mapping.\n" );
+ // get the new network
+ pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fSwitching, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ Abc_NtkDelete( pNtk );
+ fprintf( pErr, "FPGA mapping has failed.\n" );
+ return 1;
+ }
+ Abc_NtkDelete( pNtk );
+ }
+ else
+ {
+ // get the new network
+ pNtkRes = Abc_NtkFpga( pNtk, fRecovery, fSwitching, fVerbose );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "FPGA mapping has failed.\n" );
+ return 1;
+ }
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: fpga [-apvh]\n" );
+ fprintf( pErr, "\t performs FPGA mapping of the current network\n" );
+ fprintf( pErr, "\t-a : toggles area recovery [default = %s]\n", fRecovery? "yes": "no" );
+ fprintf( pErr, "\t-p : optimizes power by minimizing switching activity [default = %s]\n", fSwitching? "yes": "no" );
+ fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : prints the command usage\n");
+ return 1;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSeq( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int c;
+ extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ printf( "This command is not yet implemented.\n" );
+ return 0;
+
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "Works only for AIG.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkAigToSeq( pNtk );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Converting to sequential AIG has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: seq [-h]\n" );
+ fprintf( pErr, "\t converts AIG into sequential AIG (while sweeping latches)\n" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk;
+ int c;
+ int fForward;
+ int fBackward;
+
+ extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk );
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fForward = 0;
+ fBackward = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "fbh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'f':
+ fForward ^= 1;
+ break;
+ case 'b':
+ fBackward ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( pErr, "Empty network.\n" );
+ return 1;
+ }
+
+ printf( "This command is not yet implemented.\n" );
+ return 0;
+
+
+ if ( !Abc_NtkIsSeq(pNtk) )
+ {
+ fprintf( pErr, "Works only for sequential AIG.\n" );
+ return 1;
+ }
+
+ // get the new network
+ if ( fForward )
+ Abc_NtkSeqRetimeForward( pNtk );
+ else if ( fBackward )
+ Abc_NtkSeqRetimeBackward( pNtk );
+ else
+ Abc_NtkSeqRetimeDelay( pNtk );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: retime [-fbh]\n" );
+ fprintf( pErr, "\t retimes sequential AIG (default is Pan's algorithm)\n" );
+ fprintf( pErr, "\t-f : toggle forward retiming [default = %s]\n", fForward? "yes": "no" );
+ fprintf( pErr, "\t-b : toggle backward retiming [default = %s]\n", fBackward? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtk1, * pNtk2;
+ int fDelete1, fDelete2;
+ char ** pArgvNew;
+ int nArgcNew;
+ int c;
+ int fSat;
+ int fVerbose;
+
+ extern void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
+ extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fVerbose );
+
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ fSat = 0;
+ fVerbose = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "svh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 's':
+ fSat ^= 1;
+ break;
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ pArgvNew = argv + util_optind;
+ nArgcNew = argc - util_optind;
+ if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
+ return 1;
+
+ // perform equivalence checking
+ if ( fSat )
+ Abc_NtkCecSat( pNtk1, pNtk2 );
+ else
+ Abc_NtkCecFraig( pNtk1, pNtk2, fVerbose );
+
+ if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
+ if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: cec [-svh] <file1> <file2>\n" );
+ fprintf( pErr, "\t performs combinational equivalence checking\n" );
+ fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" );
+ fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
+ fprintf( pErr, "\tfile2 : (optional) the file with the second network\n");
+ fprintf( pErr, "\t if no files are given, uses the current network and its spec\n");
+ fprintf( pErr, "\t if one file is given, uses the current network and the file\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtk1, * pNtk2;
+ int fDelete1, fDelete2;
+ char ** pArgvNew;
+ int nArgcNew;
+ int c;
+ int fSat;
+ int nFrames;
+
+ extern void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames );
+ extern void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames );
+
+
+ pNtk = Abc_FrameReadNet(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ nFrames = 3;
+ fSat = 0;
+ util_getopt_reset();
+ while ( ( c = util_getopt( argc, argv, "Fsh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'F':
+ if ( util_optind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nFrames = atoi(argv[util_optind]);
+ util_optind++;
+ if ( nFrames < 0 )
+ goto usage;
+ break;
+ case 's':
+ fSat ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ pArgvNew = argv + util_optind;
+ nArgcNew = argc - util_optind;
+ if ( !Abc_NtkPrepareTwoNtks( pErr, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) )
+ return 1;
+
+ // perform equivalence checking
+ if ( fSat )
+ Abc_NtkSecSat( pNtk1, pNtk2, nFrames );
+ else
+ Abc_NtkSecFraig( pNtk1, pNtk2, nFrames );
+
+ if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
+ if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: sec [-sh] [-F num] <file1> <file2>\n" );
+ fprintf( pErr, "\t performs bounded sequential equivalence checking\n" );
+ fprintf( pErr, "\t-s : toggle \"SAT only\" and \"FRAIG + SAT\" [default = %s]\n", fSat? "SAT only": "FRAIG + SAT" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ fprintf( pErr, "\t-F num : the number of time frames to use [default = %d]\n", nFrames );
+ fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
+ fprintf( pErr, "\tfile2 : (optional) the file with the second network\n");
+ fprintf( pErr, "\t if no files are given, uses the current network and its spec\n");
+ fprintf( pErr, "\t if one file is given, uses the current network and the file\n");
+ return 1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcAttach.c b/src/base/abci/abcAttach.c
new file mode 100644
index 00000000..a8e06555
--- /dev/null
+++ b/src/base/abci/abcAttach.c
@@ -0,0 +1,405 @@
+/**CFile****************************************************************
+
+ FileName [abcAttach.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Attaches the library gates to the current network.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcAttach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "main.h"
+#include "mio.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+#define ATTACH_FULL (~((unsigned)0))
+#define ATTACH_MASK(n) ((~((unsigned)0)) >> (32-(n)))
+
+static void Abc_AttachSetupTruthTables( unsigned uTruths[][2] );
+static void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthNode );
+static Mio_Gate_t * Abc_AttachFind( Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned * uTruthNode, int * Perm );
+static int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode );
+static int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] );
+static void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm );
+
+static char ** s_pPerms = NULL;
+static int s_nPerms;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Attaches gates from the current library to the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkAttach( Abc_Ntk_t * pNtk )
+{
+ int fCheck = 1;
+ Mio_Library_t * pGenlib;
+ unsigned ** puTruthGates;
+ unsigned uTruths[6][2];
+ Abc_Obj_t * pNode;
+ Mio_Gate_t ** ppGates;
+ int nGates, nFanins, i;
+
+ assert( Abc_NtkIsSopLogic(pNtk) );
+
+ // check that the library is available
+ pGenlib = Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame());
+ if ( pGenlib == NULL )
+ {
+ printf( "The current library is not available.\n" );
+ return 0;
+ }
+
+ // start the truth tables
+ Abc_AttachSetupTruthTables( uTruths );
+
+ // collect all the gates
+ ppGates = Mio_CollectRoots( pGenlib, 6, (float)1.0e+20, 1, &nGates );
+
+ // derive the gate truth tables
+ puTruthGates = ALLOC( unsigned *, nGates );
+ puTruthGates[0] = ALLOC( unsigned, 2 * nGates );
+ for ( i = 1; i < nGates; i++ )
+ puTruthGates[i] = puTruthGates[i-1] + 2;
+ for ( i = 0; i < nGates; i++ )
+ Mio_DeriveTruthTable( ppGates[i], uTruths, Mio_GateReadInputs(ppGates[i]), 6, puTruthGates[i] );
+
+ // assign the gates to pNode->pCopy
+ Abc_NtkCleanCopy( pNtk );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ nFanins = Abc_ObjFaninNum(pNode);
+ if ( nFanins == 0 )
+ {
+ if ( Abc_SopIsConst1(pNode->pData) )
+ pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst1(pGenlib);
+ else
+ pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst0(pGenlib);
+ }
+ else if ( nFanins == 1 )
+ {
+ if ( Abc_SopIsBuf(pNode->pData) )
+ pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadBuf(pGenlib);
+ else
+ pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadInv(pGenlib);
+ }
+ else if ( nFanins > 6 )
+ {
+ printf( "Cannot attach gate with more than 6 inputs to node %s.\n", Abc_ObjName(pNode) );
+ free( puTruthGates[0] );
+ free( puTruthGates );
+ free( ppGates );
+ return 0;
+ }
+ else if ( !Abc_NodeAttach( pNode, ppGates, puTruthGates, nGates, uTruths ) )
+ {
+ printf( "Could not attach the library gate to node %s.\n", Abc_ObjName(pNode) );
+ free( puTruthGates[0] );
+ free( puTruthGates );
+ free( ppGates );
+ return 0;
+ }
+ }
+ free( puTruthGates[0] );
+ free( puTruthGates );
+ free( ppGates );
+ FREE( s_pPerms );
+
+ // perform the final transformation
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( pNode->pCopy == NULL )
+ {
+ printf( "Some elementary gates (constant, buffer, or inverter) are missing in the library.\n" );
+ return 0;
+ }
+ }
+
+ // replace SOP representation by the gate representation
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ pNode->pData = pNode->pCopy, pNode->pCopy = NULL;
+ pNtk->ntkFunc = ABC_FUNC_MAP;
+ Extra_MmFlexStop( pNtk->pManFunc, 0 );
+ pNtk->pManFunc = pGenlib;
+
+ printf( "Library gates are successfully attached to the nodes.\n" );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkAttach: The network check has failed.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] )
+{
+ int Perm[10];
+ int pTempInts[10];
+ unsigned uTruthNode[2];
+ Abc_Obj_t * pFanin;
+ Mio_Gate_t * pGate;
+ int nFanins, i;
+
+ // compute the node's truth table
+ Abc_AttachComputeTruth( pNode->pData, uTruths, uTruthNode );
+ // find the matching gate and permutation
+ pGate = Abc_AttachFind( ppGates, puTruthGates, nGates, uTruthNode, Perm );
+ if ( pGate == NULL )
+ return 0;
+ // permute the fanins
+ nFanins = Abc_ObjFaninNum(pNode);
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ pTempInts[i] = pFanin->Id;
+ for ( i = 0; i < nFanins; i++ )
+ pNode->vFanins.pArray[Perm[i]].iFan = pTempInts[i];
+ // set the gate
+ pNode->pCopy = (Abc_Obj_t *)pGate;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets up the truth tables.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_AttachSetupTruthTables( unsigned uTruths[][2] )
+{
+ int m, v;
+ for ( v = 0; v < 5; v++ )
+ uTruths[v][0] = 0;
+ // set up the truth tables
+ for ( m = 0; m < 32; m++ )
+ for ( v = 0; v < 5; v++ )
+ if ( m & (1 << v) )
+ uTruths[v][0] |= (1 << m);
+ // make adjustments for the case of 6 variables
+ for ( v = 0; v < 5; v++ )
+ uTruths[v][1] = uTruths[v][0];
+ uTruths[5][0] = 0;
+ uTruths[5][1] = ATTACH_FULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Compute the truth table of the node's cover.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthRes )
+{
+// Mvc_Cube_t * pCube;
+ unsigned uSignCube[2];
+ int Value;
+// int nInputs = pCover->nBits/2;
+ int nInputs = 6;
+ int nFanins = Abc_SopGetVarNum(pSop);
+ char * pCube;
+ int k;
+
+ // make sure that the number of input truth tables in equal to the number of gate inputs
+ assert( nInputs < 7 );
+
+ // clean the resulting truth table
+ uTruthRes[0] = 0;
+ uTruthRes[1] = 0;
+ if ( nInputs < 6 )
+ {
+ // consider the case when only one unsigned can be used
+// Mvc_CoverForEachCube( pCover, pCube )
+ Abc_SopForEachCube( pSop, nFanins, pCube )
+ {
+ uSignCube[0] = ATTACH_FULL;
+// Mvc_CubeForEachVarValue( pCover, pCube, Var, Value )
+ Abc_CubeForEachVar( pCube, Value, k )
+ {
+ if ( Value == '0' )
+ uSignCube[0] &= ~uTruthsIn[k][0];
+ else if ( Value == '1' )
+ uSignCube[0] &= uTruthsIn[k][0];
+ }
+ uTruthRes[0] |= uSignCube[0];
+ }
+ if ( Abc_SopGetPhase(pSop) == 0 )
+ uTruthRes[0] = ~uTruthRes[0];
+ if ( nInputs < 5 )
+ uTruthRes[0] &= ATTACH_MASK(1<<nInputs);
+ }
+ else
+ {
+ // consider the case when two unsigneds should be used
+// Mvc_CoverForEachCube( pCover, pCube )
+ Abc_SopForEachCube( pSop, nFanins, pCube )
+ {
+ uSignCube[0] = ATTACH_FULL;
+ uSignCube[1] = ATTACH_FULL;
+// Mvc_CubeForEachVarValue( pCover, pCube, Var, Value )
+ Abc_CubeForEachVar( pCube, Value, k )
+ {
+ if ( Value == '0' )
+ {
+ uSignCube[0] &= ~uTruthsIn[k][0];
+ uSignCube[1] &= ~uTruthsIn[k][1];
+ }
+ else if ( Value == '1' )
+ {
+ uSignCube[0] &= uTruthsIn[k][0];
+ uSignCube[1] &= uTruthsIn[k][1];
+ }
+ }
+ uTruthRes[0] |= uSignCube[0];
+ uTruthRes[1] |= uSignCube[1];
+ }
+
+ // complement if the SOP is complemented
+ if ( Abc_SopGetPhase(pSop) == 0 )
+ {
+ uTruthRes[0] = ~uTruthRes[0];
+ uTruthRes[1] = ~uTruthRes[1];
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find the gate by truth table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Mio_Gate_t * Abc_AttachFind( Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned * uTruthNode, int * Perm )
+{
+ unsigned uTruthPerm[2];
+ int i, v, iNum;
+
+ // try the gates without permutation
+ if ( (iNum = Abc_AttachCompare( puTruthGates, nGates, uTruthNode )) >= 0 )
+ {
+ for ( v = 0; v < 6; v++ )
+ Perm[v] = v;
+ return ppGates[iNum];
+ }
+ // get permutations
+ if ( s_pPerms == NULL )
+ {
+ s_pPerms = Extra_Permutations( 6 );
+ s_nPerms = Extra_Factorial( 6 );
+ }
+ // try permutations
+ for ( i = 0; i < s_nPerms; i++ )
+ {
+ Abc_TruthPermute( s_pPerms[i], 6, uTruthNode, uTruthPerm );
+ if ( (iNum = Abc_AttachCompare( puTruthGates, nGates, uTruthPerm )) >= 0 )
+ {
+ for ( v = 0; v < 6; v++ )
+ Perm[v] = (int)s_pPerms[i][v];
+ return ppGates[iNum];
+ }
+ }
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find the gate by truth table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode )
+{
+ int i;
+ for ( i = 0; i < nGates; i++ )
+ if ( puTruthGates[i][0] == uTruthNode[0] && puTruthGates[i][1] == uTruthNode[1] )
+ return i;
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Permutes the 6-input truth table.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm )
+{
+ int nMints, iMintPerm, iMint, v;
+ uTruthPerm[0] = uTruthPerm[1] = 0;
+ nMints = (1 << nVars);
+ for ( iMint = 0; iMint < nMints; iMint++ )
+ {
+ if ( (uTruthNode[iMint/32] & (1 << (iMint%32))) == 0 )
+ continue;
+ iMintPerm = 0;
+ for ( v = 0; v < nVars; v++ )
+ if ( iMint & (1 << v) )
+ iMintPerm |= (1 << pPerm[v]);
+ uTruthPerm[iMintPerm/32] |= (1 << (iMintPerm%32));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcBalance.c b/src/base/abci/abcBalance.c
new file mode 100644
index 00000000..5042d0d5
--- /dev/null
+++ b/src/base/abci/abcBalance.c
@@ -0,0 +1,239 @@
+/**CFile****************************************************************
+
+ FileName [abcBalance.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Performs global balancing of the AIG by the number of levels.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcBalance.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate );
+static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, Vec_Vec_t * vStorage, bool fDuplicate );
+static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vSuper, int fDuplicate );
+static int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Balances the AIG network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkAig;
+ assert( Abc_NtkIsStrash(pNtk) );
+ // perform balancing
+ pNtkAig = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG );
+ Abc_NtkBalancePerform( pNtk, pNtkAig, fDuplicate );
+ Abc_NtkFinalize( pNtk, pNtkAig );
+ // make sure everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkAig ) )
+ {
+ printf( "Abc_NtkBalance: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkAig );
+ return NULL;
+ }
+ return pNtkAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Balances the AIG network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate )
+{
+ int fCheck = 1;
+ ProgressBar * pProgress;
+ Vec_Vec_t * vStorage;
+ Abc_Obj_t * pNode, * pDriver;
+ int i;
+
+ // copy the constant node
+ Abc_AigConst1(pNtk->pManFunc)->pCopy = Abc_AigConst1(pNtkAig->pManFunc);
+ // set the level of PIs of AIG according to the arrival times of the old network
+ Abc_NtkSetNodeLevelsArrival( pNtk );
+ // allocate temporary storage for supergates
+ vStorage = Vec_VecStart( Abc_AigGetLevelNum(pNtk) + 1 );
+ // perform balancing of POs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // strash the driver node
+ pDriver = Abc_ObjFanin0(pNode);
+ Abc_NodeBalance_rec( pNtkAig, pDriver, vStorage, fDuplicate );
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_VecFree( vStorage );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Rebalances the multi-input node rooted at pNodeOld.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_Vec_t * vStorage, bool fDuplicate )
+{
+ Abc_Aig_t * pMan = pNtkNew->pManFunc;
+ Abc_Obj_t * pNodeNew, * pNode1, * pNode2;
+ Vec_Ptr_t * vSuper;
+ int i;
+ assert( !Abc_ObjIsComplement(pNodeOld) );
+ // return if the result if known
+ if ( pNodeOld->pCopy )
+ return pNodeOld->pCopy;
+ assert( Abc_ObjIsNode(pNodeOld) );
+ // get the implication supergate
+ vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, fDuplicate );
+ if ( vSuper->nSize == 0 )
+ { // it means that the supergate contains two nodes in the opposite polarity
+ pNodeOld->pCopy = Abc_ObjNot(Abc_AigConst1(pMan));
+ return pNodeOld->pCopy;
+ }
+ // for each old node, derive the new well-balanced node
+ for ( i = 0; i < vSuper->nSize; i++ )
+ {
+ pNodeNew = Abc_NodeBalance_rec( pNtkNew, Abc_ObjRegular(vSuper->pArray[i]), vStorage, fDuplicate );
+ vSuper->pArray[i] = Abc_ObjNotCond( pNodeNew, Abc_ObjIsComplement(vSuper->pArray[i]) );
+ }
+ // sort the new nodes by level in the decreasing order
+ Vec_PtrSort( vSuper, Abc_NodeCompareLevelsDecrease );
+ // balance the nodes
+ assert( vSuper->nSize > 1 );
+ while ( vSuper->nSize > 1 )
+ {
+ pNode1 = Vec_PtrPop(vSuper);
+ pNode2 = Vec_PtrPop(vSuper);
+ Abc_VecObjPushUniqueOrderByLevel( vSuper, Abc_AigAnd(pMan, pNode1, pNode2) );
+ }
+ // make sure the balanced node is not assigned
+ assert( pNodeOld->pCopy == NULL );
+ // mark the old node with the new node
+ pNodeOld->pCopy = vSuper->pArray[0];
+ return pNodeOld->pCopy;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the nodes in the cone delimited by fMarkA==1.]
+
+ Description [Returns -1 if the AND-cone has the same node in both polarities.
+ Returns 1 if the AND-cone has the same node in the same polarity. Returns 0
+ if the AND-cone has no repeated nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vStorage, int fDuplicate )
+{
+ Vec_Ptr_t * vNodes;
+ int RetValue, i;
+ assert( !Abc_ObjIsComplement(pNode) );
+ vNodes = Vec_VecEntry( vStorage, pNode->Level );
+ Vec_PtrClear( vNodes );
+ RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, fDuplicate );
+ assert( vNodes->nSize > 0 );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ Abc_ObjRegular((Abc_Obj_t *)vNodes->pArray[i])->fMarkB = 0;
+ if ( RetValue == -1 )
+ vNodes->nSize = 0;
+ return vNodes;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Collects the nodes in the cone delimited by fMarkA==1.]
+
+ Description [Returns -1 if the AND-cone has the same node in both polarities.
+ Returns 1 if the AND-cone has the same node in the same polarity. Returns 0
+ if the AND-cone has no repeated nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate )
+{
+ int RetValue1, RetValue2, i;
+ // check if the node is visited
+ if ( Abc_ObjRegular(pNode)->fMarkB )
+ {
+ // check if the node occurs in the same polarity
+ for ( i = 0; i < vSuper->nSize; i++ )
+ if ( vSuper->pArray[i] == pNode )
+ return 1;
+ // check if the node is present in the opposite polarity
+ for ( i = 0; i < vSuper->nSize; i++ )
+ if ( vSuper->pArray[i] == Abc_ObjNot(pNode) )
+ return -1;
+ assert( 0 );
+ return 0;
+ }
+ // if the new node is complemented or a PI, another gate begins
+ if ( !fFirst && (Abc_ObjIsComplement(pNode) || !Abc_ObjIsNode(pNode) || !fDuplicate && (Abc_ObjFanoutNum(pNode) > 1)) )
+ {
+ Vec_PtrPush( vSuper, pNode );
+ Abc_ObjRegular(pNode)->fMarkB = 1;
+ return 0;
+ }
+ assert( !Abc_ObjIsComplement(pNode) );
+ assert( Abc_ObjIsNode(pNode) );
+ // go through the branches
+ RetValue1 = Abc_NodeBalanceCone_rec( Abc_ObjChild0(pNode), vSuper, 0, fDuplicate );
+ RetValue2 = Abc_NodeBalanceCone_rec( Abc_ObjChild1(pNode), vSuper, 0, fDuplicate );
+ if ( RetValue1 == -1 || RetValue2 == -1 )
+ return -1;
+ // return 1 if at least one branch has a duplicate
+ return RetValue1 || RetValue2;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcCollapse.c b/src/base/abci/abcCollapse.c
new file mode 100644
index 00000000..4e359506
--- /dev/null
+++ b/src/base/abci/abcCollapse.c
@@ -0,0 +1,147 @@
+/**CFile****************************************************************
+
+ FileName [abcCollapse.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Collapsing the network into two-levels.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcCollapse.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk );
+static Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Collapses the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkCollapse( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // compute the global BDDs
+ if ( Abc_NtkGlobalBdds(pNtk, 0) == NULL )
+ return NULL;
+ if ( fVerbose )
+ printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(pNtk->pManGlob) - Cudd_ReadDead(pNtk->pManGlob) );
+
+ // create the new network
+ pNtkNew = Abc_NtkFromGlobalBdds( pNtk );
+ Abc_NtkFreeGlobalBdds( pNtk );
+ if ( pNtkNew == NULL )
+ {
+ Cudd_Quit( pNtk->pManGlob );
+ pNtk->pManGlob = NULL;
+ return NULL;
+ }
+ Extra_StopManager( pNtk->pManGlob );
+ pNtk->pManGlob = NULL;
+
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtkNew );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkCollapse: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the network with the given global BDD.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromGlobalBdds( Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pNode, * pNodeNew;
+ DdManager * dd = pNtk->pManGlob;
+ int i;
+ // start the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD );
+ // make sure the new manager has the same number of inputs
+ Cudd_bddIthVar( pNtkNew->pManFunc, dd->size-1 );
+ // process the POs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNodeNew = Abc_NodeFromGlobalBdds( pNtkNew, dd, Vec_PtrEntry(pNtk->vFuncsGlob, i) );
+ Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
+ }
+ Extra_ProgressBarStop( pProgress );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the network with the given global BDD.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromGlobalBdds( Abc_Ntk_t * pNtkNew, DdManager * dd, DdNode * bFunc )
+{
+ Abc_Obj_t * pNodeNew, * pTemp;
+ int i;
+ // create a new node
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ // add the fanins in the order, in which they appear in the reordered manager
+ Abc_NtkForEachCi( pNtkNew, pTemp, i )
+ Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtkNew, dd->invperm[i]) );
+ // transfer the function
+ pNodeNew->pData = Extra_TransferLevelByLevel( dd, pNtkNew->pManFunc, bFunc ); Cudd_Ref( pNodeNew->pData );
+ return pNodeNew;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcCut.c b/src/base/abci/abcCut.c
new file mode 100644
index 00000000..f487bd1b
--- /dev/null
+++ b/src/base/abci/abcCut.c
@@ -0,0 +1,190 @@
+/**CFile****************************************************************
+
+ FileName [abcCut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Interface to cut computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "cut.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
+{
+ Cut_Man_t * p;
+ Abc_Obj_t * pObj, * pDriver, * pNode;
+ Vec_Ptr_t * vNodes;
+ Vec_Int_t * vChoices;
+ int i;
+ int clk = clock();
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // start the manager
+ pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
+ p = Cut_ManStart( pParams );
+ if ( pParams->fDrop )
+ Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
+ // set cuts for PIs
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ if ( Abc_ObjFanoutNum(pObj) > 0 )
+ Cut_NodeSetTriv( p, pObj->Id );
+ // compute cuts for internal nodes
+ vNodes = Abc_AigDfs( pNtk, 0, 1 );
+ vChoices = Vec_IntAlloc( 100 );
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ // when we reached a CO, it is time to deallocate the cuts
+ if ( Abc_ObjIsCo(pObj) )
+ {
+ if ( pParams->fDrop )
+ Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
+ continue;
+ }
+ // skip constant node, it has no cuts
+ if ( Abc_NodeIsConst(pObj) )
+ continue;
+ // compute the cuts to the internal node
+ Abc_NodeGetCuts( p, pObj );
+ // add cuts due to choices
+ if ( Abc_NodeIsAigChoice(pObj) )
+ {
+ Vec_IntClear( vChoices );
+ for ( pNode = pObj; pNode; pNode = pNode->pData )
+ Vec_IntPush( vChoices, pNode->Id );
+ Cut_NodeUnionCuts( p, vChoices );
+ }
+ }
+ if ( !pParams->fSeq )
+ {
+ Vec_PtrFree( vNodes );
+ Vec_IntFree( vChoices );
+PRT( "Total", clock() - clk );
+ return p;
+ }
+ assert( 0 );
+
+ // compute sequential cuts
+ Abc_NtkIncrementTravId( pNtk );
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ pDriver = Abc_ObjFanin0(pObj);
+ if ( !Abc_ObjIsNode(pDriver) )
+ continue;
+ if ( Abc_NodeIsTravIdCurrent(pDriver) )
+ continue;
+ Abc_NodeSetTravIdCurrent(pDriver);
+ Cut_NodeSetComputedAsNew( p, pDriver->Id );
+ }
+ // compute as long as new cuts appear
+
+
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj )
+{
+ void * pList;
+ if ( pList = Abc_NodeReadCuts( p, pObj ) )
+ return pList;
+ Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj) );
+ Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj) );
+ return Abc_NodeGetCuts( p, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj )
+{
+ return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
+ Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj )
+{
+ return Cut_NodeReadCuts( p, pObj->Id );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the cuts for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj )
+{
+ Cut_NodeFreeCuts( p, pObj->Id );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c
new file mode 100644
index 00000000..013b7ac4
--- /dev/null
+++ b/src/base/abci/abcDsd.c
@@ -0,0 +1,539 @@
+/**CFile****************************************************************
+
+ FileName [abcDsd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Decomposes the network using disjoint-support decomposition.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "dsd.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Abc_Ntk_t * Abc_NtkDsdInternal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort );
+static void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
+static Abc_Obj_t * Abc_NtkDsdConstructNode( Dsd_Manager_t * pManDsd, Dsd_Node_t * pNodeDsd, Abc_Ntk_t * pNtkNew );
+
+static Vec_Ptr_t * Abc_NtkCollectNodesForDsd( Abc_Ntk_t * pNtk );
+static void Abc_NodeDecompDsdAndMux( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Dsd_Manager_t * pManDsd, bool fRecursive );
+static bool Abc_NodeIsForDsd( Abc_Obj_t * pNode );
+static int Abc_NodeFindMuxVar( DdManager * dd, DdNode * bFunc, int nVars );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Derives the DSD network.]
+
+ Description [Takes the strashed network (pNtk), derives global BDDs for
+ the combinational outputs of this network, and decomposes these BDDs using
+ disjoint support decomposition. Finally, constructs and return a new
+ network, which is topologically equivalent to the decomposition tree.
+ Allocates and frees a new BDD manager and a new DSD manager.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkDsdGlobal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // perform FPGA mapping
+ if ( Abc_NtkGlobalBdds(pNtk, 0) == NULL )
+ return NULL;
+ if ( fVerbose )
+ printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(pNtk->pManGlob) - Cudd_ReadDead(pNtk->pManGlob) );
+
+ // transform the result of mapping into a BDD network
+ pNtkNew = Abc_NtkDsdInternal( pNtk, fVerbose, fPrint, fShort );
+ if ( pNtkNew == NULL )
+ {
+ Cudd_Quit( pNtk->pManGlob );
+ pNtk->pManGlob = NULL;
+ return NULL;
+ }
+ Extra_StopManager( pNtk->pManGlob );
+ pNtk->pManGlob = NULL;
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkDsdGlobal: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkDsdInternal( Abc_Ntk_t * pNtk, bool fVerbose, bool fPrint, bool fShort )
+{
+ DdManager * dd = pNtk->pManGlob;
+ Dsd_Manager_t * pManDsd;
+ Abc_Ntk_t * pNtkNew;
+ DdNode * bFunc;
+ char ** ppNamesCi, ** ppNamesCo;
+ Abc_Obj_t * pObj;
+ int i;
+
+ // complement the global functions
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ {
+ bFunc = Vec_PtrEntry(pNtk->vFuncsGlob, i);
+ Vec_PtrWriteEntry(pNtk->vFuncsGlob, i, Cudd_NotCond(bFunc, Abc_ObjFaninC0(pObj)) );
+ }
+
+ // perform the decomposition
+ assert( Vec_PtrSize(pNtk->vFuncsGlob) == Abc_NtkCoNum(pNtk) );
+ pManDsd = Dsd_ManagerStart( dd, Abc_NtkCiNum(pNtk), fVerbose );
+ Dsd_Decompose( pManDsd, (DdNode **)pNtk->vFuncsGlob->pArray, Abc_NtkCoNum(pNtk) );
+ Abc_NtkFreeGlobalBdds( pNtk );
+ if ( pManDsd == NULL )
+ {
+ Cudd_Quit( dd );
+ return NULL;
+ }
+
+ // start the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD );
+ // make sure the new manager has enough inputs
+ Cudd_bddIthVar( pNtkNew->pManFunc, dd->size-1 );
+ // put the results into the new network (save new CO drivers in old CO drivers)
+ Abc_NtkDsdConstruct( pManDsd, pNtk, pNtkNew );
+ // finalize the new network
+ Abc_NtkFinalize( pNtk, pNtkNew );
+ // fix the problem with complemented and duplicated CO edges
+ Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
+
+ if ( fPrint )
+ {
+ ppNamesCi = Abc_NtkCollectCioNames( pNtk, 0 );
+ ppNamesCo = Abc_NtkCollectCioNames( pNtk, 1 );
+ Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, fShort, -1 );
+ free( ppNamesCi );
+ free( ppNamesCo );
+ }
+
+ // stop the DSD manager
+ Dsd_ManagerStop( pManDsd );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the decomposed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
+{
+ Dsd_Node_t ** ppNodesDsd;
+ Dsd_Node_t * pNodeDsd;
+ Abc_Obj_t * pNode, * pNodeNew, * pDriver, * pConst1;
+ int i, nNodesDsd;
+
+ // save the CI nodes in the DSD nodes
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ {
+ pNodeDsd = Dsd_ManagerReadInput( pManDsd, i );
+ Dsd_NodeSetMark( pNodeDsd, (int)pNode->pCopy );
+ }
+ // set the constant node
+ pConst1 = Abc_AigConst1(pNtk->pManFunc);
+ if ( Abc_ObjFanoutNum(pConst1) > 0 )
+ pConst1->pCopy = Abc_NodeCreateConst1(pNtkNew);
+
+ // collect DSD nodes in DFS order (leaves and const1 are not collected)
+ ppNodesDsd = Dsd_TreeCollectNodesDfs( pManDsd, &nNodesDsd );
+ for ( i = 0; i < nNodesDsd; i++ )
+ Abc_NtkDsdConstructNode( pManDsd, ppNodesDsd[i], pNtkNew );
+ free( ppNodesDsd );
+
+ // set the pointers to the CO drivers
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ pDriver = Abc_ObjFanin0( pNode );
+ if ( !Abc_ObjIsNode(pDriver) )
+ continue;
+ if ( !Abc_NodeIsAigAnd(pDriver) )
+ continue;
+ pNodeDsd = Dsd_ManagerReadRoot( pManDsd, i );
+ pNodeNew = (Abc_Obj_t *)Dsd_NodeReadMark( Dsd_Regular(pNodeDsd) );
+ assert( !Abc_ObjIsComplement(pNodeNew) );
+ pDriver->pCopy = Abc_ObjNotCond( pNodeNew, Dsd_IsComplement(pNodeDsd) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs DSD using the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkDsdConstructNode( Dsd_Manager_t * pManDsd, Dsd_Node_t * pNodeDsd, Abc_Ntk_t * pNtkNew )
+{
+ DdManager * ddDsd = Dsd_ManagerReadDd( pManDsd );
+ DdManager * ddNew = pNtkNew->pManFunc;
+ Dsd_Node_t * pFaninDsd;
+ Abc_Obj_t * pNodeNew, * pFanin;
+ DdNode * bLocal, * bTemp, * bVar;
+ Dsd_Type_t Type;
+ int i, nDecs;
+
+ // create the new node
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ // add the fanins
+ Type = Dsd_NodeReadType( pNodeDsd );
+ nDecs = Dsd_NodeReadDecsNum( pNodeDsd );
+ assert( nDecs > 1 );
+ for ( i = 0; i < nDecs; i++ )
+ {
+ pFaninDsd = Dsd_NodeReadDec( pNodeDsd, i );
+ pFanin = (Abc_Obj_t *)Dsd_NodeReadMark(Dsd_Regular(pFaninDsd));
+ Abc_ObjAddFanin( pNodeNew, pFanin );
+ assert( Type == DSD_NODE_OR || !Dsd_IsComplement(pFaninDsd) );
+ }
+
+ // create the local function depending on the type of the node
+ ddNew = pNtkNew->pManFunc;
+ switch ( Type )
+ {
+ case DSD_NODE_CONST1:
+ {
+ bLocal = ddNew->one; Cudd_Ref( bLocal );
+ break;
+ }
+ case DSD_NODE_OR:
+ {
+ bLocal = Cudd_Not(ddNew->one); Cudd_Ref( bLocal );
+ for ( i = 0; i < nDecs; i++ )
+ {
+ pFaninDsd = Dsd_NodeReadDec( pNodeDsd, i );
+ bVar = Cudd_NotCond( ddNew->vars[i], Dsd_IsComplement(pFaninDsd) );
+ bLocal = Cudd_bddOr( ddNew, bTemp = bLocal, bVar ); Cudd_Ref( bLocal );
+ Cudd_RecursiveDeref( ddNew, bTemp );
+ }
+ break;
+ }
+ case DSD_NODE_EXOR:
+ {
+ bLocal = Cudd_Not(ddNew->one); Cudd_Ref( bLocal );
+ for ( i = 0; i < nDecs; i++ )
+ {
+ bLocal = Cudd_bddXor( ddNew, bTemp = bLocal, ddNew->vars[i] ); Cudd_Ref( bLocal );
+ Cudd_RecursiveDeref( ddNew, bTemp );
+ }
+ break;
+ }
+ case DSD_NODE_PRIME:
+ {
+ bLocal = Dsd_TreeGetPrimeFunction( ddDsd, pNodeDsd ); Cudd_Ref( bLocal );
+ bLocal = Extra_TransferLevelByLevel( ddDsd, ddNew, bTemp = bLocal ); Cudd_Ref( bLocal );
+ Cudd_RecursiveDeref( ddDsd, bTemp );
+ // bLocal is now in the new BDD manager
+ break;
+ }
+ default:
+ {
+ assert( 0 );
+ break;
+ }
+ }
+ pNodeNew->pData = bLocal;
+ Dsd_NodeSetMark( pNodeDsd, (int)pNodeNew );
+ return pNodeNew;
+}
+
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Recursively decomposes internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkDsdLocal( Abc_Ntk_t * pNtk, bool fVerbose, bool fRecursive )
+{
+ int fCheck = 1;
+ Dsd_Manager_t * pManDsd;
+ DdManager * dd = pNtk->pManFunc;
+ Vec_Ptr_t * vNodes;
+ int i;
+
+ assert( Abc_NtkIsBddLogic(pNtk) );
+
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtk );
+
+ // start the DSD manager
+ pManDsd = Dsd_ManagerStart( dd, dd->size, 0 );
+
+ // collect nodes for decomposition
+ vNodes = Abc_NtkCollectNodesForDsd( pNtk );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ Abc_NodeDecompDsdAndMux( vNodes->pArray[i], vNodes, pManDsd, fRecursive );
+ Vec_PtrFree( vNodes );
+
+ // stop the DSD manager
+ Dsd_ManagerStop( pManDsd );
+
+ // make sure everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkDsdRecursive: The network check has failed.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the nodes that may need decomposition.]
+
+ Description [The nodes that do not need decomposition are those
+ whose BDD has more internal nodes than the support size.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NtkCollectNodesForDsd( Abc_Ntk_t * pNtk )
+{
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode;
+ int i;
+ vNodes = Vec_PtrAlloc( 100 );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( Abc_NodeIsForDsd(pNode) )
+ Vec_PtrPush( vNodes, pNode );
+ }
+ return vNodes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs decomposition of one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeDecompDsdAndMux( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Dsd_Manager_t * pManDsd, bool fRecursive )
+{
+ DdManager * dd = pNode->pNtk->pManFunc;
+ Abc_Obj_t * pRoot, * pFanin, * pNode1, * pNode2, * pNodeC;
+ Dsd_Node_t ** ppNodesDsd, * pNodeDsd, * pFaninDsd;
+ int i, nNodesDsd, iVar, fCompl;
+
+ // try disjoint support decomposition
+ pNodeDsd = Dsd_DecomposeOne( pManDsd, pNode->pData );
+ fCompl = Dsd_IsComplement( pNodeDsd );
+ pNodeDsd = Dsd_Regular( pNodeDsd );
+
+ // determine what decomposition to use
+ if ( !fRecursive || Dsd_NodeReadDecsNum(pNodeDsd) != Abc_ObjFaninNum(pNode) )
+ { // perform DSD
+
+ // set the inputs
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ pFaninDsd = Dsd_ManagerReadInput( pManDsd, i );
+ Dsd_NodeSetMark( pFaninDsd, (int)pFanin );
+ }
+
+ // construct the intermediate nodes
+ ppNodesDsd = Dsd_TreeCollectNodesDfsOne( pManDsd, pNodeDsd, &nNodesDsd );
+ for ( i = 0; i < nNodesDsd; i++ )
+ {
+ pRoot = Abc_NtkDsdConstructNode( pManDsd, ppNodesDsd[i], pNode->pNtk );
+ if ( Abc_NodeIsForDsd(pRoot) && fRecursive )
+ Vec_PtrPush( vNodes, pRoot );
+ }
+ free( ppNodesDsd );
+
+ // remove the current fanins
+ Abc_ObjRemoveFanins( pNode );
+ // add fanin to the root
+ Abc_ObjAddFanin( pNode, pRoot );
+ // update the function to be that of buffer
+ Cudd_RecursiveDeref( dd, pNode->pData );
+ pNode->pData = Cudd_NotCond( dd->vars[0], fCompl ); Cudd_Ref( pNode->pData );
+ }
+ else // perform MUX-decomposition
+ {
+ // get the cofactoring variable
+ iVar = Abc_NodeFindMuxVar( dd, pNode->pData, Abc_ObjFaninNum(pNode) );
+ pNodeC = Abc_ObjFanin( pNode, iVar );
+
+ // get the negative cofactor
+ pNode1 = Abc_NodeClone( pNode );
+ pNode1->pData = Cudd_Cofactor( dd, pNode->pData, Cudd_Not(dd->vars[iVar]) ); Cudd_Ref( pNode1->pData );
+ Abc_NodeMinimumBase( pNode1 );
+ if ( Abc_NodeIsForDsd(pNode1) )
+ Vec_PtrPush( vNodes, pNode1 );
+
+ // get the positive cofactor
+ pNode2 = Abc_NodeClone( pNode );
+ pNode2->pData = Cudd_Cofactor( dd, pNode->pData, dd->vars[iVar] ); Cudd_Ref( pNode2->pData );
+ Abc_NodeMinimumBase( pNode2 );
+ if ( Abc_NodeIsForDsd(pNode2) )
+ Vec_PtrPush( vNodes, pNode2 );
+
+ // remove the current fanins
+ Abc_ObjRemoveFanins( pNode );
+ // add new fanins
+ Abc_ObjAddFanin( pNode, pNodeC );
+ Abc_ObjAddFanin( pNode, pNode2 );
+ Abc_ObjAddFanin( pNode, pNode1 );
+ // update the function to be that of MUX
+ Cudd_RecursiveDeref( dd, pNode->pData );
+ pNode->pData = Cudd_bddIte( dd, dd->vars[0], dd->vars[1], dd->vars[2] ); Cudd_Ref( pNode->pData );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs decomposition of one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NodeIsForDsd( Abc_Obj_t * pNode )
+{
+ DdManager * dd = pNode->pNtk->pManFunc;
+ DdNode * bFunc, * bFunc0, * bFunc1;
+ assert( Abc_ObjIsNode(pNode) );
+// if ( Cudd_DagSize(pNode->pData)-1 > Abc_ObjFaninNum(pNode) )
+// return 1;
+// return 0;
+
+ for ( bFunc = Cudd_Regular(pNode->pData); !cuddIsConstant(bFunc); )
+ {
+ bFunc0 = Cudd_Regular( cuddE(bFunc) );
+ bFunc1 = cuddT(bFunc);
+ if ( bFunc0 == b1 )
+ bFunc = bFunc1;
+ else if ( bFunc1 == b1 || bFunc0 == bFunc1 )
+ bFunc = bFunc0;
+ else
+ return 1;
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Determines a cofactoring variable.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeFindMuxVar( DdManager * dd, DdNode * bFunc, int nVars )
+{
+ DdNode * bVar, * bCof0, * bCof1;
+ int SuppSumMin = 1000000;
+ int i, nSSD, nSSQ, iVar;
+
+// printf( "\n\nCofactors:\n\n" );
+ iVar = -1;
+ for ( i = 0; i < nVars; i++ )
+ {
+ bVar = dd->vars[i];
+
+ bCof0 = Cudd_Cofactor( dd, bFunc, Cudd_Not(bVar) ); Cudd_Ref( bCof0 );
+ bCof1 = Cudd_Cofactor( dd, bFunc, bVar ); Cudd_Ref( bCof1 );
+
+// nodD = Cudd_DagSize(bCof0);
+// nodQ = Cudd_DagSize(bCof1);
+// printf( "+%02d: D=%2d. Q=%2d. ", i, nodD, nodQ );
+// printf( "S=%2d. D=%2d. ", nodD + nodQ, abs(nodD-nodQ) );
+
+ nSSD = Cudd_SupportSize( dd, bCof0 );
+ nSSQ = Cudd_SupportSize( dd, bCof1 );
+
+// printf( "SD=%2d. SQ=%2d. ", nSSD, nSSQ );
+// printf( "S=%2d. D=%2d. ", nSSD + nSSQ, abs(nSSD - nSSQ) );
+// printf( "Cost=%3d. ", Cost(nodD,nodQ,nSSD,nSSQ) );
+// printf( "\n" );
+
+ Cudd_RecursiveDeref( dd, bCof0 );
+ Cudd_RecursiveDeref( dd, bCof1 );
+
+ if ( SuppSumMin > nSSD + nSSQ )
+ {
+ SuppSumMin = nSSD + nSSQ;
+ iVar = i;
+ }
+ }
+ return iVar;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcFpga.c b/src/base/abci/abcFpga.c
new file mode 100644
index 00000000..f30325c0
--- /dev/null
+++ b/src/base/abci/abcFpga.c
@@ -0,0 +1,267 @@
+/**CFile****************************************************************
+
+ FileName [abcFpga.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Interface with the FPGA mapping package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFpga.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fpgaInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose );
+static Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk );
+static Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Interface with the FPGA mapping package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, int fRecovery, int fSwitching, int fVerbose )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+ Fpga_Man_t * pMan;
+ Vec_Int_t * vSwitching;
+ float * pSwitching = NULL;
+ int fShowSwitching = 0;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // print a warning about choice nodes
+ if ( Abc_NtkGetChoiceNum( pNtk ) )
+ printf( "Performing FPGA mapping with choices.\n" );
+
+ // compute switching activity
+ fShowSwitching |= fSwitching;
+ if ( fShowSwitching )
+ {
+ extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns );
+ vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 );
+ pSwitching = (float *)vSwitching->pArray;
+ }
+
+ // perform FPGA mapping
+ pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fVerbose );
+ if ( pSwitching ) Vec_IntFree( vSwitching );
+ if ( pMan == NULL )
+ return NULL;
+ Fpga_ManSetSwitching( pMan, fSwitching );
+ if ( !Fpga_Mapping( pMan ) )
+ {
+ Fpga_ManFree( pMan );
+ return NULL;
+ }
+
+ // transform the result of mapping into a BDD network
+ pNtkNew = Abc_NtkFromFpga( pMan, pNtk );
+ if ( pNtkNew == NULL )
+ return NULL;
+ Fpga_ManFree( pMan );
+
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtkNew );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkFpga: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Load the network into FPGA manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fpga_Man_t * Abc_NtkToFpga( Abc_Ntk_t * pNtk, int fRecovery, float * pSwitching, int fVerbose )
+{
+ Fpga_Man_t * pMan;
+ ProgressBar * pProgress;
+ Fpga_Node_t * pNodeFpga;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pFanin, * pPrev;
+ int i;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // start the mapping manager and set its parameters
+ pMan = Fpga_ManCreate( Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), fVerbose );
+ if ( pMan == NULL )
+ return NULL;
+ Fpga_ManSetAreaRecovery( pMan, fRecovery );
+ Fpga_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
+ Fpga_ManSetInputArrivals( pMan, Abc_NtkGetCiArrivalFloats(pNtk) );
+
+ // create PIs and remember them in the old nodes
+ Abc_NtkCleanCopy( pNtk );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ {
+ pNodeFpga = Fpga_ManReadInputs(pMan)[i];
+ pNode->pCopy = (Abc_Obj_t *)pNodeFpga;
+ if ( pSwitching )
+ Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] );
+ }
+
+ // load the AIG into the mapper
+ vNodes = Abc_AigDfs( pNtk, 0, 0 );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // consider the case of a constant
+ if ( Abc_NodeIsConst(pNode) )
+ {
+ Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Fpga_ManReadConst1(pMan);
+ continue;
+ }
+ // add the node to the mapper
+ pNodeFpga = Fpga_NodeAnd( pMan,
+ Fpga_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
+ Fpga_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
+ assert( pNode->pCopy == NULL );
+ // remember the node
+ pNode->pCopy = (Abc_Obj_t *)pNodeFpga;
+ if ( pSwitching )
+ Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] );
+ // set up the choice node
+ if ( Abc_NodeIsAigChoice( pNode ) )
+ for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
+ {
+ Fpga_NodeSetNextE( (Fpga_Node_t *)pPrev->pCopy, (Fpga_Node_t *)pFanin->pCopy );
+ Fpga_NodeSetRepr( (Fpga_Node_t *)pFanin->pCopy, (Fpga_Node_t *)pNode->pCopy );
+ }
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+
+ // set the primary outputs without copying the phase
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Fpga_ManReadOutputs(pMan)[i] = (Fpga_Node_t *)Abc_ObjFanin0(pNode)->pCopy;
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the mapped network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromFpga( Fpga_Man_t * pMan, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pNode, * pNodeNew;
+ int i, nDupGates;
+ // create the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD );
+ // make the mapper point to the new network
+ Fpga_CutsCleanSign( pMan );
+ Fpga_ManCleanData0( pMan );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ Fpga_NodeSetData0( Fpga_ManReadInputs(pMan)[i], (char *)pNode->pCopy );
+ // set the constant node
+ if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 )
+ Fpga_NodeSetData0( Fpga_ManReadConst1(pMan), (char *)Abc_NodeCreateConst1(pNtkNew) );
+ // process the nodes in topological order
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNodeNew = Abc_NodeFromFpga_rec( pNtkNew, Fpga_ManReadOutputs(pMan)[i] );
+ assert( !Abc_ObjIsComplement(pNodeNew) );
+ Abc_ObjFanin0(pNode)->pCopy = pNodeNew;
+ }
+ Extra_ProgressBarStop( pProgress );
+ // finalize the new network
+ Abc_NtkFinalize( pNtk, pNtkNew );
+ // decouple the PO driver nodes to reduce the number of levels
+ nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
+// if ( nDupGates && Fpga_ManReadVerbose(pMan) )
+// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derive one node after FPGA mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromFpga_rec( Abc_Ntk_t * pNtkNew, Fpga_Node_t * pNodeFpga )
+{
+ Fpga_Cut_t * pCutBest;
+ Fpga_Node_t ** ppLeaves;
+ Abc_Obj_t * pNodeNew;
+ int i, nLeaves;
+ assert( !Fpga_IsComplement(pNodeFpga) );
+ // return if the result if known
+ pNodeNew = (Abc_Obj_t *)Fpga_NodeReadData0( pNodeFpga );
+ if ( pNodeNew )
+ return pNodeNew;
+ assert( Fpga_NodeIsAnd(pNodeFpga) );
+ // get the parameters of the best cut
+ pCutBest = Fpga_NodeReadCutBest( pNodeFpga );
+ ppLeaves = Fpga_CutReadLeaves( pCutBest );
+ nLeaves = Fpga_CutReadLeavesNum( pCutBest );
+ // create a new node
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < nLeaves; i++ )
+ Abc_ObjAddFanin( pNodeNew, Abc_NodeFromFpga_rec(pNtkNew, ppLeaves[i]) );
+ // derive the function of this node
+ pNodeNew->pData = Fpga_TruthsCutBdd( pNtkNew->pManFunc, pCutBest ); Cudd_Ref( pNodeNew->pData );
+ Fpga_NodeSetData0( pNodeFpga, (char *)pNodeNew );
+ return pNodeNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcFraig.c b/src/base/abci/abcFraig.c
new file mode 100644
index 00000000..fbe676a3
--- /dev/null
+++ b/src/base/abci/abcFraig.c
@@ -0,0 +1,586 @@
+/**CFile****************************************************************
+
+ FileName [abcFraig.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures interfacing with the FRAIG package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFraig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fraig.h"
+#include "main.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes );
+static Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
+static Abc_Obj_t * Abc_NodeFromFraig_rec( Abc_Ntk_t * pNtkNew, Fraig_Node_t * pNodeFraig );
+
+static int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk );
+static void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
+static Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFraig( Abc_Ntk_t * pNtk, void * pParams, int fAllNodes )
+{
+ int fCheck = 1;
+ Fraig_Params_t * pPars = pParams;
+ Abc_Ntk_t * pNtkNew;
+ Fraig_Man_t * pMan;
+ // perform fraiging
+ pMan = Abc_NtkToFraig( pNtk, pParams, fAllNodes );
+ // prove the miter if asked to
+ if ( pPars->fTryProve )
+ Fraig_ManProveMiter( pMan );
+ // reconstruct FRAIG in the new network
+ pNtkNew = Abc_NtkFromFraig( pMan, pNtk );
+ Fraig_ManFree( pMan );
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkFraig: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the strashed network into FRAIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes )
+{
+ Fraig_Man_t * pMan;
+ ProgressBar * pProgress;
+ Fraig_Node_t * pNodeFraig;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pConst1, * pReset;
+ int i;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // create the FRAIG manager
+ pMan = Fraig_ManCreate( pParams );
+
+ // create PIs and remember them in the old nodes
+ Abc_NtkCleanCopy( pNtk );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ pNode->pCopy = (Abc_Obj_t *)Fraig_ManReadIthVar(pMan, i);
+ pConst1 = Abc_AigConst1( pNtk->pManFunc );
+ pReset = Abc_AigReset( pNtk->pManFunc );
+
+ // perform strashing
+ vNodes = Abc_AigDfs( pNtk, fAllNodes, 0 );
+ if ( !pParams->fInternal )
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ if ( !pParams->fInternal )
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ if ( pNode == pConst1 )
+ pNodeFraig = Fraig_ManReadConst1(pMan);
+ else if ( pNode == pReset )
+ continue;
+ else
+ pNodeFraig = Fraig_NodeAnd( pMan,
+ Fraig_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
+ Fraig_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
+ assert( pNode->pCopy == NULL );
+ pNode->pCopy = (Abc_Obj_t *)pNodeFraig;
+ }
+ if ( !pParams->fInternal )
+ Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+
+ // set the primary outputs
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Fraig_ManSetPo( pMan, (Fraig_Node_t *)Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ) );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms FRAIG into what looks like a strashed network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pNode, * pNodeNew;
+ int i;
+ // create the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG );
+ // make the mapper point to the new network
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ Fraig_NodeSetData1( Fraig_ManReadIthVar(pMan, i), (Fraig_Node_t *)pNode->pCopy );
+ // set the constant node
+ Fraig_NodeSetData1( Fraig_ManReadConst1(pMan), (Fraig_Node_t *)Abc_AigConst1(pNtkNew->pManFunc) );
+ // process the nodes in topological order
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNodeNew = Abc_NodeFromFraig_rec( pNtkNew, Fraig_ManReadOutputs(pMan)[i] );
+ Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
+ }
+ Extra_ProgressBarStop( pProgress );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms into AIG one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromFraig_rec( Abc_Ntk_t * pNtkNew, Fraig_Node_t * pNodeFraig )
+{
+ Abc_Obj_t * pRes, * pRes0, * pRes1, * pResMin, * pResCur;
+ Fraig_Node_t * pNodeTemp, * pNodeFraigR = Fraig_Regular(pNodeFraig);
+ void ** ppTail;
+ // check if the node was already considered
+ if ( pRes = (Abc_Obj_t *)Fraig_NodeReadData1(pNodeFraigR) )
+ return Abc_ObjNotCond( pRes, Fraig_IsComplement(pNodeFraig) );
+ // solve the children
+ pRes0 = Abc_NodeFromFraig_rec( pNtkNew, Fraig_NodeReadOne(pNodeFraigR) );
+ pRes1 = Abc_NodeFromFraig_rec( pNtkNew, Fraig_NodeReadTwo(pNodeFraigR) );
+ // derive the new node
+ pRes = Abc_AigAnd( pNtkNew->pManFunc, pRes0, pRes1 );
+ pRes->fPhase = Fraig_NodeReadSimInv( pNodeFraigR );
+ // if the node has an equivalence class, find its representative
+ if ( Fraig_NodeReadRepr(pNodeFraigR) == NULL && Fraig_NodeReadNextE(pNodeFraigR) != NULL )
+ {
+ // go through the FRAIG nodes belonging to this equivalence class
+ // and find the representative node (the node with the smallest level)
+ pResMin = pRes;
+ for ( pNodeTemp = Fraig_NodeReadNextE(pNodeFraigR); pNodeTemp; pNodeTemp = Fraig_NodeReadNextE(pNodeTemp) )
+ {
+ assert( Fraig_NodeReadData1(pNodeTemp) == NULL );
+ pResCur = Abc_NodeFromFraig_rec( pNtkNew, pNodeTemp );
+ if ( pResMin->Level > pResCur->Level )
+ pResMin = pResCur;
+ }
+ // link the nodes in such a way that representative goes first
+ ppTail = &pResMin->pData;
+ if ( pRes != pResMin )
+ {
+ *ppTail = pRes;
+ ppTail = &pRes->pData;
+ }
+ for ( pNodeTemp = Fraig_NodeReadNextE(pNodeFraigR); pNodeTemp; pNodeTemp = Fraig_NodeReadNextE(pNodeTemp) )
+ {
+ pResCur = (Abc_Obj_t *)Fraig_NodeReadData1(pNodeTemp);
+ assert( pResCur );
+ if ( pResMin == pResCur )
+ continue;
+ *ppTail = pResCur;
+ ppTail = &pResCur->pData;
+ }
+ assert( *ppTail == NULL );
+
+ // update the phase of the node
+ pRes = Abc_ObjNotCond( pResMin, (pRes->fPhase ^ pResMin->fPhase) );
+ }
+ Fraig_NodeSetData1( pNodeFraigR, (Fraig_Node_t *)pRes );
+ return Abc_ObjNotCond( pRes, Fraig_IsComplement(pNodeFraig) );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFraigTrust( Abc_Ntk_t * pNtk )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+
+ if ( !Abc_NtkIsSopLogic(pNtk) )
+ {
+ printf( "Abc_NtkFraigTrust: Trust mode works for netlists and logic SOP networks.\n" );
+ return NULL;
+ }
+
+ if ( !Abc_NtkFraigTrustCheck(pNtk) )
+ {
+ printf( "Abc_NtkFraigTrust: The network does not look like an AIG with choice nodes.\n" );
+ return NULL;
+ }
+
+ // perform strashing
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG );
+ Abc_NtkFraigTrustOne( pNtk, pNtkNew );
+ Abc_NtkFinalize( pNtk, pNtkNew );
+
+ // print a warning about choice nodes
+ printf( "Warning: The resulting AIG contains %d choice nodes.\n", Abc_NtkGetChoiceNum( pNtkNew ) );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkFraigTrust: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks whether the node can be processed in the trust mode.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkFraigTrustCheck( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, nFanins;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ nFanins = Abc_ObjFaninNum(pNode);
+ if ( nFanins < 2 )
+ continue;
+ if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) )
+ continue;
+ if ( !Abc_SopIsOrType(pNode->pData) )
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigTrustOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
+{
+ ProgressBar * pProgress;
+ Abc_Aig_t * pMan = pNtkNew->pManFunc;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pNodeNew, * pObj;
+ int i;
+
+ // perform strashing
+ vNodes = Abc_NtkDfs( pNtk, 0 );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // get the node
+ assert( Abc_ObjIsNode(pNode) );
+ // strash the node
+ pNodeNew = Abc_NodeFraigTrust( pMan, pNode );
+ // get the old object
+ if ( Abc_NtkIsNetlist(pNtk) )
+ pObj = Abc_ObjFanout0( pNode ); // the fanout net
+ else
+ pObj = pNode; // the node itself
+ // make sure the node is not yet strashed
+ assert( pObj->pCopy == NULL );
+ // mark the old object with the new AIG node
+ pObj->pCopy = pNodeNew;
+ }
+ Vec_PtrFree( vNodes );
+ Extra_ProgressBarStop( pProgress );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms one node into a FRAIG in the trust mode.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFraigTrust( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pSum, * pFanin;
+ Abc_Obj_t * pConst1 = Abc_AigConst1(pMan);
+ void ** ppTail;
+ int i, nFanins, fCompl;
+
+ assert( Abc_ObjIsNode(pNode) );
+ // get the number of node's fanins
+ nFanins = Abc_ObjFaninNum( pNode );
+ assert( nFanins == Abc_SopGetVarNum(pNode->pData) );
+ // check if it is a constant
+ if ( nFanins == 0 )
+ return Abc_ObjNotCond( pConst1, Abc_SopIsConst0(pNode->pData) );
+ if ( nFanins == 1 )
+ return Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_SopIsInv(pNode->pData) );
+ if ( nFanins == 2 && Abc_SopIsAndType(pNode->pData) )
+ return Abc_AigAnd( pMan,
+ Abc_ObjNotCond( Abc_ObjFanin0(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,0) ),
+ Abc_ObjNotCond( Abc_ObjFanin1(pNode)->pCopy, !Abc_SopGetIthCareLit(pNode->pData,1) ) );
+ assert( Abc_SopIsOrType(pNode->pData) );
+ fCompl = Abc_SopGetIthCareLit(pNode->pData,0);
+ // get the root of the choice node (the first fanin)
+ pSum = Abc_ObjFanin0(pNode)->pCopy;
+ // connect other fanins
+ ppTail = &pSum->pData;
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ if ( i == 0 )
+ continue;
+ *ppTail = pFanin->pCopy;
+ ppTail = &pFanin->pCopy->pData;
+ // set the complemented bit of this cut
+ if ( fCompl ^ Abc_SopGetIthCareLit(pNode->pData, i) )
+ pFanin->pCopy->fPhase = 1;
+ }
+ assert( *ppTail == NULL );
+ return pSum;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkFraigStore( Abc_Ntk_t * pNtk )
+{
+ Abc_Frame_t * p;
+ Abc_Ntk_t * pStore;
+ int nAndsOld;
+
+ if ( !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) )
+ {
+ printf( "The netlist need to be converted into a logic network before adding it to storage.\n" );
+ return 0;
+ }
+
+ // get the network currently stored
+ p = Abc_FrameGetGlobalFrame();
+ pStore = Abc_FrameReadNtkStore(p);
+ if ( pStore == NULL )
+ {
+ // start the stored network
+ pStore = Abc_NtkStrash( pNtk, 0, 0 );
+ if ( pStore == NULL )
+ {
+ printf( "Abc_NtkFraigStore: Initial strashing has failed.\n" );
+ return 0;
+ }
+ // save the parameters
+ Abc_FrameSetNtkStore( p, pStore );
+ Abc_FrameSetNtkStoreSize( p, 1 );
+ nAndsOld = 0;
+ }
+ else
+ {
+ // add the new network to storage
+ nAndsOld = Abc_NtkNodeNum( pStore );
+ if ( !Abc_NtkAppend( pStore, pNtk ) )
+ {
+ printf( "The current network cannot be appended to the stored network.\n" );
+ return 0;
+ }
+ // set the number of networks stored
+ Abc_FrameSetNtkStoreSize( p, Abc_FrameReadNtkStoreSize(p) + 1 );
+ }
+ printf( "The number of AIG nodes added to storage = %5d.\n", Abc_NtkNodeNum(pStore) - nAndsOld );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFraigRestore()
+{
+ Abc_Frame_t * p;
+ Fraig_Params_t Params;
+ Abc_Ntk_t * pStore, * pFraig;
+ int nWords1, nWords2, nWordsMin;
+
+ // get the stored network
+ p = Abc_FrameGetGlobalFrame();
+ pStore = Abc_FrameReadNtkStore(p);
+ Abc_FrameSetNtkStore( p, NULL );
+ if ( pStore == NULL )
+ {
+ printf( "There are no network currently in storage.\n" );
+ return NULL;
+ }
+ printf( "Currently stored %d networks with %d nodes will be fraiged.\n",
+ Abc_FrameReadNtkStoreSize(p), Abc_NtkNodeNum(pStore) );
+
+ // to determine the number of simulation patterns
+ // use the following strategy
+ // at least 64 words (32 words random and 32 words dynamic)
+ // no more than 256M for one circuit (128M + 128M)
+ nWords1 = 32;
+ nWords2 = (1<<27) / (Abc_NtkNodeNum(pStore) + Abc_NtkCiNum(pStore));
+ nWordsMin = ABC_MIN( nWords1, nWords2 );
+
+ // set parameters for fraiging
+ Fraig_ParamsSetDefault( &Params );
+ Params.nPatsRand = nWordsMin * 32; // the number of words of random simulation info
+ Params.nPatsDyna = nWordsMin * 32; // the number of words of dynamic simulation info
+ Params.nBTLimit = 99; // the max number of backtracks to perform
+ Params.fFuncRed = 1; // performs only one level hashing
+ Params.fFeedBack = 1; // enables solver feedback
+ Params.fDist1Pats = 1; // enables distance-1 patterns
+ Params.fDoSparse = 1; // performs equiv tests for sparse functions
+ Params.fChoicing = 1; // enables recording structural choices
+ Params.fTryProve = 0; // tries to solve the final miter
+ Params.fVerbose = 0; // the verbosiness flag
+
+// Fraig_ManReportChoices( p );
+ // transform it into FRAIG
+ pFraig = Abc_NtkFraig( pStore, &Params, 1 );
+ if ( pFraig == NULL )
+ return NULL;
+ Abc_NtkDelete( pStore );
+ return pFraig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Interfaces the network with the FRAIG package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigStoreClean()
+{
+ Abc_Frame_t * p;
+ Abc_Ntk_t * pStore;
+ // get the stored network
+ p = Abc_FrameGetGlobalFrame();
+ pStore = Abc_FrameReadNtkStore(p);
+ if ( pStore )
+ Abc_NtkDelete( pStore );
+ Abc_FrameSetNtkStore( p, NULL );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks the correctness of stored networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigStoreCheck( Abc_Ntk_t * pFraig )
+{
+ Abc_Obj_t * pNode0, * pNode1;
+ int nPoOrig, nPoFinal, nStored;
+ int i, k;
+ // check that the PO functions are correct
+ nPoFinal = Abc_NtkPoNum(pFraig);
+ nStored = Abc_FrameReadNtkStoreSize(Abc_FrameGetGlobalFrame());
+ assert( nPoFinal % nStored == 0 );
+ nPoOrig = nPoFinal / nStored;
+ for ( i = 0; i < nPoOrig; i++ )
+ {
+ pNode0 = Abc_ObjFanin0( Abc_NtkPo(pFraig, i) );
+ for ( k = 1; k < nStored; k++ )
+ {
+ pNode1 = Abc_ObjFanin0( Abc_NtkPo(pFraig, k*nPoOrig+i) );
+ if ( pNode0 != pNode1 )
+ printf( "Verification for PO #%d of network #%d has failed. The PO function is not used.\n", i+1, k+1 );
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcFxu.c b/src/base/abci/abcFxu.c
new file mode 100644
index 00000000..0c8994e1
--- /dev/null
+++ b/src/base/abci/abcFxu.c
@@ -0,0 +1,259 @@
+/**CFile****************************************************************
+
+ FileName [abcFxu.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Interface with the fast extract package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcFxu.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fxu.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static bool Abc_NtkFxuCheck( Abc_Ntk_t * pNtk );
+static void Abc_NtkFxuCollectInfo( Abc_Ntk_t * pNtk, Fxu_Data_t * p );
+static void Abc_NtkFxuReconstruct( Abc_Ntk_t * pNtk, Fxu_Data_t * p );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs fast_extract on the current network.]
+
+ Description [Takes the network and the maximum number of nodes to extract.
+ Uses the concurrent double-cube and single cube divisor extraction procedure.
+ Modifies the network in the end, after extracting all nodes. Note that
+ Ntk_NetworkSweep() may increase the performance of this procedure because
+ the single-literal nodes will not be created in the sparse matrix. Returns 1
+ if the network has been changed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
+{
+ int fCheck = 1;
+
+ assert( Abc_NtkIsLogic(pNtk) );
+ // convert nodes to SOPs
+ if ( Abc_NtkIsMappedLogic(pNtk) )
+ Abc_NtkUnmap(pNtk);
+ else if ( Abc_NtkIsBddLogic(pNtk) )
+ Abc_NtkBddToSop(pNtk);
+ else
+ { // to make sure the SOPs are SCC-free
+// Abc_NtkSopToBdd(pNtk);
+// Abc_NtkBddToSop(pNtk);
+ }
+ // check if the network meets the requirements
+ if ( !Abc_NtkFxuCheck(pNtk) )
+ {
+ printf( "Abc_NtkFastExtract: Nodes have duplicated or complemented fanins. FXU is not performed.\n" );
+ return 0;
+ }
+ // sweep removes useless nodes
+ Abc_NtkCleanup( pNtk, 0 );
+ // collect information about the covers
+ Abc_NtkFxuCollectInfo( pNtk, p );
+ // call the fast extract procedure
+ if ( Fxu_FastExtract(p) > 0 )
+ {
+ // update the network
+ Abc_NtkFxuReconstruct( pNtk, p );
+ // make sure everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ printf( "Abc_NtkFastExtract: The network check has failed.\n" );
+ return 1;
+ }
+ else
+ printf( "Warning: The network has not been changed by \"fx\".\n" );
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Makes sure the nodes do not have complemented and duplicated fanins.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkFxuCheck( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode, * pFanin1, * pFanin2;
+ int n, i, k;
+ Abc_NtkForEachNode( pNtk, pNode, n )
+ {
+ Abc_ObjForEachFanin( pNode, pFanin1, i )
+ {
+ if ( Abc_ObjFaninC(pNode, i) )
+ return 0;
+ Abc_ObjForEachFanin( pNode, pFanin2, k )
+ {
+ if ( i == k )
+ continue;
+ if ( pFanin1 == pFanin2 )
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect information about the network for fast_extract.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFxuCollectInfo( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ // add information to the manager
+ p->pManSop = pNtk->pManFunc;
+ p->vSops = Vec_PtrAlloc(0);
+ p->vFanins = Vec_PtrAlloc(0);
+ p->vSopsNew = Vec_PtrAlloc(0);
+ p->vFaninsNew = Vec_PtrAlloc(0);
+ Vec_PtrFill( p->vSops, Abc_NtkObjNumMax(pNtk), NULL );
+ Vec_PtrFill( p->vFanins, Abc_NtkObjNumMax(pNtk), NULL );
+ Vec_PtrFill( p->vSopsNew, Abc_NtkObjNumMax(pNtk) + p->nNodesExt, NULL );
+ Vec_PtrFill( p->vFaninsNew, Abc_NtkObjNumMax(pNtk) + p->nNodesExt, NULL );
+ // add SOPs and fanin array
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( Abc_SopGetVarNum(pNode->pData) < 2 )
+ continue;
+ if ( Abc_SopGetCubeNum(pNode->pData) < 1 )
+ continue;
+ p->vSops->pArray[i] = pNode->pData;
+ p->vFanins->pArray[i] = &pNode->vFanins;
+ }
+ p->nNodesOld = Abc_NtkObjNumMax(pNtk);
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFxuFreeInfo( Fxu_Data_t * p )
+{
+ int i;
+ // free the arrays of new fanins
+ if ( p->vFaninsNew )
+ for ( i = 0; i < p->vFaninsNew->nSize; i++ )
+ if ( p->vFaninsNew->pArray[i] )
+ Vec_IntFree( p->vFaninsNew->pArray[i] );
+ // free the arrays
+ if ( p->vSops ) Vec_PtrFree( p->vSops );
+ if ( p->vSopsNew ) Vec_PtrFree( p->vSopsNew );
+ if ( p->vFanins ) Vec_PtrFree( p->vFanins );
+ if ( p->vFaninsNew ) Vec_PtrFree( p->vFaninsNew );
+ FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recostructs the network after FX.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFxuReconstruct( Abc_Ntk_t * pNtk, Fxu_Data_t * p )
+{
+ Vec_Int_t * vFanins;
+ Abc_Obj_t * pNode, * pFanin;
+ int i, k;
+
+ assert( p->vFanins->nSize < p->vFaninsNew->nSize );
+ // create the new nodes
+ for ( i = p->vFanins->nSize; i < p->vFanins->nSize + p->nNodesNew; i++ )
+ {
+ // start the node
+ pNode = Abc_NtkCreateNode( pNtk );
+ assert( i == (int)pNode->Id );
+ }
+ // update the old nodes
+ for ( i = 0; i < p->vFanins->nSize; i++ )
+ {
+ // the new array of fanins
+ vFanins = p->vFaninsNew->pArray[i];
+ if ( vFanins == NULL )
+ continue;
+ // remove old fanins
+ pNode = Abc_NtkObj( pNtk, i );
+ Abc_ObjRemoveFanins( pNode );
+ // add new fanins
+ vFanins = p->vFaninsNew->pArray[i];
+ for ( k = 0; k < vFanins->nSize; k++ )
+ {
+ pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] );
+ Abc_ObjAddFanin( pNode, pFanin );
+ }
+ pNode->pData = p->vSopsNew->pArray[i];
+ assert( pNode->pData != NULL );
+ }
+ // set up the new nodes
+ for ( i = p->vFanins->nSize; i < p->vFanins->nSize + p->nNodesNew; i++ )
+ {
+ // get the new node
+ pNode = Abc_NtkObj( pNtk, i );
+ // add the fanins
+ vFanins = p->vFaninsNew->pArray[i];
+ for ( k = 0; k < vFanins->nSize; k++ )
+ {
+ pFanin = Abc_NtkObj( pNtk, vFanins->pArray[k] );
+ Abc_ObjAddFanin( pNode, pFanin );
+ }
+ pNode->pData = p->vSopsNew->pArray[i];
+ assert( pNode->pData != NULL );
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c
new file mode 100644
index 00000000..45f600ed
--- /dev/null
+++ b/src/base/abci/abcMap.c
@@ -0,0 +1,689 @@
+/**CFile****************************************************************
+
+ FileName [abcMap.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Interface with the SC mapping package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "main.h"
+#include "mio.h"
+#include "mapper.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose );
+static Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
+static Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
+static Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase );
+static Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis );
+
+static Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk );
+static void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
+static void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase );
+static Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis );
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Interface with the mapping package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fSwitching, int fVerbose )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+ Map_Man_t * pMan;
+ Vec_Int_t * vSwitching;
+ float * pSwitching = NULL;
+ int fShowSwitching = 0;
+ int clk;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // check that the library is available
+ if ( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) == NULL )
+ {
+ printf( "The current library is not available.\n" );
+ return 0;
+ }
+
+ // derive the supergate library
+ if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) == NULL && Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) )
+ {
+ printf( "A simple supergate library is derived from gate library \"%s\".\n",
+ Mio_LibraryReadName(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) );
+ Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
+ }
+
+ // print a warning about choice nodes
+ if ( Abc_NtkGetChoiceNum( pNtk ) )
+ printf( "Performing mapping with choices.\n" );
+
+ // compute switching activity
+ fShowSwitching |= fSwitching;
+ if ( fShowSwitching )
+ {
+ extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns );
+ vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 );
+ pSwitching = (float *)vSwitching->pArray;
+ }
+
+ // perform the mapping
+ pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, pSwitching, fVerbose );
+ if ( pSwitching ) Vec_IntFree( vSwitching );
+ if ( pMan == NULL )
+ return NULL;
+clk = clock();
+ Map_ManSetSwitching( pMan, fSwitching );
+ if ( !Map_Mapping( pMan ) )
+ {
+ Map_ManFree( pMan );
+ return NULL;
+ }
+ Map_ManPrintStatsToFile( pNtk->pSpec, Map_ManReadAreaFinal(pMan), Map_ManReadRequiredGlo(pMan), clock()-clk );
+
+ // reconstruct the network after mapping
+ pNtkNew = Abc_NtkFromMap( pMan, pNtk );
+ if ( pNtkNew == NULL )
+ return NULL;
+ Map_ManFree( pMan );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkMap: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Load the network into manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose )
+{
+ Map_Man_t * pMan;
+ ProgressBar * pProgress;
+ Map_Node_t * pNodeMap;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pFanin, * pPrev;
+ int i;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // start the mapping manager and set its parameters
+ pMan = Map_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk), Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk), fVerbose );
+ if ( pMan == NULL )
+ return NULL;
+ Map_ManSetAreaRecovery( pMan, fRecovery );
+ Map_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
+ Map_ManSetDelayTarget( pMan, (float)DelayTarget );
+ Map_ManSetInputArrivals( pMan, (Map_Time_t *)Abc_NtkGetCiArrivalTimes(pNtk) );
+
+ // create PIs and remember them in the old nodes
+ Abc_NtkCleanCopy( pNtk );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ {
+ pNodeMap = Map_ManReadInputs(pMan)[i];
+ pNode->pCopy = (Abc_Obj_t *)pNodeMap;
+ if ( pSwitching )
+ Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
+ }
+
+ // load the AIG into the mapper
+ vNodes = Abc_AigDfs( pNtk, 0, 0 );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // consider the case of a constant
+ if ( Abc_NodeIsConst(pNode) )
+ {
+ Abc_AigConst1(pNtk->pManFunc)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan);
+ continue;
+ }
+ // add the node to the mapper
+ pNodeMap = Map_NodeAnd( pMan,
+ Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ),
+ Map_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) );
+ assert( pNode->pCopy == NULL );
+ // remember the node
+ pNode->pCopy = (Abc_Obj_t *)pNodeMap;
+ if ( pSwitching )
+ Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
+ // set up the choice node
+ if ( Abc_NodeIsAigChoice( pNode ) )
+ for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
+ {
+ Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy );
+ Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy );
+ }
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+
+ // set the primary outputs in the required phase
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Map_ManReadOutputs(pMan)[i] = Map_NotCond( (Map_Node_t *)Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
+ return pMan;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the mapped network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew;
+ Map_Node_t * pNodeMap;
+ Abc_Obj_t * pNode, * pNodeNew;
+ int i, nDupGates;
+
+ // create the new network
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_MAP );
+ // make the mapper point to the new network
+ Map_ManCleanData( pMan );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
+ // set the constant node
+ if ( Abc_ObjFanoutNum( Abc_AigConst1(pNtk->pManFunc) ) > 0 )
+ Map_NodeSetData( Map_ManReadConst1(pMan), 1, (char *)Abc_NodeCreateConst1(pNtkNew) );
+
+ // assign the mapping of the required phase to the POs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ pNodeMap = Map_ManReadOutputs(pMan)[i];
+ pNodeNew = Abc_NodeFromMap_rec( pNtkNew, Map_Regular(pNodeMap), !Map_IsComplement(pNodeMap) );
+ assert( !Abc_ObjIsComplement(pNodeNew) );
+ Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
+ }
+ Extra_ProgressBarStop( pProgress );
+ // decouple the PO driver nodes to reduce the number of levels
+ nDupGates = Abc_NtkLogicMakeSimpleCos( pNtkNew, 1 );
+// if ( nDupGates && Map_ManReadVerbose(pMan) )
+// printf( "Duplicated %d gates to decouple the CO drivers.\n", nDupGates );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the nodes corrresponding to one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
+{
+ Abc_Obj_t * pNodeNew, * pNodeInv;
+
+ // check if the phase is already implemented
+ pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
+ if ( pNodeNew )
+ return pNodeNew;
+
+ // implement the node if the best cut is assigned
+ if ( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL )
+ return Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, fPhase );
+
+ // if the cut is not assigned, implement the node
+ assert( Map_NodeReadCutBest(pNodeMap, !fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
+ pNodeNew = Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, !fPhase );
+
+ // add the inverter
+ pNodeInv = Abc_NtkCreateNode( pNtkNew );
+ Abc_ObjAddFanin( pNodeInv, pNodeNew );
+ pNodeInv->pData = Mio_LibraryReadInv(Map_ManReadGenLib(Map_NodeReadMan(pNodeMap)));
+
+ // set the inverter
+ Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeInv );
+ return pNodeInv;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the nodes corrresponding to one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
+{
+ Abc_Obj_t * pNodePIs[10];
+ Abc_Obj_t * pNodeNew;
+ Map_Node_t ** ppLeaves;
+ Map_Cut_t * pCutBest;
+ Map_Super_t * pSuperBest;
+ unsigned uPhaseBest;
+ int i, fInvPin, nLeaves;
+
+ // make sure the node can be implemented in this phase
+ assert( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
+ // check if the phase is already implemented
+ pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
+ if ( pNodeNew )
+ return pNodeNew;
+
+ // get the information about the best cut
+ pCutBest = Map_NodeReadCutBest( pNodeMap, fPhase );
+ pSuperBest = Map_CutReadSuperBest( pCutBest, fPhase );
+ uPhaseBest = Map_CutReadPhaseBest( pCutBest, fPhase );
+ nLeaves = Map_CutReadLeavesNum( pCutBest );
+ ppLeaves = Map_CutReadLeaves( pCutBest );
+
+ // collect the PI nodes
+ for ( i = 0; i < nLeaves; i++ )
+ {
+ fInvPin = ((uPhaseBest & (1 << i)) > 0);
+ pNodePIs[i] = Abc_NodeFromMap_rec( pNtkNew, ppLeaves[i], !fInvPin );
+ assert( pNodePIs[i] != NULL );
+ }
+
+ // implement the supergate
+ pNodeNew = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, pSuperBest, pNodePIs, nLeaves );
+ Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeNew );
+ return pNodeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the nodes corrresponding to one supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
+{
+ Mio_Gate_t * pRoot;
+ Map_Super_t ** ppFanins;
+ Abc_Obj_t * pNodeNew, * pNodeFanin;
+ int nFanins, Number, i;
+
+ // get the parameters of the supergate
+ pRoot = Map_SuperReadRoot(pSuper);
+ if ( pRoot == NULL )
+ {
+ Number = Map_SuperReadNum(pSuper);
+ if ( Number < nNodePis )
+ {
+ return pNodePis[Number];
+ }
+ else
+ {
+// assert( 0 );
+ /* It might happen that a super gate with 5 inputs is constructed that
+ * actually depends only on the first four variables; i.e the fifth is a
+ * don't care -- in that case we connect constant node for the fifth
+ * (since the cut only has 4 variables). An interesting question is what
+ * if the first variable (and not the fifth one is the redundant one;
+ * can that happen?) */
+ return Abc_NodeCreateConst0(pNtkNew);
+ }
+ }
+
+ // get information about the fanins of the supergate
+ nFanins = Map_SuperReadFaninNum( pSuper );
+ ppFanins = Map_SuperReadFanins( pSuper );
+ // create a new node with these fanins
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < nFanins; i++ )
+ {
+ pNodeFanin = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, ppFanins[i], pNodePis, nNodePis );
+ Abc_ObjAddFanin( pNodeNew, pNodeFanin );
+ }
+ pNodeNew->pData = pRoot;
+ return pNodeNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Unmaps the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkUnmap( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ char * pSop;
+ int i;
+
+ assert( Abc_NtkIsMappedLogic(pNtk) );
+ // update the functionality manager
+ assert( pNtk->pManFunc == Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
+ pNtk->pManFunc = Extra_MmFlexStart();
+ pNtk->ntkFunc = ABC_FUNC_SOP;
+ // update the nodes
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ pSop = Mio_GateReadSop(pNode->pData);
+ assert( Abc_SopGetVarNum(pSop) == Abc_ObjFaninNum(pNode) );
+ pNode->pData = Abc_SopRegister( pNtk->pManFunc, pSop );
+ }
+ return 1;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Interface with the mapping package.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+
+ Map_Man_t * pMan;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // check that the library is available
+ if ( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) == NULL )
+ {
+ printf( "The current library is not available.\n" );
+ return 0;
+ }
+
+ // derive the supergate library
+ if ( Abc_FrameReadLibSuper(Abc_FrameGetGlobalFrame()) == NULL && Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) )
+ {
+ printf( "A simple supergate library is derived from gate library \"%s\".\n",
+ Mio_LibraryReadName(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) );
+ Map_SuperLibDeriveFromGenlib( Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()) );
+ }
+
+ // print a warning about choice nodes
+ if ( Abc_NtkGetChoiceNum( pNtk ) )
+ printf( "Performing mapping with choices.\n" );
+
+ // perform the mapping
+ pMan = Abc_NtkToMap( pNtk, -1, 1, NULL, 0 );
+ if ( pMan == NULL )
+ return NULL;
+ if ( !Map_Mapping( pMan ) )
+ {
+ Map_ManFree( pMan );
+ return NULL;
+ }
+
+ // reconstruct the network after mapping
+ pNtkNew = Abc_NtkFromMapSuperChoice( pMan, pNtk );
+ if ( pNtkNew == NULL )
+ return NULL;
+ Map_ManFree( pMan );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkMap: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates the mapped network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFromMapSuperChoice( Map_Man_t * pMan, Abc_Ntk_t * pNtk )
+{
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkNew, * pNtkNew2;
+ Abc_Obj_t * pNode;
+ int i;
+
+ // save the pointer to the mapped nodes
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ pNode->pNext = pNode->pCopy;
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ pNode->pNext = pNode->pCopy;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ pNode->pNext = pNode->pCopy;
+
+ // duplicate the network
+ pNtkNew2 = Abc_NtkDup( pNtk );
+ pNtkNew = Abc_NtkRenode( pNtkNew2, 0, 20, 0, 0, 1 );
+ Abc_NtkBddToSop( pNtkNew );
+
+ // set the old network to point to the new network
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ pNode->pCopy = pNode->pCopy->pCopy;
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ pNode->pCopy = pNode->pCopy->pCopy;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ pNode->pCopy = pNode->pCopy->pCopy;
+ Abc_NtkDelete( pNtkNew2 );
+
+ // set the pointers from the mapper to the new nodes
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ {
+ Map_NodeSetData( Map_ManReadInputs(pMan)[i], 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
+ Map_NodeSetData( Map_ManReadInputs(pMan)[i], 1, (char *)pNode->pCopy );
+ }
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ Map_NodeSetData( (Map_Node_t *)pNode->pNext, 0, (char *)Abc_NodeCreateInv(pNtkNew,pNode->pCopy) );
+ Map_NodeSetData( (Map_Node_t *)pNode->pNext, 1, (char *)pNode->pCopy );
+ }
+
+ // assign the mapping of the required phase to the POs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkObjNumMax(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ Abc_NodeSuperChoice( pNtkNew, pNode );
+ }
+ Extra_ProgressBarStop( pProgress );
+ return pNtkNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates the mapped network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeSuperChoice( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
+{
+ Map_Node_t * pMapNode = (Map_Node_t *)pNode->pNext;
+ Map_Cut_t * pCuts, * pTemp;
+
+ pCuts = Map_NodeReadCuts(pMapNode);
+ for ( pTemp = Map_CutReadNext(pCuts); pTemp; pTemp = Map_CutReadNext(pTemp) )
+ {
+ Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 0 );
+ Abc_NodeFromMapCutPhase( pNtkNew, pTemp, 1 );
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the nodes corrresponding to one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeFromMapCutPhase( Abc_Ntk_t * pNtkNew, Map_Cut_t * pCut, int fPhase )
+{
+ Abc_Obj_t * pNodePIs[10];
+ Map_Node_t ** ppLeaves;
+ Map_Super_t * pSuperBest;
+ unsigned uPhaseBest;
+ int i, fInvPin, nLeaves;
+
+ pSuperBest = Map_CutReadSuperBest( pCut, fPhase );
+ if ( pSuperBest == NULL )
+ return;
+
+ // get the information about the best cut
+ uPhaseBest = Map_CutReadPhaseBest( pCut, fPhase );
+ nLeaves = Map_CutReadLeavesNum( pCut );
+ ppLeaves = Map_CutReadLeaves( pCut );
+
+ // collect the PI nodes
+ for ( i = 0; i < nLeaves; i++ )
+ {
+ fInvPin = ((uPhaseBest & (1 << i)) > 0);
+ pNodePIs[i] = (Abc_Obj_t *)Map_NodeReadData( ppLeaves[i], !fInvPin );
+ assert( pNodePIs[i] != NULL );
+ }
+
+ // implement the supergate
+ Abc_NodeFromMapSuperChoice_rec( pNtkNew, pSuperBest, pNodePIs, nLeaves );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the nodes corrresponding to one supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
+{
+ Mio_Gate_t * pRoot;
+ Map_Super_t ** ppFanins;
+ Abc_Obj_t * pNodeNew, * pNodeFanin;
+ int nFanins, Number, i;
+
+ // get the parameters of the supergate
+ pRoot = Map_SuperReadRoot(pSuper);
+ if ( pRoot == NULL )
+ {
+ Number = Map_SuperReadNum(pSuper);
+ if ( Number < nNodePis )
+ {
+ return pNodePis[Number];
+ }
+ else
+ {
+// assert( 0 );
+ /* It might happen that a super gate with 5 inputs is constructed that
+ * actually depends only on the first four variables; i.e the fifth is a
+ * don't care -- in that case we connect constant node for the fifth
+ * (since the cut only has 4 variables). An interesting question is what
+ * if the first variable (and not the fifth one is the redundant one;
+ * can that happen?) */
+ return Abc_NodeCreateConst0(pNtkNew);
+ }
+ }
+
+ // get information about the fanins of the supergate
+ nFanins = Map_SuperReadFaninNum( pSuper );
+ ppFanins = Map_SuperReadFanins( pSuper );
+ // create a new node with these fanins
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < nFanins; i++ )
+ {
+ pNodeFanin = Abc_NodeFromMapSuperChoice_rec( pNtkNew, ppFanins[i], pNodePis, nNodePis );
+ Abc_ObjAddFanin( pNodeNew, pNodeFanin );
+ }
+ pNodeNew->pData = Abc_SopRegister( pNtkNew->pManFunc, Mio_GateReadSop(pRoot) );
+ return pNodeNew;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c
new file mode 100644
index 00000000..0d75ba1f
--- /dev/null
+++ b/src/base/abci/abcMiter.c
@@ -0,0 +1,600 @@
+/**CFile****************************************************************
+
+ FileName [abcMiter.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures to derive the miter of two circuits.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcMiter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
+static void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb );
+static void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter );
+static void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pNode );
+static void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb );
+static void Abc_NtkAddFrame( Abc_Ntk_t * pNetNew, Abc_Ntk_t * pNet, int iFrame, Vec_Ptr_t * vNodes );
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Derives the miter of two networks.]
+
+ Description [Preprocesses the networks to make sure that they are strashed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkMiter( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
+{
+ Abc_Ntk_t * pTemp = NULL;
+ int fRemove1, fRemove2;
+ // check that the networks have the same PIs/POs/latches
+ if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, fComb ) )
+ return NULL;
+ // make sure the circuits are strashed
+ fRemove1 = (!Abc_NtkIsStrash(pNtk1)) && (pNtk1 = Abc_NtkStrash(pNtk1, 0, 0));
+ fRemove2 = (!Abc_NtkIsStrash(pNtk2)) && (pNtk2 = Abc_NtkStrash(pNtk2, 0, 0));
+ if ( pNtk1 && pNtk2 )
+ pTemp = Abc_NtkMiterInt( pNtk1, pNtk2, fComb );
+ if ( fRemove1 ) Abc_NtkDelete( pNtk1 );
+ if ( fRemove2 ) Abc_NtkDelete( pNtk2 );
+ return pTemp;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the miter of two sequential networks.]
+
+ Description [Assumes that the networks are strashed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkMiterInt( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
+{
+ int fCheck = 1;
+ char Buffer[100];
+ Abc_Ntk_t * pNtkMiter;
+
+ assert( Abc_NtkIsStrash(pNtk1) );
+ assert( Abc_NtkIsStrash(pNtk2) );
+
+ // start the new network
+ pNtkMiter = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG );
+ sprintf( Buffer, "%s_%s_miter", pNtk1->pName, pNtk2->pName );
+ pNtkMiter->pName = util_strsav(Buffer);
+
+ // perform strashing
+ Abc_NtkMiterPrepare( pNtk1, pNtk2, pNtkMiter, fComb );
+ Abc_NtkMiterAddOne( pNtk1, pNtkMiter );
+ Abc_NtkMiterAddOne( pNtk2, pNtkMiter );
+ Abc_NtkMiterFinalize( pNtk1, pNtk2, pNtkMiter, fComb );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkMiter ) )
+ {
+ printf( "Abc_NtkMiter: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkMiter );
+ return NULL;
+ }
+ return pNtkMiter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the network for mitering.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMiterPrepare( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb )
+{
+ Abc_Obj_t * pObj, * pObjNew;
+ int i;
+ // clean the copy field in all objects
+// Abc_NtkCleanCopy( pNtk1 );
+// Abc_NtkCleanCopy( pNtk2 );
+ if ( fComb )
+ {
+ // create new PIs and remember them in the old PIs
+ Abc_NtkForEachCi( pNtk1, pObj, i )
+ {
+ pObjNew = Abc_NtkCreatePi( pNtkMiter );
+ // remember this PI in the old PIs
+ pObj->pCopy = pObjNew;
+ pObj = Abc_NtkCi(pNtk2, i);
+ pObj->pCopy = pObjNew;
+ // add name
+ Abc_NtkLogicStoreName( pObjNew, Abc_ObjName(pObj) );
+ }
+ // create the only PO
+ pObjNew = Abc_NtkCreatePo( pNtkMiter );
+ // add the PO name
+ Abc_NtkLogicStoreName( pObjNew, "miter" );
+ }
+ else
+ {
+ // create new PIs and remember them in the old PIs
+ Abc_NtkForEachPi( pNtk1, pObj, i )
+ {
+ pObjNew = Abc_NtkCreatePi( pNtkMiter );
+ // remember this PI in the old PIs
+ pObj->pCopy = pObjNew;
+ pObj = Abc_NtkPi(pNtk2, i);
+ pObj->pCopy = pObjNew;
+ // add name
+ Abc_NtkLogicStoreName( pObjNew, Abc_ObjName(pObj) );
+ }
+ // create the only PO
+ pObjNew = Abc_NtkCreatePo( pNtkMiter );
+ // add the PO name
+ Abc_NtkLogicStoreName( pObjNew, "miter" );
+ // create the latches
+ Abc_NtkForEachLatch( pNtk1, pObj, i )
+ {
+ pObjNew = Abc_NtkDupObj( pNtkMiter, pObj );
+ Vec_PtrPush( pNtkMiter->vCis, pObjNew );
+ Vec_PtrPush( pNtkMiter->vCos, pObjNew );
+ // add name
+ Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_1" );
+ }
+ Abc_NtkForEachLatch( pNtk2, pObj, i )
+ {
+ pObjNew = Abc_NtkDupObj( pNtkMiter, pObj );
+ Vec_PtrPush( pNtkMiter->vCis, pObjNew );
+ Vec_PtrPush( pNtkMiter->vCos, pObjNew );
+ // add name
+ Abc_NtkLogicStoreNamePlus( pObjNew, Abc_ObjName(pObj), "_2" );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs mitering for one network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMiterAddOne( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter )
+{
+ ProgressBar * pProgress;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pConst1, * pConst1New;
+ int i;
+ // get the constant nodes
+ pConst1 = Abc_AigConst1( pNtk->pManFunc );
+ pConst1New = Abc_AigConst1( pNtkMiter->pManFunc );
+ // perform strashing
+ vNodes = Abc_NtkDfs( pNtk, 0 );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ if ( pNode == pConst1 )
+ pNode->pCopy = pConst1New;
+ else
+ pNode->pCopy = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
+ }
+ Vec_PtrFree( vNodes );
+ Extra_ProgressBarStop( pProgress );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs mitering for one network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMiterAddCone( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkMiter, Abc_Obj_t * pRoot )
+{
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pNodeNew, * pConst1, * pConst1New;
+ int i;
+ // get the constant nodes
+ pConst1 = Abc_AigConst1( pNtk->pManFunc );
+ pConst1New = Abc_AigConst1( pNtkMiter->pManFunc );
+ // perform strashing
+ vNodes = Abc_NtkDfsNodes( pNtk, &pRoot, 1 );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ pNode = vNodes->pArray[i];
+ if ( pNode == pConst1 )
+ pNodeNew = pConst1New;
+ else
+ pNodeNew = Abc_AigAnd( pNtkMiter->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
+ pNode->pCopy = pNodeNew;
+ }
+ Vec_PtrFree( vNodes );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Finalizes the miter by adding the output part.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMiterFinalize( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, Abc_Ntk_t * pNtkMiter, int fComb )
+{
+ Vec_Ptr_t * vPairs;
+ Abc_Obj_t * pMiter, * pNode;
+ int i;
+ // collect the PO pairs from both networks
+ vPairs = Vec_PtrAlloc( 100 );
+ if ( fComb )
+ {
+ // collect the CO nodes for the miter
+ Abc_NtkForEachCo( pNtk1, pNode, i )
+ {
+ Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) );
+ pNode = Abc_NtkCo( pNtk2, i );
+ Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) );
+ }
+ }
+ else
+ {
+ // collect the PO nodes for the miter
+ Abc_NtkForEachPo( pNtk1, pNode, i )
+ {
+ Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) );
+ pNode = Abc_NtkPo( pNtk2, i );
+ Vec_PtrPush( vPairs, Abc_ObjChild0Copy(pNode) );
+ }
+ // connect new latches
+ Abc_NtkForEachLatch( pNtk1, pNode, i )
+ Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) );
+ Abc_NtkForEachLatch( pNtk2, pNode, i )
+ Abc_ObjAddFanin( pNode->pCopy, Abc_ObjChild0Copy(pNode) );
+ }
+ // add the miter
+ pMiter = Abc_AigMiter( pNtkMiter->pManFunc, vPairs );
+ Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter );
+ Vec_PtrFree( vPairs );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives the miter of two cofactors of one output.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkMiterForCofactors( Abc_Ntk_t * pNtk, int Out, int In1, int In2 )
+{
+ int fCheck = 1;
+ char Buffer[100];
+ Abc_Ntk_t * pNtkMiter;
+ Abc_Obj_t * pRoot, * pOutput1, * pOutput2, * pMiter;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( Out < Abc_NtkCoNum(pNtk) );
+ assert( In1 < Abc_NtkCiNum(pNtk) );
+ assert( In2 < Abc_NtkCiNum(pNtk) );
+
+ // start the new network
+ pNtkMiter = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG );
+ sprintf( Buffer, "%s_miter", Abc_ObjName(Abc_NtkCo(pNtk, Out)) );
+ pNtkMiter->pName = util_strsav(Buffer);
+
+ // get the root output
+ pRoot = Abc_NtkCo( pNtk, Out );
+
+ // perform strashing
+ Abc_NtkMiterPrepare( pNtk, pNtk, pNtkMiter, 1 );
+ // set the first cofactor
+ Abc_NtkCi(pNtk, In1)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) );
+ if ( In2 >= 0 )
+ Abc_NtkCi(pNtk, In2)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc );
+ // add the first cofactor
+ Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
+
+ // save the output
+ pOutput1 = Abc_ObjFanin0(pRoot)->pCopy;
+
+ // set the second cofactor
+ Abc_NtkCi(pNtk, In1)->pCopy = Abc_AigConst1( pNtkMiter->pManFunc );
+ if ( In2 >= 0 )
+ Abc_NtkCi(pNtk, In2)->pCopy = Abc_ObjNot( Abc_AigConst1(pNtkMiter->pManFunc) );
+ // add the second cofactor
+ Abc_NtkMiterAddCone( pNtk, pNtkMiter, pRoot );
+
+ // save the output
+ pOutput2 = Abc_ObjFanin0(pRoot)->pCopy;
+
+ // create the miter of the two outputs
+ pMiter = Abc_AigXor( pNtkMiter->pManFunc, pOutput1, pOutput2 );
+ Abc_ObjAddFanin( Abc_NtkPo(pNtkMiter,0), pMiter );
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkMiter ) )
+ {
+ printf( "Abc_NtkMiter: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkMiter );
+ return NULL;
+ }
+ return pNtkMiter;
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Checks the status of the miter.]
+
+ Description [Return 1 if the miter is sat for at least one output.
+ Return 0 if the miter is unsat for all its outputs. Returns -1 if the
+ miter is undecided for some outputs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkMiterIsConstant( Abc_Ntk_t * pMiter )
+{
+ Abc_Obj_t * pNodePo, * pChild;
+ int i;
+ assert( Abc_NtkIsStrash(pMiter) );
+ Abc_NtkForEachPo( pMiter, pNodePo, i )
+ {
+ pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) );
+ if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) )
+ {
+ assert( Abc_ObjRegular(pChild) == Abc_AigConst1(pMiter->pManFunc) );
+ if ( !Abc_ObjIsComplement(pChild) )
+ {
+ // if the miter is constant 1, return immediately
+ printf( "MITER IS CONSTANT 1!\n" );
+ return 1;
+ }
+ }
+ // if the miter is undecided (or satisfiable), return immediately
+ else
+ return -1;
+ }
+ // return 0, meaning all outputs are constant zero
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reports the status of the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkMiterReport( Abc_Ntk_t * pMiter )
+{
+ Abc_Obj_t * pChild, * pNode;
+ int i;
+ if ( Abc_NtkPoNum(pMiter) == 1 )
+ {
+ pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,0) );
+ if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) )
+ {
+ if ( Abc_ObjIsComplement(pChild) )
+ printf( "Unsatisfiable.\n" );
+ else
+ printf( "Satisfiable. (Constant 1).\n" );
+ }
+ else
+ printf( "Satisfiable.\n" );
+ }
+ else
+ {
+ Abc_NtkForEachPo( pMiter, pNode, i )
+ {
+ pChild = Abc_ObjChild0( Abc_NtkPo(pMiter,i) );
+ printf( "Output #%2d : ", i );
+ if ( Abc_ObjIsNode(Abc_ObjRegular(pChild)) && Abc_NodeIsConst(pChild) )
+ {
+ if ( Abc_ObjIsComplement(pChild) )
+ printf( "Unsatisfiable.\n" );
+ else
+ printf( "Satisfiable. (Constant 1).\n" );
+ }
+ else
+ printf( "Satisfiable.\n" );
+ }
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives the timeframes of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial )
+{
+ int fCheck = 1;
+ char Buffer[100];
+ ProgressBar * pProgress;
+ Abc_Ntk_t * pNtkFrames;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pLatch, * pLatchNew;
+ int i, Counter;
+ assert( nFrames > 0 );
+ assert( Abc_NtkIsStrash(pNtk) );
+ // start the new network
+ pNtkFrames = Abc_NtkAlloc( ABC_TYPE_STRASH, ABC_FUNC_AIG );
+ sprintf( Buffer, "%s_%d_frames", pNtk->pName, nFrames );
+ pNtkFrames->pName = util_strsav(Buffer);
+ // create new latches (or their initial values) and remember them in the new latches
+ if ( !fInitial )
+ {
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ Abc_NtkDupObj( pNtkFrames, pLatch );
+ }
+ else
+ {
+ Counter = 0;
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ {
+ if ( Abc_LatchIsInitDc(pLatch) ) // don't-care initial value - create a new PI
+ {
+ pLatch->pCopy = Abc_NtkCreatePi(pNtkFrames);
+ Abc_NtkLogicStoreName( pLatch->pCopy, Abc_ObjName(pLatch) );
+ Counter++;
+ }
+ else
+ pLatch->pCopy = Abc_ObjNotCond( Abc_AigConst1(pNtkFrames->pManFunc), Abc_LatchIsInit0(pLatch) );
+ }
+ if ( Counter )
+ printf( "Warning: %d uninitialized latches are replaced by free variables.\n", Counter );
+ }
+
+ // create the timeframes
+ vNodes = Abc_NtkDfs( pNtk, 0 );
+ pProgress = Extra_ProgressBarStart( stdout, nFrames );
+ for ( i = 0; i < nFrames; i++ )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ Abc_NtkAddFrame( pNtkFrames, pNtk, i, vNodes );
+ }
+ Extra_ProgressBarStop( pProgress );
+ Vec_PtrFree( vNodes );
+
+ // connect the new latches to the outputs of the last frame
+ if ( !fInitial )
+ {
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ {
+ pLatchNew = Abc_NtkLatch(pNtkFrames, i);
+ Abc_ObjAddFanin( pLatchNew, Abc_ObjFanin0(pLatch)->pCopy );
+ Vec_PtrPush( pNtkFrames->vCis, pLatchNew );
+ Vec_PtrPush( pNtkFrames->vCos, pLatchNew );
+ Abc_NtkLogicStoreName( pLatchNew, Abc_ObjName(pLatch) );
+ }
+ }
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkFrames ) )
+ {
+ printf( "Abc_NtkFrames: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkFrames );
+ return NULL;
+ }
+ return pNtkFrames;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds one time frame to the new network.]
+
+ Description [Assumes that the latches of the old network point
+ to the outputs of the previous frame of the new network (pLatch->pCopy).
+ In the end, updates the latches of the old network to point to the
+ outputs of the current frame of the new network.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkAddFrame( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec_Ptr_t * vNodes )
+{
+ char Buffer[10];
+ Abc_Obj_t * pNode, * pNodeNew, * pLatch;
+ Abc_Obj_t * pConst1, * pConst1New;
+ int i;
+ // get the constant nodes
+ pConst1 = Abc_AigConst1( pNtk->pManFunc );
+ pConst1New = Abc_AigConst1( pNtkFrames->pManFunc );
+ // create the prefix to be added to the node names
+ sprintf( Buffer, "_%02d", iFrame );
+ // add the new PI nodes
+ Abc_NtkForEachPi( pNtk, pNode, i )
+ {
+ pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode );
+ Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer );
+ }
+ // add the internal nodes
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ if ( pNode == pConst1 )
+ pNodeNew = pConst1New;
+ else
+ pNodeNew = Abc_AigAnd( pNtkFrames->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
+ pNode->pCopy = pNodeNew;
+ }
+ // add the new POs
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ {
+ pNodeNew = Abc_NtkDupObj( pNtkFrames, pNode );
+ Abc_ObjAddFanin( pNodeNew, Abc_ObjChild0Copy(pNode) );
+ Abc_NtkLogicStoreNamePlus( pNodeNew, Abc_ObjName(pNode), Buffer );
+ }
+ // transfer the implementation of the latch drivers to the latches
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ pLatch->pCopy = Abc_ObjChild0Copy(pLatch);
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c
new file mode 100644
index 00000000..61c1a110
--- /dev/null
+++ b/src/base/abci/abcNtbdd.c
@@ -0,0 +1,402 @@
+/**CFile****************************************************************
+
+ FileName [abcNtbdd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures to translate between the BDD and the network.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcNtbdd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+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, Abc_Obj_t * pConst1 );
+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 );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Constructs the network isomorphic to the given BDD.]
+
+ Description [Assumes that the BDD depends on the variables whose indexes
+ correspond to the names in the array (pNamesPi). Otherwise, returns NULL.
+ The resulting network comes with one node, whose functionality is
+ equal to the given BDD. To decompose this BDD into the network of
+ multiplexers use Abc_NtkBddToMuxes(). To decompose this BDD into
+ an And-Inverter Graph, use Abc_NtkStrash().]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkDeriveFromBdd( DdManager * dd, DdNode * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi )
+{
+ Abc_Ntk_t * pNtk;
+ Vec_Ptr_t * vNamesPiFake = NULL;
+ Abc_Obj_t * pNode, * pNodePi, * pNodePo;
+ DdNode * bSupp, * bTemp;
+ char * pName;
+ int i;
+
+ // supply fake names if real names are not given
+ if ( pNamePo == NULL )
+ pNamePo = "F";
+ if ( vNamesPi == NULL )
+ {
+ vNamesPiFake = Abc_NodeGetFakeNames( dd->size );
+ vNamesPi = vNamesPiFake;
+ }
+
+ // make sure BDD depends on the variables whose index
+ // does not exceed the size of the array with PI names
+ bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp );
+ for ( bTemp = bSupp; bTemp != Cudd_ReadOne(dd); bTemp = cuddT(bTemp) )
+ if ( (int)Cudd_NodeReadIndex(bTemp) >= Vec_PtrSize(vNamesPi) )
+ break;
+ Cudd_RecursiveDeref( dd, bSupp );
+ if ( bTemp != Cudd_ReadOne(dd) )
+ return NULL;
+
+ // start the network
+ pNtk = Abc_NtkAlloc( ABC_TYPE_LOGIC, ABC_FUNC_BDD );
+ pNtk->pName = util_strsav(pNamePo);
+ // make sure the new manager has enough inputs
+ Cudd_bddIthVar( pNtk->pManFunc, Vec_PtrSize(vNamesPi) );
+ // add the PIs corresponding to the names
+ Vec_PtrForEachEntry( vNamesPi, pName, i )
+ Abc_NtkLogicStoreName( Abc_NtkCreatePi(pNtk), pName );
+ // create the node
+ pNode = Abc_NtkCreateNode( pNtk );
+ pNode->pData = Cudd_bddTransfer( dd, pNtk->pManFunc, bFunc ); Cudd_Ref(pNode->pData);
+ Abc_NtkForEachPi( pNtk, pNodePi, i )
+ Abc_ObjAddFanin( pNode, pNodePi );
+ // create the only PO
+ pNodePo = Abc_NtkCreatePo( pNtk );
+ Abc_ObjAddFanin( pNodePo, pNode );
+ Abc_NtkLogicStoreName( pNodePo, pNamePo );
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtk );
+ if ( vNamesPiFake )
+ Abc_NodeFreeNames( vNamesPiFake );
+ if ( !Abc_NtkCheck( pNtk ) )
+ fprintf( stdout, "Abc_NtkDeriveFromBdd(): Network check has failed.\n" );
+ return pNtk;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates the network isomorphic to the union of local BDDs of the nodes.]
+
+ Description [The nodes of the local BDDs are converted into the network nodes
+ with logic functions equal to the MUX.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+ assert( Abc_NtkIsBddLogic(pNtk) );
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_SOP );
+ Abc_NtkBddToMuxesPerform( pNtk, pNtkNew );
+ Abc_NtkFinalize( pNtk, pNtkNew );
+ // make sure everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkBddToMuxes: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the network to MUXes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
+{
+ ProgressBar * pProgress;
+ DdManager * dd = pNtk->pManFunc;
+ Abc_Obj_t * pNode, * pNodeNew, * pConst1;
+ Vec_Ptr_t * vNodes;
+ int i;
+ // create the constant one node
+ pConst1 = Abc_NodeCreateConst1( pNtkNew );
+ // perform conversion in the topological order
+ vNodes = Abc_NtkDfs( pNtk, 0 );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // convert one node
+ assert( Abc_ObjIsNode(pNode) );
+ pNodeNew = Abc_NodeBddToMuxes( pNode, pNtkNew, pConst1 );
+ // mark the old node with the new one
+ assert( pNode->pCopy == NULL );
+ pNode->pCopy = pNodeNew;
+ }
+ Vec_PtrFree( vNodes );
+ Extra_ProgressBarStop( pProgress );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the node to MUXes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew, Abc_Obj_t * pConst1 )
+{
+ DdManager * dd = pNodeOld->pNtk->pManFunc;
+ DdNode * bFunc = pNodeOld->pData;
+ Abc_Obj_t * pFaninOld, * pNodeNew;
+ st_table * tBdd2Node;
+ int i;
+ // create the table mapping BDD nodes into the ABC nodes
+ tBdd2Node = st_init_table( st_ptrcmp, st_ptrhash );
+ // add the constant and the elementary vars
+ st_insert( tBdd2Node, (char *)b1, (char *)pConst1 );
+ Abc_ObjForEachFanin( pNodeOld, pFaninOld, i )
+ st_insert( tBdd2Node, (char *)Cudd_bddIthVar(dd, i), (char *)pFaninOld->pCopy );
+ // create the new nodes recursively
+ pNodeNew = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(bFunc), pNtkNew, tBdd2Node );
+ st_free_table( tBdd2Node );
+ if ( Cudd_IsComplement(bFunc) )
+ pNodeNew = Abc_NodeCreateInv( pNtkNew, pNodeNew );
+ return pNodeNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Converts the node to MUXes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st_table * tBdd2Node )
+{
+ Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC;
+ assert( !Cudd_IsComplement(bFunc) );
+ if ( st_lookup( tBdd2Node, (char *)bFunc, (char **)&pNodeNew ) )
+ return pNodeNew;
+ // solve for the children nodes
+ pNodeNew0 = Abc_NodeBddToMuxes_rec( dd, Cudd_Regular(cuddE(bFunc)), pNtkNew, tBdd2Node );
+ if ( Cudd_IsComplement(cuddE(bFunc)) )
+ pNodeNew0 = Abc_NodeCreateInv( pNtkNew, pNodeNew0 );
+ pNodeNew1 = Abc_NodeBddToMuxes_rec( dd, cuddT(bFunc), pNtkNew, tBdd2Node );
+ if ( !st_lookup( tBdd2Node, (char *)Cudd_bddIthVar(dd, bFunc->index), (char **)&pNodeNewC ) )
+ assert( 0 );
+ // create the MUX node
+ pNodeNew = Abc_NodeCreateMux( pNtkNew, pNodeNewC, pNodeNew1, pNodeNew0 );
+ st_insert( tBdd2Node, (char *)bFunc, (char *)pNodeNew );
+ return pNodeNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives global BDDs for the COs of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdManager * Abc_NtkGlobalBdds( Abc_Ntk_t * pNtk, int fLatchOnly )
+{
+ int fReorder = 1;
+ ProgressBar * pProgress;
+ Vec_Ptr_t * vFuncsGlob;
+ Abc_Obj_t * pNode;
+ DdNode * bFunc;
+ DdManager * dd;
+ int i;
+
+ // start the manager
+ assert( pNtk->pManGlob == NULL );
+ dd = Cudd_Init( Abc_NtkCiNum(pNtk), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
+ if ( fReorder )
+ Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
+
+ // set the elementary variables
+ Abc_NtkCleanCopy( pNtk );
+ Abc_NtkForEachCi( pNtk, pNode, i )
+ pNode->pCopy = (Abc_Obj_t *)dd->vars[i];
+ // assign the constant node BDD
+ pNode = Abc_AigConst1( pNtk->pManFunc );
+ pNode->pCopy = (Abc_Obj_t *)dd->one; Cudd_Ref( dd->one );
+
+ // collect the global functions of the COs
+ vFuncsGlob = Vec_PtrAlloc( 100 );
+ if ( fLatchOnly )
+ {
+ // construct the BDDs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkLatchNum(pNtk) );
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode) );
+ if ( bFunc == NULL )
+ {
+ printf( "Constructing global BDDs timed out.\n" );
+ Extra_ProgressBarStop( pProgress );
+ Cudd_Quit( dd );
+ return NULL;
+ }
+ bFunc = Cudd_NotCond( bFunc, Abc_ObjFaninC0(pNode) ); Cudd_Ref( bFunc );
+ Vec_PtrPush( vFuncsGlob, bFunc );
+ }
+ Extra_ProgressBarStop( pProgress );
+ }
+ else
+ {
+ // construct the BDDs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ bFunc = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin0(pNode) );
+ if ( bFunc == NULL )
+ {
+ printf( "Constructing global BDDs timed out.\n" );
+ Extra_ProgressBarStop( pProgress );
+ Cudd_Quit( dd );
+ return NULL;
+ }
+ bFunc = Cudd_NotCond( bFunc, Abc_ObjFaninC0(pNode) ); Cudd_Ref( bFunc );
+ Vec_PtrPush( vFuncsGlob, bFunc );
+ }
+ Extra_ProgressBarStop( pProgress );
+ }
+
+ // derefence the intermediate BDDs
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ if ( pNode->pCopy )
+ {
+ Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy );
+ pNode->pCopy = NULL;
+ }
+ // reorder one more time
+ if ( fReorder )
+ {
+ Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 );
+ Cudd_AutodynDisable( dd );
+ }
+ pNtk->pManGlob = dd;
+ pNtk->vFuncsGlob = vFuncsGlob;
+ return dd;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the global BDD for one AIG node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NodeGlobalBdds_rec( DdManager * dd, Abc_Obj_t * pNode )
+{
+ DdNode * bFunc, * bFunc0, * bFunc1;
+ assert( !Abc_ObjIsComplement(pNode) );
+ if ( Cudd_ReadKeys(dd) > 500000 )
+ return NULL;
+ // if the result is available return
+ if ( pNode->pCopy )
+ return (DdNode *)pNode->pCopy;
+ // compute the result for both branches
+ bFunc0 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,0) );
+ if ( bFunc0 == NULL )
+ return NULL;
+ Cudd_Ref( bFunc0 );
+ bFunc1 = Abc_NodeGlobalBdds_rec( dd, Abc_ObjFanin(pNode,1) );
+ if ( bFunc1 == NULL )
+ return NULL;
+ Cudd_Ref( bFunc1 );
+ bFunc0 = Cudd_NotCond( bFunc0, Abc_ObjFaninC0(pNode) );
+ bFunc1 = Cudd_NotCond( bFunc1, Abc_ObjFaninC1(pNode) );
+ // get the final result
+ bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc );
+ Cudd_RecursiveDeref( dd, bFunc0 );
+ Cudd_RecursiveDeref( dd, bFunc1 );
+ // set the result
+ assert( pNode->pCopy == NULL );
+ pNode->pCopy = (Abc_Obj_t *)bFunc;
+ return bFunc;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Dereferences global BDDs of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk )
+{
+ DdNode * bFunc;
+ int i;
+ assert( pNtk->pManGlob );
+ assert( pNtk->vFuncsGlob );
+ Vec_PtrForEachEntry( pNtk->vFuncsGlob, bFunc, i )
+ Cudd_RecursiveDeref( pNtk->pManGlob, bFunc );
+ Vec_PtrFree( pNtk->vFuncsGlob );
+ pNtk->vFuncsGlob = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c
new file mode 100644
index 00000000..41b9288e
--- /dev/null
+++ b/src/base/abci/abcPrint.c
@@ -0,0 +1,505 @@
+/**CFile****************************************************************
+
+ FileName [abcPrint.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Printing statistics.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcPrint.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "dec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Print the vital stats of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
+{
+ int Num;
+
+ fprintf( pFile, "%-13s:", pNtk->pName );
+ fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );
+
+ if ( !Abc_NtkIsSeq(pNtk) )
+ fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) );
+ else
+ fprintf( pFile, " lat = %4d", Abc_NtkSeqLatchNum(pNtk) );
+
+ if ( Abc_NtkIsNetlist(pNtk) )
+ {
+ fprintf( pFile, " net = %5d", Abc_NtkNetNum(pNtk) );
+ fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) );
+ }
+ else if ( Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) );
+ if ( Num = Abc_NtkGetChoiceNum(pNtk) )
+ fprintf( pFile, " (choice = %d)", Num );
+ if ( Num = Abc_NtkGetExorNum(pNtk) )
+ fprintf( pFile, " (exor = %d)", Num );
+ }
+ else if ( Abc_NtkIsSeq(pNtk) )
+ fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) );
+ else
+ fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) );
+
+ if ( Abc_NtkHasSop(pNtk) )
+ {
+ fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) );
+// fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) );
+ if ( fFactored )
+ fprintf( pFile, " lit(fac) = %5d", Abc_NtkGetLitFactNum(pNtk) );
+ }
+ else if ( Abc_NtkHasBdd(pNtk) )
+ fprintf( pFile, " bdd = %5d", Abc_NtkGetBddNodeNum(pNtk) );
+ else if ( Abc_NtkHasMapping(pNtk) )
+ {
+ fprintf( pFile, " area = %5.2f", Abc_NtkGetMappedArea(pNtk) );
+ fprintf( pFile, " delay = %5.2f", Abc_NtkDelayTrace(pNtk) );
+ }
+ else if ( !Abc_NtkHasAig(pNtk) )
+ {
+ assert( 0 );
+ }
+
+ if ( Abc_NtkIsStrash(pNtk) )
+ fprintf( pFile, " lev = %3d", Abc_AigGetLevelNum(pNtk) );
+ else if ( !Abc_NtkIsSeq(pNtk) )
+ fprintf( pFile, " lev = %3d", Abc_NtkGetLevelNum(pNtk) );
+
+ fprintf( pFile, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints PIs/POs and LIs/LOs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ int i;
+
+ fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) );
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ fprintf( pFile, " %s", Abc_ObjName(pObj) );
+ fprintf( pFile, "\n" );
+
+ fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) );
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ fprintf( pFile, " %s", Abc_ObjName(pObj) );
+ fprintf( pFile, "\n" );
+
+ fprintf( pFile, "Latches (%d): ", Abc_NtkLatchNum(pNtk) );
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ fprintf( pFile, " %s", Abc_ObjName(pObj) );
+ fprintf( pFile, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints statistics about latches.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pLatch, * pFanin;
+ int i, Counter0, Counter1, Counter2;
+ int Init0, Init1, Init2;
+
+ if ( Abc_NtkLatchNum(pNtk) == 0 )
+ {
+ fprintf( pFile, "The network is combinational.\n" );
+ return;
+ }
+
+ assert( !Abc_NtkIsNetlist(pNtk) );
+
+ Init0 = Init1 = Init2 = 0;
+ Counter0 = Counter1 = Counter2 = 0;
+
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ {
+ if ( Abc_LatchIsInit0(pLatch) )
+ Init0++;
+ else if ( Abc_LatchIsInit1(pLatch) )
+ Init1++;
+ else if ( Abc_LatchIsInitDc(pLatch) )
+ Init2++;
+ else
+ assert( 0 );
+
+ pFanin = Abc_ObjFanin0(pLatch);
+ if ( !Abc_ObjIsNode(pFanin) || !Abc_NodeIsConst(pFanin) )
+ continue;
+
+ // the latch input is a constant node
+ Counter0++;
+ if ( Abc_LatchIsInitDc(pLatch) )
+ {
+ Counter1++;
+ continue;
+ }
+ // count the number of cases when the constant is equal to the initial value
+ if ( Abc_NtkIsStrash(pNtk) )
+ {
+ if ( Abc_LatchIsInit1(pLatch) == !Abc_ObjFaninC0(pLatch) )
+ Counter2++;
+ }
+ else
+ {
+ if ( Abc_LatchIsInit1(pLatch) == Abc_NodeIsConst1(pLatch) )
+ Counter2++;
+ }
+ }
+// fprintf( pFile, "%-15s: ", pNtk->pName );
+// fprintf( pFile, "L = %5d: 0 = %4d. 1 = %3d. DC = %4d. ", Abc_NtkLatchNum(pNtk), Init0, Init1, Init2 );
+// fprintf( pFile, "Con = %3d. DC = %3d. Mat = %3d. ", Counter0, Counter1, Counter2 );
+// fprintf( pFile, "SFeed = %2d.\n", Abc_NtkCountSelfFeedLatches(pNtk) );
+ fprintf( pFile, "%-15s: ", pNtk->pName );
+ fprintf( pFile, "Lat = %5d: 0 = %4d. 1 = %3d. DC = %4d. \n", Abc_NtkLatchNum(pNtk), Init0, Init1, Init2 );
+ fprintf( pFile, "Con = %3d. DC = %3d. Mat = %3d. ", Counter0, Counter1, Counter2 );
+ fprintf( pFile, "SFeed = %2d.\n", Abc_NtkCountSelfFeedLatches(pNtk) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the distribution of fanins/fanouts in the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintFanio( FILE * pFile, Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, k, nFanins, nFanouts;
+ Vec_Int_t * vFanins, * vFanouts;
+ int nOldSize, nNewSize;
+
+ vFanins = Vec_IntAlloc( 0 );
+ vFanouts = Vec_IntAlloc( 0 );
+ Vec_IntFill( vFanins, 100, 0 );
+ Vec_IntFill( vFanouts, 100, 0 );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ nFanins = Abc_ObjFaninNum(pNode);
+ if ( Abc_NtkIsNetlist(pNtk) )
+ nFanouts = Abc_ObjFanoutNum( Abc_ObjFanout0(pNode) );
+ else
+ nFanouts = Abc_ObjFanoutNum(pNode);
+ if ( nFanins > vFanins->nSize || nFanouts > vFanouts->nSize )
+ {
+ nOldSize = vFanins->nSize;
+ nNewSize = ABC_MAX(nFanins, nFanouts) + 10;
+ Vec_IntGrow( vFanins, nNewSize );
+ Vec_IntGrow( vFanouts, nNewSize );
+ for ( k = nOldSize; k < nNewSize; k++ )
+ {
+ Vec_IntPush( vFanins, 0 );
+ Vec_IntPush( vFanouts, 0 );
+ }
+ }
+ vFanins->pArray[nFanins]++;
+ vFanouts->pArray[nFanouts]++;
+ }
+ fprintf( pFile, "The distribution of fanins and fanouts in the network:\n" );
+ fprintf( pFile, " Number Nodes with fanin Nodes with fanout\n" );
+ for ( k = 0; k < vFanins->nSize; k++ )
+ {
+ if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 )
+ continue;
+ fprintf( pFile, "%5d : ", k );
+ if ( vFanins->pArray[k] == 0 )
+ fprintf( pFile, " " );
+ else
+ fprintf( pFile, "%12d ", vFanins->pArray[k] );
+ fprintf( pFile, " " );
+ if ( vFanouts->pArray[k] == 0 )
+ fprintf( pFile, " " );
+ else
+ fprintf( pFile, "%12d ", vFanouts->pArray[k] );
+ fprintf( pFile, "\n" );
+ }
+ Vec_IntFree( vFanins );
+ Vec_IntFree( vFanouts );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the fanins/fanouts of a node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pNode2;
+ int i;
+ if ( Abc_ObjIsPo(pNode) )
+ pNode = Abc_ObjFanin0(pNode);
+
+ fprintf( pFile, "Node %s", Abc_ObjName(pNode) );
+ fprintf( pFile, "\n" );
+
+ fprintf( pFile, "Fanins (%d): ", Abc_ObjFaninNum(pNode) );
+ Abc_ObjForEachFanin( pNode, pNode2, i )
+ fprintf( pFile, " %s", Abc_ObjName(pNode2) );
+ fprintf( pFile, "\n" );
+
+ fprintf( pFile, "Fanouts (%d): ", Abc_ObjFaninNum(pNode) );
+ Abc_ObjForEachFanout( pNode, pNode2, i )
+ fprintf( pFile, " %s", Abc_ObjName(pNode2) );
+ fprintf( pFile, "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the factored form of one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, int fUseRealNames )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ assert( Abc_NtkIsSopLogic(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ Abc_NodePrintFactor( pFile, pNode, fUseRealNames );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the factored form of one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames )
+{
+ Dec_Graph_t * pGraph;
+ Vec_Ptr_t * vNamesIn;
+ if ( Abc_ObjIsCo(pNode) )
+ pNode = Abc_ObjFanin0(pNode);
+ if ( Abc_ObjIsPi(pNode) )
+ {
+ fprintf( pFile, "Skipping the PI node.\n" );
+ return;
+ }
+ if ( Abc_ObjIsLatch(pNode) )
+ {
+ fprintf( pFile, "Skipping the latch.\n" );
+ return;
+ }
+ assert( Abc_ObjIsNode(pNode) );
+ pGraph = Dec_Factor( pNode->pData );
+ if ( fUseRealNames )
+ {
+ vNamesIn = Abc_NodeGetFaninNames(pNode);
+ Dec_GraphPrint( stdout, pGraph, (char **)vNamesIn->pArray, Abc_ObjName(pNode) );
+ Abc_NodeFreeNames( vNamesIn );
+ }
+ else
+ Dec_GraphPrint( stdout, pGraph, (char **)NULL, Abc_ObjName(pNode) );
+ Dec_GraphFree( pGraph );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints the level stats of the PO node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile )
+{
+ Abc_Obj_t * pNode;
+ int i, Length;
+
+ // print the delay profile
+ if ( fProfile && Abc_NtkHasMapping(pNtk) )
+ {
+ int nIntervals = 12;
+ float DelayMax, DelayCur, DelayDelta;
+ int * pLevelCounts;
+ int DelayInt, nOutsSum, nOutsTotal;
+
+ // get the max delay and delta
+ DelayMax = Abc_NtkDelayTrace( pNtk );
+ DelayDelta = DelayMax/nIntervals;
+ // collect outputs by delay
+ pLevelCounts = ALLOC( int, nIntervals );
+ memset( pLevelCounts, 0, sizeof(int) * nIntervals );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ DelayCur = Abc_NodeReadArrival( Abc_ObjFanin0(pNode) )->Worst;
+ DelayInt = (int)(DelayCur / DelayDelta);
+ if ( DelayInt >= nIntervals )
+ DelayInt = nIntervals - 1;
+ pLevelCounts[DelayInt]++;
+ }
+
+ nOutsSum = 0;
+ nOutsTotal = Abc_NtkCoNum(pNtk);
+ for ( i = 0; i < nIntervals; i++ )
+ {
+ nOutsSum += pLevelCounts[i];
+ printf( "[%8.2f - %8.2f] : COs = %4d. %5.1f %%\n",
+ DelayDelta * i, DelayDelta * (i+1), pLevelCounts[i], 100.0 * nOutsSum/nOutsTotal );
+ }
+ free( pLevelCounts );
+ return;
+ }
+ else if ( fProfile )
+ {
+ int LevelMax, * pLevelCounts;
+ int nOutsSum, nOutsTotal;
+
+ if ( !Abc_NtkIsStrash(pNtk) )
+ Abc_NtkGetLevelNum(pNtk);
+
+ LevelMax = 0;
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ if ( LevelMax < (int)Abc_ObjFanin0(pNode)->Level )
+ LevelMax = Abc_ObjFanin0(pNode)->Level;
+ pLevelCounts = ALLOC( int, LevelMax + 1 );
+ memset( pLevelCounts, 0, sizeof(int) * (LevelMax + 1) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ pLevelCounts[Abc_ObjFanin0(pNode)->Level]++;
+
+ nOutsSum = 0;
+ nOutsTotal = Abc_NtkCoNum(pNtk);
+ for ( i = 0; i <= LevelMax; i++ )
+ if ( pLevelCounts[i] )
+ {
+ nOutsSum += pLevelCounts[i];
+ printf( "Level = %4d. COs = %4d. %5.1f %%\n", i, pLevelCounts[i], 100.0 * nOutsSum/nOutsTotal );
+ }
+ free( pLevelCounts );
+ return;
+ }
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // find the longest name
+ Length = 0;
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ if ( Length < (int)strlen(Abc_ObjName(pNode)) )
+ Length = strlen(Abc_ObjName(pNode));
+ if ( Length < 5 )
+ Length = 5;
+ // print stats for each output
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ fprintf( pFile, "CO %4d : %*s ", i, Length, Abc_ObjName(pNode) );
+ Abc_NodePrintLevel( pFile, pNode );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the factored form of one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pDriver;
+ Vec_Ptr_t * vNodes;
+
+ pDriver = Abc_ObjIsCo(pNode)? Abc_ObjFanin0(pNode) : pNode;
+ if ( Abc_ObjIsPi(pDriver) )
+ {
+ fprintf( pFile, "Primary input.\n" );
+ return;
+ }
+ if ( Abc_ObjIsLatch(pDriver) )
+ {
+ fprintf( pFile, "Latch.\n" );
+ return;
+ }
+ if ( Abc_NodeIsConst(pDriver) )
+ {
+ fprintf( pFile, "Constant %d.\n", !Abc_ObjFaninC0(pNode) );
+ return;
+ }
+ // print the level
+ fprintf( pFile, "Level = %3d. ", pDriver->Level );
+ // print the size of MFFC
+ fprintf( pFile, "Mffc = %5d. ", Abc_NodeMffcSize(pDriver) );
+ // print the size of the shole cone
+ vNodes = Abc_NtkDfsNodes( pNode->pNtk, &pDriver, 1 );
+ fprintf( pFile, "Cone = %5d. ", Vec_PtrSize(vNodes) );
+ Vec_PtrFree( vNodes );
+ fprintf( pFile, "\n" );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcReconv.c b/src/base/abci/abcReconv.c
new file mode 100644
index 00000000..766c14f3
--- /dev/null
+++ b/src/base/abci/abcReconv.c
@@ -0,0 +1,742 @@
+/**CFile****************************************************************
+
+ FileName [abcRes.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Reconvergence=driven cut computation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcRes.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct Abc_ManCut_t_
+{
+ // user specified parameters
+ int nNodeSizeMax; // the limit on the size of the supernode
+ int nConeSizeMax; // the limit on the size of the containing cone
+ int nNodeFanStop; // the limit on the size of the supernode
+ int nConeFanStop; // the limit on the size of the containing cone
+ // internal parameters
+ Vec_Ptr_t * vNodeLeaves; // fanins of the collapsed node (the cut)
+ Vec_Ptr_t * vConeLeaves; // fanins of the containing cone
+ Vec_Ptr_t * vVisited; // the visited nodes
+ Vec_Vec_t * vLevels; // the data structure to compute TFO nodes
+ Vec_Ptr_t * vNodesTfo; // the nodes in the TFO of the cut
+};
+
+static int Abc_NodeBuildCutLevelOne_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nSizeLimit, int nFaninLimit );
+static int Abc_NodeBuildCutLevelTwo_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nFaninLimit );
+static void Abc_NodeConeMarkCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vVisited );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Unmarks the TFI cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Abc_NodesMark( Vec_Ptr_t * vVisited )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ Vec_PtrForEachEntry( vVisited, pNode, i )
+ pNode->fMarkA = 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Unmarks the TFI cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Abc_NodesUnmark( Vec_Ptr_t * vVisited )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ Vec_PtrForEachEntry( vVisited, pNode, i )
+ pNode->fMarkA = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Unmarks the TFI cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Abc_NodesUnmarkB( Vec_Ptr_t * vVisited )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ Vec_PtrForEachEntry( vVisited, pNode, i )
+ pNode->fMarkB = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Evaluate the cost of removing the node from the set of leaves.]
+
+ Description [Returns the number of new leaves that will be brought in.
+ Returns large number if the node cannot be removed from the set of leaves.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Abc_NodeGetLeafCostOne( Abc_Obj_t * pNode, int nFaninLimit )
+{
+ int Cost;
+ // make sure the node is in the construction zone
+ assert( pNode->fMarkB == 1 );
+ // cannot expand over the PI node
+ if ( Abc_ObjIsCi(pNode) )
+ return 999;
+ // get the cost of the cone
+ Cost = (!Abc_ObjFanin0(pNode)->fMarkB) + (!Abc_ObjFanin1(pNode)->fMarkB);
+ // always accept if the number of leaves does not increase
+ if ( Cost < 2 )
+ return Cost;
+ // skip nodes with many fanouts
+ if ( Abc_ObjFanoutNum(pNode) > nFaninLimit )
+ return 999;
+ // return the number of nodes that will be on the leaves if this node is removed
+ return Cost;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Evaluate the cost of removing the node from the set of leaves.]
+
+ Description [Returns the number of new leaves that will be brought in.
+ Returns large number if the node cannot be removed from the set of leaves.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Abc_NodeGetLeafCostTwo( Abc_Obj_t * pNode, int nFaninLimit,
+ Abc_Obj_t ** ppLeafToAdd, Abc_Obj_t ** pNodeToMark1, Abc_Obj_t ** pNodeToMark2 )
+{
+ Abc_Obj_t * pFanin0, * pFanin1, * pTemp;
+ Abc_Obj_t * pGrand, * pGrandToAdd;
+ // make sure the node is in the construction zone
+ assert( pNode->fMarkB == 1 );
+ // cannot expand over the PI node
+ if ( Abc_ObjIsCi(pNode) )
+ return 999;
+ // skip nodes with many fanouts
+// if ( Abc_ObjFanoutNum(pNode) > nFaninLimit )
+// return 999;
+ // get the children
+ pFanin0 = Abc_ObjFanin0(pNode);
+ pFanin1 = Abc_ObjFanin1(pNode);
+ assert( !pFanin0->fMarkB && !pFanin1->fMarkB );
+ // count the number of unique grandchildren that will be included
+ // return infinite cost if this number if more than 1
+ if ( Abc_ObjIsCi(pFanin0) && Abc_ObjIsCi(pFanin1) )
+ return 999;
+ // consider the special case when a non-CI fanin can be dropped
+ if ( !Abc_ObjIsCi(pFanin0) && Abc_ObjFanin0(pFanin0)->fMarkB && Abc_ObjFanin1(pFanin0)->fMarkB )
+ {
+ *ppLeafToAdd = pFanin1;
+ *pNodeToMark1 = pFanin0;
+ *pNodeToMark2 = NULL;
+ return 1;
+ }
+ if ( !Abc_ObjIsCi(pFanin1) && Abc_ObjFanin0(pFanin1)->fMarkB && Abc_ObjFanin1(pFanin1)->fMarkB )
+ {
+ *ppLeafToAdd = pFanin0;
+ *pNodeToMark1 = pFanin1;
+ *pNodeToMark2 = NULL;
+ return 1;
+ }
+
+ // make the first node CI if any
+ if ( Abc_ObjIsCi(pFanin1) )
+ pTemp = pFanin0, pFanin0 = pFanin1, pFanin1 = pTemp;
+ // consider the first node
+ pGrandToAdd = NULL;
+ if ( Abc_ObjIsCi(pFanin0) )
+ {
+ *pNodeToMark1 = NULL;
+ pGrandToAdd = pFanin0;
+ }
+ else
+ {
+ *pNodeToMark1 = pFanin0;
+ pGrand = Abc_ObjFanin0(pFanin0);
+ if ( !pGrand->fMarkB )
+ {
+ if ( pGrandToAdd && pGrandToAdd != pGrand )
+ return 999;
+ pGrandToAdd = pGrand;
+ }
+ pGrand = Abc_ObjFanin1(pFanin0);
+ if ( !pGrand->fMarkB )
+ {
+ if ( pGrandToAdd && pGrandToAdd != pGrand )
+ return 999;
+ pGrandToAdd = pGrand;
+ }
+ }
+ // consider the second node
+ *pNodeToMark2 = pFanin1;
+ pGrand = Abc_ObjFanin0(pFanin1);
+ if ( !pGrand->fMarkB )
+ {
+ if ( pGrandToAdd && pGrandToAdd != pGrand )
+ return 999;
+ pGrandToAdd = pGrand;
+ }
+ pGrand = Abc_ObjFanin1(pFanin1);
+ if ( !pGrand->fMarkB )
+ {
+ if ( pGrandToAdd && pGrandToAdd != pGrand )
+ return 999;
+ pGrandToAdd = pGrand;
+ }
+ assert( pGrandToAdd != NULL );
+ *ppLeafToAdd = pGrandToAdd;
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Finds a fanin-limited, reconvergence-driven cut for the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NodeFindCut( Abc_ManCut_t * p, Abc_Obj_t * pRoot, bool fContain )
+{
+ Abc_Obj_t * pNode;
+ int i;
+
+ assert( !Abc_ObjIsComplement(pRoot) );
+ assert( Abc_ObjIsNode(pRoot) );
+
+ // start the visited nodes and mark them
+ Vec_PtrClear( p->vVisited );
+ Vec_PtrPush( p->vVisited, pRoot );
+ Vec_PtrPush( p->vVisited, Abc_ObjFanin0(pRoot) );
+ Vec_PtrPush( p->vVisited, Abc_ObjFanin1(pRoot) );
+ pRoot->fMarkB = 1;
+ Abc_ObjFanin0(pRoot)->fMarkB = 1;
+ Abc_ObjFanin1(pRoot)->fMarkB = 1;
+
+ // start the cut
+ Vec_PtrClear( p->vNodeLeaves );
+ Vec_PtrPush( p->vNodeLeaves, Abc_ObjFanin0(pRoot) );
+ Vec_PtrPush( p->vNodeLeaves, Abc_ObjFanin1(pRoot) );
+
+ // compute the cut
+ while ( Abc_NodeBuildCutLevelOne_int( p->vVisited, p->vNodeLeaves, p->nNodeSizeMax, p->nNodeFanStop ) );
+ assert( Vec_PtrSize(p->vNodeLeaves) <= p->nNodeSizeMax );
+
+ // return if containing cut is not requested
+ if ( !fContain )
+ {
+ // unmark both fMarkA and fMarkB in tbe TFI
+ Abc_NodesUnmarkB( p->vVisited );
+ return p->vNodeLeaves;
+ }
+
+//printf( "\n\n\n" );
+ // compute the containing cut
+ assert( p->nNodeSizeMax < p->nConeSizeMax );
+ // copy the current boundary
+ Vec_PtrClear( p->vConeLeaves );
+ Vec_PtrForEachEntry( p->vNodeLeaves, pNode, i )
+ Vec_PtrPush( p->vConeLeaves, pNode );
+ // compute the containing cut
+ while ( Abc_NodeBuildCutLevelOne_int( p->vVisited, p->vConeLeaves, p->nConeSizeMax, p->nConeFanStop ) );
+ assert( Vec_PtrSize(p->vConeLeaves) <= p->nConeSizeMax );
+ // unmark TFI using fMarkA and fMarkB
+ Abc_NodesUnmarkB( p->vVisited );
+ return p->vNodeLeaves;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Builds reconvergence-driven cut by changing one leaf at a time.]
+
+ Description [This procedure looks at the current leaves and tries to change
+ one leaf at a time in such a way that the cut grows as little as possible.
+ In evaluating the fanins, this procedure looks only at their immediate
+ predecessors (this is why it is called a one-level construction procedure).]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeBuildCutLevelOne_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nSizeLimit, int nFaninLimit )
+{
+ Abc_Obj_t * pNode, * pFaninBest, * pNext;
+ int CostBest, CostCur, i;
+ // find the best fanin
+ CostBest = 100;
+ pFaninBest = NULL;
+//printf( "Evaluating fanins of the cut:\n" );
+ Vec_PtrForEachEntry( vLeaves, pNode, i )
+ {
+ CostCur = Abc_NodeGetLeafCostOne( pNode, nFaninLimit );
+//printf( " Fanin %s has cost %d.\n", Abc_ObjName(pNode), CostCur );
+ if ( CostBest > CostCur )
+ {
+ CostBest = CostCur;
+ pFaninBest = pNode;
+ }
+ if ( CostBest == 0 )
+ break;
+ }
+ if ( pFaninBest == NULL )
+ return 0;
+// return Abc_NodeBuildCutLevelTwo_int( vVisited, vLeaves, nFaninLimit );
+
+ assert( CostBest < 3 );
+ if ( vLeaves->nSize - 1 + CostBest > nSizeLimit )
+ return 0;
+// return Abc_NodeBuildCutLevelTwo_int( vVisited, vLeaves, nFaninLimit );
+
+ assert( Abc_ObjIsNode(pFaninBest) );
+ // remove the node from the array
+ Vec_PtrRemove( vLeaves, pFaninBest );
+//printf( "Removing fanin %s.\n", Abc_ObjName(pFaninBest) );
+
+ // add the left child to the fanins
+ pNext = Abc_ObjFanin0(pFaninBest);
+ if ( !pNext->fMarkB )
+ {
+//printf( "Adding fanin %s.\n", Abc_ObjName(pNext) );
+ pNext->fMarkB = 1;
+ Vec_PtrPush( vLeaves, pNext );
+ Vec_PtrPush( vVisited, pNext );
+ }
+ // add the right child to the fanins
+ pNext = Abc_ObjFanin1(pFaninBest);
+ if ( !pNext->fMarkB )
+ {
+//printf( "Adding fanin %s.\n", Abc_ObjName(pNext) );
+ pNext->fMarkB = 1;
+ Vec_PtrPush( vLeaves, pNext );
+ Vec_PtrPush( vVisited, pNext );
+ }
+ assert( vLeaves->nSize <= nSizeLimit );
+ // keep doing this
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Builds reconvergence-driven cut by changing one leaf at a time.]
+
+ Description [This procedure looks at the current leaves and tries to change
+ one leaf at a time in such a way that the cut grows as little as possible.
+ In evaluating the fanins, this procedure looks across two levels of fanins
+ (this is why it is called a two-level construction procedure).]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeBuildCutLevelTwo_int( Vec_Ptr_t * vVisited, Vec_Ptr_t * vLeaves, int nFaninLimit )
+{
+ Abc_Obj_t * pNode, * pLeafToAdd, * pNodeToMark1, * pNodeToMark2;
+ int CostCur, i;
+ // find the best fanin
+ Vec_PtrForEachEntry( vLeaves, pNode, i )
+ {
+ CostCur = Abc_NodeGetLeafCostTwo( pNode, nFaninLimit, &pLeafToAdd, &pNodeToMark1, &pNodeToMark2 );
+ if ( CostCur < 2 )
+ break;
+ }
+ if ( CostCur > 2 )
+ return 0;
+ // remove the node from the array
+ Vec_PtrRemove( vLeaves, pNode );
+ // add the node to the leaves
+ if ( pLeafToAdd )
+ {
+ assert( !pLeafToAdd->fMarkB );
+ pLeafToAdd->fMarkB = 1;
+ Vec_PtrPush( vLeaves, pLeafToAdd );
+ Vec_PtrPush( vVisited, pLeafToAdd );
+ }
+ // mark the other nodes
+ if ( pNodeToMark1 )
+ {
+ assert( !pNodeToMark1->fMarkB );
+ pNodeToMark1->fMarkB = 1;
+ Vec_PtrPush( vVisited, pNodeToMark1 );
+ }
+ if ( pNodeToMark2 )
+ {
+ assert( !pNodeToMark2->fMarkB );
+ pNodeToMark2->fMarkB = 1;
+ Vec_PtrPush( vVisited, pNodeToMark2 );
+ }
+ // keep doing this
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Get the nodes contained in the cut.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeConeCollect( Abc_Obj_t ** ppRoots, int nRoots, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVisited, int fIncludeFanins )
+{
+ Abc_Obj_t * pTemp;
+ int i;
+ // mark the fanins of the cone
+ Abc_NodesMark( vLeaves );
+ // collect the nodes in the DFS order
+ Vec_PtrClear( vVisited );
+ // add the fanins
+ if ( fIncludeFanins )
+ Vec_PtrForEachEntry( vLeaves, pTemp, i )
+ Vec_PtrPush( vVisited, pTemp );
+ // add other nodes
+ for ( i = 0; i < nRoots; i++ )
+ Abc_NodeConeMarkCollect_rec( ppRoots[i], vVisited );
+ // unmark both sets
+ Abc_NodesUnmark( vLeaves );
+ Abc_NodesUnmark( vVisited );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks the TFI cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeConeMarkCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vVisited )
+{
+ if ( pNode->fMarkA == 1 )
+ return;
+ // visit transitive fanin
+ if ( Abc_ObjIsNode(pNode) )
+ {
+ Abc_NodeConeMarkCollect_rec( Abc_ObjFanin0(pNode), vVisited );
+ Abc_NodeConeMarkCollect_rec( Abc_ObjFanin1(pNode), vVisited );
+ }
+ assert( pNode->fMarkA == 0 );
+ pNode->fMarkA = 1;
+ Vec_PtrPush( vVisited, pNode );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns BDD representing the logic function of the cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NodeConeBdd( DdManager * dd, DdNode ** pbVars, Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVisited )
+{
+ DdNode * bFunc0, * bFunc1, * bFunc;
+ int i;
+ // get the nodes in the cut without fanins in the DFS order
+ Abc_NodeConeCollect( &pNode, 1, vLeaves, vVisited, 0 );
+ // set the elementary BDDs
+ Vec_PtrForEachEntry( vLeaves, pNode, i )
+ pNode->pCopy = (Abc_Obj_t *)pbVars[i];
+ // compute the BDDs for the collected nodes
+ Vec_PtrForEachEntry( vVisited, pNode, i )
+ {
+ bFunc0 = Cudd_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
+ bFunc1 = Cudd_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) );
+ bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc );
+ pNode->pCopy = (Abc_Obj_t *)bFunc;
+ }
+ Cudd_Ref( bFunc );
+ // dereference the intermediate ones
+ Vec_PtrForEachEntry( vVisited, pNode, i )
+ Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy );
+ Cudd_Deref( bFunc );
+ return bFunc;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns BDD representing the transition relation of the cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NodeConeDcs( DdManager * dd, DdNode ** pbVarsX, DdNode ** pbVarsY, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vRoots, Vec_Ptr_t * vVisited )
+{
+ DdNode * bFunc0, * bFunc1, * bFunc, * bTrans, * bTemp, * bCube, * bResult;
+ Abc_Obj_t * pNode;
+ int i;
+ // get the nodes in the cut without fanins in the DFS order
+ Abc_NodeConeCollect( (Abc_Obj_t **)vRoots->pArray, vRoots->nSize, vLeaves, vVisited, 0 );
+ // set the elementary BDDs
+ Vec_PtrForEachEntry( vLeaves, pNode, i )
+ pNode->pCopy = (Abc_Obj_t *)pbVarsX[i];
+ // compute the BDDs for the collected nodes
+ Vec_PtrForEachEntry( vVisited, pNode, i )
+ {
+ bFunc0 = Cudd_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) );
+ bFunc1 = Cudd_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) );
+ bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc );
+ pNode->pCopy = (Abc_Obj_t *)bFunc;
+ }
+ // compute the transition relation of the cone
+ bTrans = b1; Cudd_Ref( bTrans );
+ Vec_PtrForEachEntry( vRoots, pNode, i )
+ {
+ bFunc = Cudd_bddXnor( dd, (DdNode *)pNode->pCopy, pbVarsY[i] ); Cudd_Ref( bFunc );
+ bTrans = Cudd_bddAnd( dd, bTemp = bTrans, bFunc ); Cudd_Ref( bTrans );
+ Cudd_RecursiveDeref( dd, bTemp );
+ Cudd_RecursiveDeref( dd, bFunc );
+ }
+ // dereference the intermediate ones
+ Vec_PtrForEachEntry( vVisited, pNode, i )
+ Cudd_RecursiveDeref( dd, (DdNode *)pNode->pCopy );
+ // compute don't-cares
+ bCube = Extra_bddComputeRangeCube( dd, vRoots->nSize, vRoots->nSize + vLeaves->nSize ); Cudd_Ref( bCube );
+ bResult = Cudd_bddExistAbstract( dd, bTrans, bCube ); Cudd_Ref( bResult );
+ bResult = Cudd_Not( bResult );
+ Cudd_RecursiveDeref( dd, bCube );
+ Cudd_RecursiveDeref( dd, bTrans );
+ Cudd_Deref( bResult );
+ return bResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts the resynthesis manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_ManCut_t * Abc_NtkManCutStart( int nNodeSizeMax, int nConeSizeMax, int nNodeFanStop, int nConeFanStop )
+{
+ Abc_ManCut_t * p;
+ p = ALLOC( Abc_ManCut_t, 1 );
+ memset( p, 0, sizeof(Abc_ManCut_t) );
+ p->vNodeLeaves = Vec_PtrAlloc( 100 );
+ p->vConeLeaves = Vec_PtrAlloc( 100 );
+ p->vVisited = Vec_PtrAlloc( 100 );
+ p->vLevels = Vec_VecAlloc( 100 );
+ p->vNodesTfo = Vec_PtrAlloc( 100 );
+ p->nNodeSizeMax = nNodeSizeMax;
+ p->nConeSizeMax = nConeSizeMax;
+ p->nNodeFanStop = nNodeFanStop;
+ p->nConeFanStop = nConeFanStop;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the resynthesis manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkManCutStop( Abc_ManCut_t * p )
+{
+ Vec_PtrFree( p->vNodeLeaves );
+ Vec_PtrFree( p->vConeLeaves );
+ Vec_PtrFree( p->vVisited );
+ Vec_VecFree( p->vLevels );
+ Vec_PtrFree( p->vNodesTfo );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the leaves of the cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NtkManCutReadCutLarge( Abc_ManCut_t * p )
+{
+ return p->vConeLeaves;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the leaves of the cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NtkManCutReadVisited( Abc_ManCut_t * p )
+{
+ return p->vVisited;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Collects the TFO of the cut in the topological order.]
+
+ Description [TFO of the cut is defined as a set of nodes, for which the cut
+ is a cut, that is, every path from the collected nodes to the CIs goes through
+ a node in the cut. The nodes are collected if their level does not exceed
+ the given number (LevelMax). The nodes are returned in the topological order.
+ If the root node is given, its MFFC is marked, so that the collected nodes
+ do not contain any nodes in the MFFC.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Abc_NodeCollectTfoCands( Abc_ManCut_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int LevelMax )
+{
+ Abc_Ntk_t * pNtk = pRoot->pNtk;
+ Vec_Ptr_t * vVec;
+ Abc_Obj_t * pNode, * pFanout;
+ int i, k, v, LevelMin;
+ assert( Abc_NtkIsStrash(pNtk) );
+
+ // assuming that the structure is clean
+ Vec_VecForEachLevel( p->vLevels, vVec, i )
+ assert( vVec->nSize == 0 );
+
+ // put fanins into the structure while labeling them
+ Abc_NtkIncrementTravId( pNtk );
+ LevelMin = -1;
+ Vec_PtrForEachEntry( vLeaves, pNode, i )
+ {
+ if ( pNode->Level > (unsigned)LevelMax )
+ continue;
+ Abc_NodeSetTravIdCurrent( pNode );
+ Vec_VecPush( p->vLevels, pNode->Level, pNode );
+ if ( LevelMin < (int)pNode->Level )
+ LevelMin = pNode->Level;
+ }
+ assert( LevelMin >= 0 );
+
+ // mark MFFC
+ if ( pRoot )
+ Abc_NodeMffcLabel( pRoot );
+
+ // go through the levels up
+ Vec_PtrClear( p->vNodesTfo );
+ Vec_VecForEachEntryStart( p->vLevels, pNode, i, k, LevelMin )
+ {
+ if ( i > LevelMax )
+ break;
+ // if the node is not marked, it is not a fanin
+ if ( !Abc_NodeIsTravIdCurrent(pNode) )
+ {
+ // check if it belongs to the TFO
+ if ( !Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pNode)) ||
+ !Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pNode)) )
+ continue;
+ // save the node in the TFO and label it
+ Vec_PtrPush( p->vNodesTfo, pNode );
+ Abc_NodeSetTravIdCurrent( pNode );
+ }
+ // go through the fanouts and add them to the structure if they meet the conditions
+ Abc_ObjForEachFanout( pNode, pFanout, v )
+ {
+ // skip if fanout is a CO or its level exceeds
+ if ( Abc_ObjIsCo(pFanout) || pFanout->Level > (unsigned)LevelMax )
+ continue;
+ // skip if it is already added or if it is in MFFC
+ if ( Abc_NodeIsTravIdCurrent(pFanout) )
+ continue;
+ // add it to the structure but do not mark it (until tested later)
+ Vec_VecPushUnique( p->vLevels, pFanout->Level, pFanout );
+ }
+ }
+
+ // clear the levelized structure
+ Vec_VecForEachLevelStart( p->vLevels, vVec, i, LevelMin )
+ {
+ if ( i > LevelMax )
+ break;
+ Vec_PtrClear( vVec );
+ }
+ return p->vNodesTfo;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c
new file mode 100644
index 00000000..791d2d53
--- /dev/null
+++ b/src/base/abci/abcRefactor.c
@@ -0,0 +1,354 @@
+/**CFile****************************************************************
+
+ FileName [abcResRef.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Resynthesis based on refactoring.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcResRef.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "dec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Abc_ManRef_t_ Abc_ManRef_t;
+struct Abc_ManRef_t_
+{
+ // user specified parameters
+ int nNodeSizeMax; // the limit on the size of the supernode
+ int nConeSizeMax; // the limit on the size of the containing cone
+ int fVerbose; // the verbosity flag
+ // internal data structures
+ DdManager * dd; // the BDD manager
+ Vec_Str_t * vCube; // temporary
+ Vec_Int_t * vForm; // temporary
+ Vec_Ptr_t * vVisited; // temporary
+ Vec_Ptr_t * vLeaves; // temporary
+ // node statistics
+ int nLastGain;
+ int nNodesConsidered;
+ int nNodesRefactored;
+ int nNodesGained;
+ // runtime statistics
+ int timeCut;
+ int timeBdd;
+ int timeDcs;
+ int timeSop;
+ int timeFact;
+ int timeEval;
+ int timeRes;
+ int timeNtk;
+ int timeTotal;
+};
+
+static void Abc_NtkManRefPrintStats( Abc_ManRef_t * p );
+static Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUseDcs, bool fVerbose );
+static void Abc_NtkManRefStop( Abc_ManRef_t * p );
+static Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUseZeros, bool fUseDcs, bool fVerbose );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs incremental resynthesis of the AIG.]
+
+ Description [Starting from each node, computes a reconvergence-driven cut,
+ derives BDD of the cut function, constructs ISOP, factors the ISOP,
+ and replaces the current implementation of the MFFC of the node by the
+ new factored form, if the number of AIG nodes is reduced and the total
+ number of levels of the AIG network is not increated. Returns the
+ number of AIG nodes saved.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUseZeros, bool fUseDcs, bool fVerbose )
+{
+ int fCheck = 1;
+ ProgressBar * pProgress;
+ Abc_ManRef_t * pManRef;
+ Abc_ManCut_t * pManCut;
+ Dec_Graph_t * pFForm;
+ Vec_Ptr_t * vFanins;
+ Abc_Obj_t * pNode;
+ int clk, clkStart = clock();
+ int i, nNodes;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+ // cleanup the AIG
+ Abc_AigCleanup(pNtk->pManFunc);
+ // start the managers
+ pManCut = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 );
+ pManRef = Abc_NtkManRefStart( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose );
+ pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCut );
+ Abc_NtkStartReverseLevels( pNtk );
+
+ // resynthesize each node once
+ nNodes = Abc_NtkObjNumMax(pNtk);
+ pProgress = Extra_ProgressBarStart( stdout, nNodes );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // skip the constant node
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ // stop if all nodes have been tried once
+ if ( i >= nNodes )
+ break;
+ // compute a reconvergence-driven cut
+clk = clock();
+ vFanins = Abc_NodeFindCut( pManCut, pNode, fUseDcs );
+pManRef->timeCut += clock() - clk;
+ // evaluate this cut
+clk = clock();
+ pFForm = Abc_NodeRefactor( pManRef, pNode, vFanins, fUseZeros, fUseDcs, fVerbose );
+pManRef->timeRes += clock() - clk;
+ if ( pFForm == NULL )
+ continue;
+ // acceptable replacement found, update the graph
+clk = clock();
+ Dec_GraphUpdateNetwork( pNode, pFForm, pManRef->nLastGain );
+pManRef->timeNtk += clock() - clk;
+ Dec_GraphFree( pFForm );
+ }
+ Extra_ProgressBarStop( pProgress );
+pManRef->timeTotal = clock() - clkStart;
+
+ // print statistics of the manager
+ if ( fVerbose )
+ Abc_NtkManRefPrintStats( pManRef );
+ // delete the managers
+ Abc_NtkManCutStop( pManCut );
+ Abc_NtkManRefStop( pManRef );
+ Abc_NtkStopReverseLevels( pNtk );
+ // check
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkRefactor: The network check has failed.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resynthesizes the node using refactoring.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUseZeros, bool fUseDcs, bool fVerbose )
+{
+ int fVeryVerbose = 0;
+ Abc_Obj_t * pFanin;
+ Dec_Graph_t * pFForm;
+ DdNode * bNodeFunc;
+ int nNodesSaved, nNodesAdded, i, clk;
+ char * pSop;
+
+ p->nNodesConsidered++;
+
+ // get the function of the cut
+clk = clock();
+ bNodeFunc = Abc_NodeConeBdd( p->dd, p->dd->vars, pNode, vFanins, p->vVisited ); Cudd_Ref( bNodeFunc );
+p->timeBdd += clock() - clk;
+
+ // if don't-care are used, transform the function into ISOP
+ if ( fUseDcs )
+ {
+ DdNode * bNodeDc, * bNodeOn, * bNodeOnDc;
+ int nMints, nMintsDc;
+clk = clock();
+ // get the don't-cares
+ bNodeDc = Abc_NodeConeDcs( p->dd, p->dd->vars + vFanins->nSize, p->dd->vars, p->vLeaves, vFanins, p->vVisited ); Cudd_Ref( bNodeDc );
+ nMints = (1 << vFanins->nSize);
+ nMintsDc = (int)Cudd_CountMinterm( p->dd, bNodeDc, vFanins->nSize );
+// printf( "Percentage of minterms = %5.2f.\n", 100.0 * nMintsDc / nMints );
+ // get the ISF
+ bNodeOn = Cudd_bddAnd( p->dd, bNodeFunc, Cudd_Not(bNodeDc) ); Cudd_Ref( bNodeOn );
+ bNodeOnDc = Cudd_bddOr ( p->dd, bNodeFunc, bNodeDc ); Cudd_Ref( bNodeOnDc );
+ Cudd_RecursiveDeref( p->dd, bNodeFunc );
+ Cudd_RecursiveDeref( p->dd, bNodeDc );
+ // get the ISOP
+ bNodeFunc = Cudd_bddIsop( p->dd, bNodeOn, bNodeOnDc ); Cudd_Ref( bNodeFunc );
+ Cudd_RecursiveDeref( p->dd, bNodeOn );
+ Cudd_RecursiveDeref( p->dd, bNodeOnDc );
+p->timeDcs += clock() - clk;
+ }
+
+ // always accept the case of constant node
+ if ( Cudd_IsConstant(bNodeFunc) )
+ {
+ p->nLastGain = Abc_NodeMffcSize( pNode );
+ p->nNodesGained += p->nLastGain;
+ p->nNodesRefactored++;
+ Cudd_RecursiveDeref( p->dd, bNodeFunc );
+ if ( Cudd_IsComplement(bNodeFunc) )
+ return Dec_GraphCreateConst0();
+ return Dec_GraphCreateConst1();
+ }
+
+ // get the SOP of the cut
+clk = clock();
+ pSop = Abc_ConvertBddToSop( NULL, p->dd, bNodeFunc, bNodeFunc, vFanins->nSize, p->vCube, -1 );
+p->timeSop += clock() - clk;
+
+ // get the factored form
+clk = clock();
+ pFForm = Dec_Factor( pSop );
+ free( pSop );
+p->timeFact += clock() - clk;
+
+ // mark the fanin boundary
+ // (can mark only essential fanins, belonging to bNodeFunc!)
+ Vec_PtrForEachEntry( vFanins, pFanin, i )
+ pFanin->vFanouts.nSize++;
+ // label MFFC with current traversal ID
+ Abc_NtkIncrementTravId( pNode->pNtk );
+ nNodesSaved = Abc_NodeMffcLabel( pNode );
+ // unmark the fanin boundary and set the fanins as leaves in the form
+ Vec_PtrForEachEntry( vFanins, pFanin, i )
+ {
+ pFanin->vFanouts.nSize--;
+ Dec_GraphNode(pFForm, i)->pFunc = pFanin;
+ }
+
+ // detect how many new nodes will be added (while taking into account reused nodes)
+clk = clock();
+ nNodesAdded = Dec_GraphToNetworkCount( pNode, pFForm, nNodesSaved, Abc_NodeReadRequiredLevel(pNode) );
+p->timeEval += clock() - clk;
+ // quit if there is no improvement
+ if ( nNodesAdded == -1 || nNodesAdded == nNodesSaved && !fUseZeros )
+ {
+ Cudd_RecursiveDeref( p->dd, bNodeFunc );
+ Dec_GraphFree( pFForm );
+ return NULL;
+ }
+
+ // compute the total gain in the number of nodes
+ p->nLastGain = nNodesSaved - nNodesAdded;
+ p->nNodesGained += p->nLastGain;
+ p->nNodesRefactored++;
+
+ // report the progress
+ if ( fVeryVerbose )
+ {
+ printf( "Node %6s : ", Abc_ObjName(pNode) );
+ printf( "Cone = %2d. ", vFanins->nSize );
+ printf( "BDD = %2d. ", Cudd_DagSize(bNodeFunc) );
+ printf( "FF = %2d. ", 1 + Dec_GraphNodeNum(pFForm) );
+ printf( "MFFC = %2d. ", nNodesSaved );
+ printf( "Add = %2d. ", nNodesAdded );
+ printf( "GAIN = %2d. ", p->nLastGain );
+ printf( "\n" );
+ }
+ Cudd_RecursiveDeref( p->dd, bNodeFunc );
+ return pFForm;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Starts the resynthesis manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUseDcs, bool fVerbose )
+{
+ Abc_ManRef_t * p;
+ p = ALLOC( Abc_ManRef_t, 1 );
+ memset( p, 0, sizeof(Abc_ManRef_t) );
+ p->vCube = Vec_StrAlloc( 100 );
+ p->vVisited = Vec_PtrAlloc( 100 );
+ p->nNodeSizeMax = nNodeSizeMax;
+ p->nConeSizeMax = nConeSizeMax;
+ p->fVerbose = fVerbose;
+ // start the BDD manager
+ if ( fUseDcs )
+ p->dd = Cudd_Init( p->nNodeSizeMax + p->nConeSizeMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
+ else
+ p->dd = Cudd_Init( p->nNodeSizeMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
+ Cudd_zddVarsFromBddVars( p->dd, 2 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the resynthesis manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkManRefStop( Abc_ManRef_t * p )
+{
+ Extra_StopManager( p->dd );
+ Vec_PtrFree( p->vVisited );
+ Vec_StrFree( p->vCube );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the resynthesis manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkManRefPrintStats( Abc_ManRef_t * p )
+{
+ printf( "Refactoring statistics:\n" );
+ printf( "Nodes considered = %8d.\n", p->nNodesConsidered );
+ printf( "Nodes refactored = %8d.\n", p->nNodesRefactored );
+ printf( "Calculated gain = %8d.\n", p->nNodesGained );
+ PRT( "Cuts ", p->timeCut );
+ PRT( "Resynthesis", p->timeRes );
+ PRT( " BDD ", p->timeBdd );
+ PRT( " DCs ", p->timeDcs );
+ PRT( " SOP ", p->timeSop );
+ PRT( " FF ", p->timeFact );
+ PRT( " Eval ", p->timeEval );
+ PRT( "AIG update ", p->timeNtk );
+ PRT( "TOTAL ", p->timeTotal );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcRenode.c b/src/base/abci/abcRenode.c
new file mode 100644
index 00000000..c77c0d70
--- /dev/null
+++ b/src/base/abci/abcRenode.c
@@ -0,0 +1,609 @@
+/**CFile****************************************************************
+
+ FileName [abcRenode.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures which transform an AIG into the network of nodes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcRenode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew );
+static Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld );
+
+static DdNode * Abc_NtkRenodeDeriveBdd_rec( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFanins );
+
+static void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax );
+static void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk );
+static void Abc_NtkRenodeSetBoundsMulti( Abc_Ntk_t * pNtk, int nThresh );
+static void Abc_NtkRenodeSetBoundsSimple( Abc_Ntk_t * pNtk );
+static void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the AIG into nodes.]
+
+ Description [Threhold is the max number of nodes duplicated at a node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkRenode( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax, int fCnf, int fMulti, int fSimple )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkNew;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( nThresh >= 0 );
+ assert( nFaninMax > 1 );
+
+ // print a warning about choice nodes
+ if ( Abc_NtkGetChoiceNum( pNtk ) )
+ printf( "Warning: The choice nodes in the AIG are removed by renoding.\n" );
+
+ // define the boundary
+ if ( fCnf )
+ Abc_NtkRenodeSetBoundsCnf( pNtk );
+ else if ( fMulti )
+ Abc_NtkRenodeSetBoundsMulti( pNtk, nThresh );
+ else if ( fSimple )
+ Abc_NtkRenodeSetBoundsSimple( pNtk );
+ else
+ Abc_NtkRenodeSetBounds( pNtk, nThresh, nFaninMax );
+
+ // perform renoding for this boundary
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_TYPE_LOGIC, ABC_FUNC_BDD );
+ Abc_NtkRenodeInt( pNtk, pNtkNew );
+ Abc_NtkFinalize( pNtk, pNtkNew );
+
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtkNew );
+
+ // fix the problem with complemented and duplicated CO edges
+ Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
+
+ // report the number of CNF objects
+ if ( fCnf )
+ {
+// int nClauses = Abc_NtkGetClauseNum(pNtkNew) + 2*Abc_NtkPoNum(pNtkNew) + 2*Abc_NtkLatchNum(pNtkNew);
+// printf( "CNF variables = %d. CNF clauses = %d.\n", Abc_NtkNodeNum(pNtkNew), nClauses );
+ }
+//printf( "Maximum fanin = %d.\n", Abc_NtkGetFaninMax(pNtkNew) );
+
+ // make sure everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkRenode: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the AIG into nodes.]
+
+ Description [Threhold is the max number of nodes duplicated at a node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
+{
+ ProgressBar * pProgress;
+ Abc_Obj_t * pNode, * pConst1, * pNodeNew;
+ int i;
+
+ // set the constant node
+ pConst1 = Abc_AigConst1(pNtk->pManFunc);
+ if ( Abc_ObjFanoutNum(pConst1) > 0 )
+ {
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ pNodeNew->pData = Cudd_ReadOne( pNtkNew->pManFunc ); Cudd_Ref( pNodeNew->pData );
+ pConst1->pCopy = pNodeNew;
+ }
+
+ // perform renoding for POs
+ pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ if ( Abc_ObjIsCi(Abc_ObjFanin0(pNode)) )
+ continue;
+ Abc_NtkRenode_rec( pNtkNew, Abc_ObjFanin0(pNode) );
+ }
+ Extra_ProgressBarStop( pProgress );
+
+ // clean the boundaries and data field in the old network
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ {
+ pNode->fMarkA = 0;
+ pNode->pData = NULL;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find the best multi-input node rooted at the given node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld )
+{
+ Vec_Ptr_t * vCone;
+ Abc_Obj_t * pNodeNew;
+ int i;
+
+ assert( !Abc_ObjIsComplement(pNodeOld) );
+ // return if the result if known
+ if ( pNodeOld->pCopy )
+ return pNodeOld->pCopy;
+ assert( Abc_ObjIsNode(pNodeOld) );
+ assert( !Abc_NodeIsConst(pNodeOld) );
+ assert( pNodeOld->fMarkA );
+
+ // collect the renoding cone
+ vCone = Vec_PtrAlloc( 10 );
+ Abc_NtkRenodeCone( pNodeOld, vCone );
+
+ // create a new node
+ pNodeNew = Abc_NtkCreateNode( pNtkNew );
+ for ( i = 0; i < vCone->nSize; i++ )
+ Abc_ObjAddFanin( pNodeNew, Abc_NtkRenode_rec(pNtkNew, vCone->pArray[i]) );
+
+ // derive the function of this node
+ pNodeNew->pData = Abc_NtkRenodeDeriveBdd( pNtkNew->pManFunc, pNodeOld, vCone );
+ Cudd_Ref( pNodeNew->pData );
+ Vec_PtrFree( vCone );
+
+ // remember the node
+ pNodeOld->pCopy = pNodeNew;
+ return pNodeOld->pCopy;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives the local BDD of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NtkRenodeDeriveBdd( DdManager * dd, Abc_Obj_t * pNodeOld, Vec_Ptr_t * vFaninsOld )
+{
+ Abc_Obj_t * pFaninOld;
+ DdNode * bFunc;
+ int i;
+ assert( !Abc_NodeIsConst(pNodeOld) );
+ assert( Abc_ObjIsNode(pNodeOld) );
+ // set the elementary BDD variables for the input nodes
+ for ( i = 0; i < vFaninsOld->nSize; i++ )
+ {
+ pFaninOld = vFaninsOld->pArray[i];
+ pFaninOld->pData = Cudd_bddIthVar( dd, i ); Cudd_Ref( pFaninOld->pData );
+ pFaninOld->fMarkC = 1;
+ }
+ // call the recursive BDD computation
+ bFunc = Abc_NtkRenodeDeriveBdd_rec( dd, pNodeOld, vFaninsOld ); Cudd_Ref( bFunc );
+ // dereference the intermediate nodes
+ for ( i = 0; i < vFaninsOld->nSize; i++ )
+ {
+ pFaninOld = vFaninsOld->pArray[i];
+ Cudd_RecursiveDeref( dd, pFaninOld->pData );
+ pFaninOld->fMarkC = 0;
+ }
+ Cudd_Deref( bFunc );
+ return bFunc;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the local BDD of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NtkRenodeDeriveBdd_rec( DdManager * dd, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins )
+{
+ DdNode * bFunc, * bFunc0, * bFunc1;
+ assert( !Abc_ObjIsComplement(pNode) );
+ // if the result is available return
+ if ( pNode->fMarkC )
+ {
+ assert( pNode->pData ); // network has a cycle
+ return pNode->pData;
+ }
+ // mark the node as visited
+ pNode->fMarkC = 1;
+ Vec_PtrPush( vFanins, pNode );
+ // compute the result for both branches
+ bFunc0 = Abc_NtkRenodeDeriveBdd_rec( dd, Abc_ObjFanin(pNode,0), vFanins ); Cudd_Ref( bFunc0 );
+ bFunc1 = Abc_NtkRenodeDeriveBdd_rec( dd, Abc_ObjFanin(pNode,1), vFanins ); Cudd_Ref( bFunc1 );
+ bFunc0 = Cudd_NotCond( bFunc0, Abc_ObjFaninC0(pNode) );
+ bFunc1 = Cudd_NotCond( bFunc1, Abc_ObjFaninC1(pNode) );
+ // get the final result
+ bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc );
+ Cudd_RecursiveDeref( dd, bFunc0 );
+ Cudd_RecursiveDeref( dd, bFunc1 );
+ // set the result
+ pNode->pData = bFunc;
+ assert( pNode->pData );
+ return bFunc;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Limits the cones to be no more than the given size.]
+
+ Description [Returns 1 if the last cone was limited. Returns 0 if no changes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRenodeLimit_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, int nFaninMax, int fCanStop, int fFirst )
+{
+ int nNodes0, nNodes1;
+ assert( !Abc_ObjIsComplement(pNode) );
+ // check if the node should be added to the fanins
+ if ( !fFirst && (pNode->fMarkA || !Abc_ObjIsNode(pNode)) )
+ {
+ Vec_PtrPushUnique( vCone, pNode );
+ return 0;
+ }
+ // if we cannot stop in this branch, collect all nodes
+ if ( !fCanStop )
+ {
+ Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,0), vCone, nFaninMax, 0, 0 );
+ Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 );
+ return 0;
+ }
+ // if we can stop, try the left branch first, and return if we stopped
+ assert( vCone->nSize == 0 );
+ if ( Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,0), vCone, nFaninMax, 1, 0 ) )
+ return 1;
+ // save the number of nodes in the left branch and call for the right branch
+ nNodes0 = vCone->nSize;
+ assert( nNodes0 <= nFaninMax );
+ Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 );
+ // check the number of nodes
+ if ( vCone->nSize <= nFaninMax )
+ return 0;
+ // the number of nodes exceeds the limit
+
+ // get the number of nodes in the right branch
+ vCone->nSize = 0;
+ Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 0, 0 );
+ // if this number exceeds the limit, solve the problem for this branch
+ if ( vCone->nSize > nFaninMax )
+ {
+ int RetValue;
+ vCone->nSize = 0;
+ RetValue = Abc_NtkRenodeLimit_rec( Abc_ObjFanin(pNode,1), vCone, nFaninMax, 1, 0 );
+ assert( RetValue == 1 );
+ return 1;
+ }
+
+ nNodes1 = vCone->nSize;
+ assert( nNodes1 <= nFaninMax );
+ if ( nNodes0 >= nNodes1 )
+ { // the left branch is larger - cut it
+ assert( Abc_ObjFanin(pNode,0)->fMarkA == 0 );
+ Abc_ObjFanin(pNode,0)->fMarkA = 1;
+ }
+ else
+ { // the right branch is larger - cut it
+ assert( Abc_ObjFanin(pNode,1)->fMarkA == 0 );
+ Abc_ObjFanin(pNode,1)->fMarkA = 1;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Limits the cones to be no more than the given size.]
+
+ Description [Returns 1 if the last cone was limited. Returns 0 if no changes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRenodeLimit( Abc_Obj_t * pNode, Vec_Ptr_t * vCone, int nFaninMax )
+{
+ vCone->nSize = 0;
+ return Abc_NtkRenodeLimit_rec( pNode, vCone, nFaninMax, 1, 1 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the expansion boundary for multi-input nodes.]
+
+ Description [The boundary includes the set of PIs and all nodes such that
+ when expanding over the node we duplicate no more than nThresh nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeSetBounds( Abc_Ntk_t * pNtk, int nThresh, int nFaninMax )
+{
+ Vec_Ptr_t * vCone = pNtk->vPtrTemp;
+ Abc_Obj_t * pNode;
+ int i, nFanouts, nConeSize;
+
+ // make sure the mark is not set
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ assert( pNode->fMarkA == 0 );
+
+ // mark the nodes where expansion stops using pNode->fMarkA
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ // mark the nodes with multiple fanouts
+ nFanouts = Abc_ObjFanoutNum(pNode);
+ nConeSize = Abc_NodeMffcSize(pNode);
+ if ( (nFanouts - 1) * nConeSize > nThresh )
+ pNode->fMarkA = 1;
+ }
+
+ // mark the PO drivers
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+
+ // make sure the fanin limit is met
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ if ( pNode->fMarkA == 0 )
+ continue;
+ // continue cutting branches ntil it meets the fanin limit
+ while ( Abc_NtkRenodeLimit(pNode, vCone, nFaninMax) );
+ assert( vCone->nSize <= nFaninMax );
+ }
+/*
+ // make sure the fanin limit is met
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ if ( pNode->fMarkA == 0 )
+ continue;
+ Abc_NtkRenodeCone( pNode, vCone );
+ assert( vCone->nSize <= nFaninMax );
+ }
+*/
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the expansion boundary for conversion into CNF.]
+
+ Description [The boundary includes the set of PIs, the roots of MUXes,
+ the nodes with multiple fanouts and the nodes with complemented outputs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeSetBoundsCnf( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, nMuxes;
+
+ // make sure the mark is not set
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ assert( pNode->fMarkA == 0 );
+
+ // mark the nodes where expansion stops using pNode->fMarkA
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ // mark the nodes with multiple fanouts
+ if ( Abc_ObjFanoutNum(pNode) > 1 )
+ pNode->fMarkA = 1;
+ // mark the nodes that are roots of MUXes
+ if ( Abc_NodeIsMuxType( pNode ) )
+ {
+ pNode->fMarkA = 1;
+ Abc_ObjFanin0( Abc_ObjFanin0(pNode) )->fMarkA = 1;
+ Abc_ObjFanin0( Abc_ObjFanin1(pNode) )->fMarkA = 1;
+ Abc_ObjFanin1( Abc_ObjFanin0(pNode) )->fMarkA = 1;
+ Abc_ObjFanin1( Abc_ObjFanin1(pNode) )->fMarkA = 1;
+ }
+ else // mark the complemented edges
+ {
+ if ( Abc_ObjFaninC0(pNode) )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+ if ( Abc_ObjFaninC1(pNode) )
+ Abc_ObjFanin1(pNode)->fMarkA = 1;
+ }
+ }
+
+ // mark the PO drivers
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+
+ // count the number of MUXes
+ nMuxes = 0;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ if ( Abc_NodeIsMuxType(pNode) &&
+ Abc_ObjFanin0(pNode)->fMarkA == 0 &&
+ Abc_ObjFanin1(pNode)->fMarkA == 0 )
+ nMuxes++;
+ }
+ printf( "The number of MUXes detected = %d (%5.2f %% of logic).\n", nMuxes, 300.0*nMuxes/Abc_NtkNodeNum(pNtk) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the expansion boundary for conversion into multi-input AND graph.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeSetBoundsMulti( Abc_Ntk_t * pNtk, int nThresh )
+{
+ Abc_Obj_t * pNode;
+ int i, nFanouts, nConeSize;
+
+ // make sure the mark is not set
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ assert( pNode->fMarkA == 0 );
+
+ // mark the nodes where expansion stops using pNode->fMarkA
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // skip PI/PO nodes
+ if ( Abc_NodeIsConst(pNode) )
+ continue;
+ // mark the nodes with multiple fanouts
+// if ( Abc_ObjFanoutNum(pNode) > 1 )
+// pNode->fMarkA = 1;
+ // mark the nodes with multiple fanouts
+ nFanouts = Abc_ObjFanoutNum(pNode);
+ nConeSize = Abc_NodeMffcSizeStop(pNode);
+ if ( (nFanouts - 1) * nConeSize > nThresh )
+ pNode->fMarkA = 1;
+ // mark the children if they are pointed by the complemented edges
+ if ( Abc_ObjFaninC0(pNode) )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+ if ( Abc_ObjFaninC1(pNode) )
+ Abc_ObjFanin1(pNode)->fMarkA = 1;
+ }
+
+ // mark the PO drivers
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Abc_ObjFanin0(pNode)->fMarkA = 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets a simple boundary.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeSetBoundsSimple( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i;
+ // make sure the mark is not set
+ Abc_NtkForEachObj( pNtk, pNode, i )
+ assert( pNode->fMarkA == 0 );
+ // mark the nodes where expansion stops using pNode->fMarkA
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ pNode->fMarkA = 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the fanins of a large node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vCone )
+{
+ assert( !Abc_ObjIsComplement(pNode) );
+ if ( pNode->fMarkA || !Abc_ObjIsNode(pNode) )
+ {
+ Vec_PtrPushUnique( vCone, pNode );
+ return;
+ }
+ Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,0), vCone );
+ Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,1), vCone );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the fanins of a large node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkRenodeCone( Abc_Obj_t * pNode, Vec_Ptr_t * vCone )
+{
+ assert( !Abc_ObjIsComplement(pNode) );
+ assert( Abc_ObjIsNode(pNode) );
+ vCone->nSize = 0;
+ Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,0), vCone );
+ Abc_NtkRenodeCone_rec( Abc_ObjFanin(pNode,1), vCone );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c
new file mode 100644
index 00000000..75fe1627
--- /dev/null
+++ b/src/base/abci/abcRewrite.c
@@ -0,0 +1,184 @@
+/**CFile****************************************************************
+
+ FileName [abcRes.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Technology-independent resynthesis of the AIG.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcRes.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "rwr.h"
+#include "dec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop );
+static void Abc_NodePrintCuts( Abc_Obj_t * pNode );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs incremental rewriting of the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUseZeros, int fVerbose )
+{
+ int fCheck = 1;
+ int fDrop = 0;
+ ProgressBar * pProgress;
+ Cut_Man_t * pManCut;
+ Rwr_Man_t * pManRwr;
+ Abc_Obj_t * pNode;
+ int i, nNodes, nGain;
+ int clk, clkStart = clock();
+
+ assert( Abc_NtkIsStrash(pNtk) );
+ // cleanup the AIG
+ Abc_AigCleanup(pNtk->pManFunc);
+ // start the rewriting manager
+ pManRwr = Rwr_ManStart( 0 );
+ if ( pManRwr == NULL )
+ return 0;
+ Abc_NtkStartReverseLevels( pNtk );
+ // start the cut manager
+clk = clock();
+ pManCut = Abc_NtkStartCutManForRewrite( pNtk, fDrop );
+Rwr_ManAddTimeCuts( pManRwr, clock() - clk );
+ pNtk->pManCut = pManCut;
+
+ // resynthesize each node once
+ 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;
+ // for each cut, try to resynthesize it
+ nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUseZeros );
+ if ( nGain > 0 || nGain == 0 && fUseZeros )
+ {
+ Dec_Graph_t * pGraph = Rwr_ManReadDecs(pManRwr);
+ int fCompl = Rwr_ManReadCompl(pManRwr);
+ // complement the FF if needed
+ if ( fCompl ) Dec_GraphComplement( pGraph );
+ Dec_GraphUpdateNetwork( pNode, pGraph, nGain );
+ if ( fCompl ) Dec_GraphComplement( pGraph );
+ }
+ }
+ Extra_ProgressBarStop( pProgress );
+Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart );
+ // print stats
+ if ( fVerbose )
+ Rwr_ManPrintStats( pManRwr );
+ // delete the managers
+ Rwr_ManStop( pManRwr );
+ Cut_ManStop( pManCut );
+ pNtk->pManCut = NULL;
+ Abc_NtkStopReverseLevels( pNtk );
+ // check
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkRewrite: The network check has failed.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Starts the cut manager for rewriting.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk, int fDrop )
+{
+ static Cut_Params_t Params, * pParams = &Params;
+ Cut_Man_t * pManCut;
+ Abc_Obj_t * pObj;
+ int i;
+ // start the cut manager
+ memset( pParams, 0, sizeof(Cut_Params_t) );
+ pParams->nVarsMax = 4; // the max cut size ("k" of the k-feasible cuts)
+ pParams->nKeepMax = 250; // the max number of cuts kept at a node
+ pParams->fTruth = 1; // compute truth tables
+ pParams->fHash = 1; // hash cuts to detect unique
+ pParams->fFilter = 0; // filter dominated cuts
+ pParams->fSeq = 0; // compute sequential cuts
+ pParams->fDrop = fDrop; // drop cuts on the fly
+ pParams->fVerbose = 0; // the verbosiness flag
+ pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
+ pManCut = Cut_ManStart( pParams );
+ if ( pParams->fDrop )
+ Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) );
+ // set cuts for PIs
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ if ( Abc_ObjFanoutNum(pObj) > 0 )
+ Cut_NodeSetTriv( pManCut, pObj->Id );
+ return pManCut;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the cuts at the nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodePrintCuts( Abc_Obj_t * pNode )
+{
+ Cut_Cut_t * pCut;
+ unsigned uTruth;
+ printf( "\nNode %s\n", Abc_ObjName(pNode) );
+ for ( pCut = (Cut_Cut_t *)pNode->pCopy; pCut; pCut = pCut->pNext )
+ {
+ uTruth = pCut->uTruth;
+ Extra_PrintBinary( stdout, &uTruth, 16 );
+ printf( " " );
+ Cut_CutPrint( pCut );
+ printf( "\n" );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcSat.c b/src/base/abci/abcSat.c
new file mode 100644
index 00000000..4fb059e5
--- /dev/null
+++ b/src/base/abci/abcSat.c
@@ -0,0 +1,252 @@
+/**CFile****************************************************************
+
+ FileName [abcSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Procedures to solve the miter using the internal SAT solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars );
+static void Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Attempts to solve the miter using an internal SAT solver.]
+
+ Description [Returns 1 if the miter is SAT.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ solver * pSat;
+ lbool status;
+ int clk;
+
+ assert( Abc_NtkIsBddLogic(pNtk) );
+ assert( Abc_NtkLatchNum(pNtk) == 0 );
+
+ if ( Abc_NtkPoNum(pNtk) > 1 )
+ fprintf( stdout, "Warning: The miter has more than 1 output. SAT will try to prove all of them.\n" );
+
+ // load clauses into the solver
+ clk = clock();
+ pSat = Abc_NtkMiterSatCreate( pNtk );
+// printf( "Created SAT problem with %d variable and %d clauses. ",
+// solver_nvars(pSat), solver_nclauses(pSat) );
+// PRT( "Time", clock() - clk );
+
+ // simplify the problem
+ clk = clock();
+ status = solver_simplify(pSat);
+// printf( "Simplified the problem to %d variables and %d clauses. ",
+// solver_nvars(pSat), solver_nclauses(pSat) );
+// PRT( "Time", clock() - clk );
+ if ( status == l_False )
+ {
+ solver_delete( pSat );
+ printf( "The problem is UNSAT after simplification.\n" );
+ return 0;
+ }
+
+ // solve the miter
+ clk = clock();
+ if ( fVerbose )
+ pSat->verbosity = 1;
+ status = solver_solve( pSat, NULL, NULL );
+// if ( fVerbose )
+// {
+ printf( "The problem is %5s. ", (status == l_True)? "SAT" : "UNSAT" );
+ PRT( "SAT solver time", clock() - clk );
+// }
+ // free the solver
+ solver_delete( pSat );
+ return status == l_True;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets up the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk )
+{
+ solver * pSat;
+ Extra_MmFlex_t * pMmFlex;
+ Abc_Obj_t * pNode;
+ Vec_Str_t * vCube;
+ Vec_Int_t * vVars;
+ char * pSop0, * pSop1;
+ int i;
+
+ assert( Abc_NtkIsBddLogic(pNtk) );
+
+ // start the data structures
+ pSat = solver_new();
+ pMmFlex = Extra_MmFlexStart();
+ vCube = Vec_StrAlloc( 100 );
+ vVars = Vec_IntAlloc( 100 );
+
+ // add clauses for each internal nodes
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ // derive SOPs for both phases of the node
+ Abc_NodeBddToCnf( pNode, pMmFlex, vCube, &pSop0, &pSop1 );
+ // add the clauses to the solver
+ Abc_NodeAddClauses( pSat, pSop0, pSop1, pNode, vVars );
+ }
+ // add clauses for each PO
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ Abc_NodeAddClausesTop( pSat, pNode, vVars );
+
+ // delete
+ Vec_StrFree( vCube );
+ Vec_IntFree( vVars );
+ Extra_MmFlexStop( pMmFlex, 0 );
+ return pSat;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses for the internal node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars )
+{
+ Abc_Obj_t * pFanin;
+ int i, c, nFanins;
+ char * pCube;
+
+ nFanins = Abc_ObjFaninNum( pNode );
+ assert( nFanins == Abc_SopGetVarNum( pSop0 ) );
+
+ // add clauses for the negative phase
+ for ( c = 0; ; c++ )
+ {
+ // get the cube
+ pCube = pSop0 + c * (nFanins + 3);
+ if ( *pCube == 0 )
+ break;
+ // add the clause
+ vVars->nSize = 0;
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ if ( pCube[i] == '0' )
+ Vec_IntPush( vVars, toLit(pFanin->Id) );
+ else if ( pCube[i] == '1' )
+ Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
+ }
+ Vec_IntPush( vVars, neg(toLit(pNode->Id)) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+ }
+
+ // add clauses for the positive phase
+ for ( c = 0; ; c++ )
+ {
+ // get the cube
+ pCube = pSop1 + c * (nFanins + 3);
+ if ( *pCube == 0 )
+ break;
+ // add the clause
+ vVars->nSize = 0;
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ if ( pCube[i] == '0' )
+ Vec_IntPush( vVars, toLit(pFanin->Id) );
+ else if ( pCube[i] == '1' )
+ Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
+ }
+ Vec_IntPush( vVars, toLit(pNode->Id) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses for the PO node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
+{
+ Abc_Obj_t * pFanin;
+
+ pFanin = Abc_ObjFanin0(pNode);
+ if ( Abc_ObjFaninC0(pNode) )
+ {
+ vVars->nSize = 0;
+ Vec_IntPush( vVars, toLit(pFanin->Id) );
+ Vec_IntPush( vVars, toLit(pNode->Id) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+
+ vVars->nSize = 0;
+ Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
+ Vec_IntPush( vVars, neg(toLit(pNode->Id)) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+ }
+ else
+ {
+ vVars->nSize = 0;
+ Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
+ Vec_IntPush( vVars, toLit(pNode->Id) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+
+ vVars->nSize = 0;
+ Vec_IntPush( vVars, toLit(pFanin->Id) );
+ Vec_IntPush( vVars, neg(toLit(pNode->Id)) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+ }
+
+ vVars->nSize = 0;
+ Vec_IntPush( vVars, toLit(pNode->Id) );
+ solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcStrash.c b/src/base/abci/abcStrash.c
new file mode 100644
index 00000000..935f1300
--- /dev/null
+++ b/src/base/abci/abcStrash.c
@@ -0,0 +1,287 @@
+/**CFile****************************************************************
+
+ FileName [aigStrash.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Strashing of the current network.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: aigStrash.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "extra.h"
+#include "dec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// static functions
+static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fAllNodes );
+static Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop );
+static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop );
+
+extern char * Mio_GateReadSop( void * pGate );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates the strashed AIG network.]
+
+ Description [Converts the logic network or the AIG into a
+ structurally hashed AIG.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup )
+{
+ int fCheck = 1;
+ Abc_Ntk_t * pNtkAig;
+ int nNodes;
+
+ assert( !Abc_NtkIsNetlist(pNtk) );
+ if ( Abc_NtkIsBddLogic(pNtk) )
+ Abc_NtkBddToSop(pNtk);
+ // print warning about choice nodes
+ if ( Abc_NtkGetChoiceNum( pNtk ) )
+ printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" );
+ // perform strashing
+ pNtkAig = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG );
+ Abc_NtkStrashPerform( pNtk, pNtkAig, fAllNodes );
+ Abc_NtkFinalize( pNtk, pNtkAig );
+ // print warning about self-feed latches
+ if ( Abc_NtkCountSelfFeedLatches(pNtkAig) )
+ printf( "The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
+ if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
+ printf( "Cleanup has removed %d nodes.\n", nNodes );
+ // duplicate EXDC
+ if ( pNtk->pExdc )
+ pNtkAig->pExdc = Abc_NtkStrash( pNtk->pExdc, 0, 1 );
+ // make sure everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtkAig ) )
+ {
+ printf( "Abc_NtkStrash: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkAig );
+ return NULL;
+ }
+ return pNtkAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Appends the second network to the first.]
+
+ Description [Modifies the first network by adding the logic of the second.
+ Performs structural hashing while appending the networks. Does not add
+ the COs of the second. Does not change the second network. Returns 0
+ if the appending failed, 1 otherise.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
+{
+ int fCheck = 1;
+ Abc_Obj_t * pObj;
+ int i;
+ // the first network should be an AIG
+ assert( Abc_NtkIsStrash(pNtk1) );
+ assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) );
+ if ( Abc_NtkIsBddLogic(pNtk2) )
+ Abc_NtkBddToSop(pNtk2);
+ // check that the networks have the same PIs
+ // reorder PIs of pNtk2 according to pNtk1
+ if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1 ) )
+ return 0;
+ // perform strashing
+ Abc_NtkCleanCopy( pNtk2 );
+ Abc_NtkForEachCi( pNtk2, pObj, i )
+ pObj->pCopy = Abc_NtkCi(pNtk1, i);
+ // add pNtk2 to pNtk1 while strashing
+ Abc_NtkStrashPerform( pNtk2, pNtk1, 1 );
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtk1 ) )
+ {
+ printf( "Abc_NtkAppend: The network check has failed.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the network for strashing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes )
+{
+ ProgressBar * pProgress;
+ Abc_Aig_t * pMan = pNtkNew->pManFunc;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode, * pNodeNew, * pObj;
+ int i;
+
+ // perform strashing
+ vNodes = Abc_NtkDfs( pNtk, fAllNodes );
+ pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ Extra_ProgressBarUpdate( pProgress, i, NULL );
+ // get the node
+ assert( Abc_ObjIsNode(pNode) );
+ // strash the node
+ pNodeNew = Abc_NodeStrash( pMan, pNode );
+ // get the old object
+ pObj = Abc_ObjFanout0Ntk( pNode );
+ // make sure the node is not yet strashed
+ assert( pObj->pCopy == NULL );
+ // mark the old object with the new AIG node
+ pObj->pCopy = pNodeNew;
+ }
+ Vec_PtrFree( vNodes );
+ Extra_ProgressBarStop( pProgress );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Strashes one logic node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
+{
+ int fUseFactor = 1;
+ char * pSop;
+
+ assert( Abc_ObjIsNode(pNode) );
+
+ // consider the case when the graph is an AIG
+ if ( Abc_NtkIsStrash(pNode->pNtk) )
+ {
+ if ( Abc_NodeIsConst(pNode) )
+ return Abc_AigConst1(pMan);
+ return Abc_AigAnd( pMan, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
+ }
+
+ // get the SOP of the node
+ if ( Abc_NtkHasMapping(pNode->pNtk) )
+ pSop = Mio_GateReadSop(pNode->pData);
+ else
+ pSop = pNode->pData;
+
+ // consider the constant node
+ if ( Abc_NodeIsConst(pNode) )
+ return Abc_ObjNotCond( Abc_AigConst1(pMan), Abc_SopIsConst0(pSop) );
+
+ // decide when to use factoring
+ if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 )
+ return Abc_NodeStrashFactor( pMan, pNode, pSop );
+ return Abc_NodeStrashSop( pMan, pNode, pSop );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Strashes one logic node using its SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop )
+{
+ Abc_Obj_t * pFanin, * pAnd, * pSum;
+ Abc_Obj_t * pConst1 = Abc_AigConst1(pMan);
+ char * pCube;
+ int i, nFanins;
+
+ // get the number of node's fanins
+ nFanins = Abc_ObjFaninNum( pNode );
+ assert( nFanins == Abc_SopGetVarNum(pSop) );
+ // go through the cubes of the node's SOP
+ pSum = Abc_ObjNot(pConst1);
+ Abc_SopForEachCube( pSop, nFanins, pCube )
+ {
+ // create the AND of literals
+ pAnd = pConst1;
+ Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net
+ {
+ if ( pCube[i] == '1' )
+ pAnd = Abc_AigAnd( pMan, pAnd, pFanin->pCopy );
+ else if ( pCube[i] == '0' )
+ pAnd = Abc_AigAnd( pMan, pAnd, Abc_ObjNot(pFanin->pCopy) );
+ }
+ // add to the sum of cubes
+ pSum = Abc_AigOr( pMan, pSum, pAnd );
+ }
+ // decide whether to complement the result
+ if ( Abc_SopIsComplement(pSop) )
+ pSum = Abc_ObjNot(pSum);
+ return pSum;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Strashes one logic node using its SOP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pSop )
+{
+ Dec_Graph_t * pFForm;
+ Dec_Node_t * pNode;
+ Abc_Obj_t * pAnd;
+ int i;
+ // perform factoring
+ pFForm = Dec_Factor( pSop );
+ // collect the fanins
+ Dec_GraphForEachLeaf( pFForm, pNode, i )
+ pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy;
+ // perform strashing
+ pAnd = Dec_GraphToNetwork( pMan, pFForm );
+ Dec_GraphFree( pFForm );
+ return pAnd;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcSweep.c b/src/base/abci/abcSweep.c
new file mode 100644
index 00000000..ca9bd34e
--- /dev/null
+++ b/src/base/abci/abcSweep.c
@@ -0,0 +1,607 @@
+/**CFile****************************************************************
+
+ FileName [abcDsd.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Technology dependent sweep.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcDsd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fraig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes );
+
+static stmm_table * Abc_NtkFraigEquiv( Fraig_Man_t * p, Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose );
+static void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose );
+static void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fVerbose, int fUseInv );
+static void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fVerbose, int fUseInv );
+static int Abc_NodeDroppingCost( Abc_Obj_t * pNode );
+
+static void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose );
+static void Abc_NodeConstantInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin, bool fConst0 );
+static void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Sweping functionally equivalence nodes.]
+
+ Description [Removes gates with equivalent functionality. Works for
+ both technology-independent and mapped networks. If the flag is set,
+ allows adding inverters at the gate outputs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose )
+{
+ int fCheck = 1;
+ Fraig_Params_t Params;
+ Abc_Ntk_t * pNtkAig;
+ Fraig_Man_t * pMan;
+ stmm_table * tEquiv;
+
+ assert( !Abc_NtkIsStrash(pNtk) );
+
+ // derive the AIG
+ pNtkAig = Abc_NtkStrash( pNtk, 0, 1 );
+ // perform fraiging of the AIG
+ Fraig_ParamsSetDefault( &Params );
+ pMan = Abc_NtkToFraig( pNtkAig, &Params, 0 );
+ // collect the classes of equivalent nets
+ tEquiv = Abc_NtkFraigEquiv( pMan, pNtk, fUseInv, fVerbose );
+
+ // transform the network into the equivalent one
+ Abc_NtkFraigTransform( pNtk, tEquiv, fUseInv, fVerbose );
+ stmm_free_table( tEquiv );
+
+ // free the manager
+ Fraig_ManFree( pMan );
+ Abc_NtkDelete( pNtkAig );
+
+ // cleanup the dangling nodes
+ Abc_NtkCleanup( pNtk, fVerbose );
+ // check
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkFraigSweep: The network check has failed.\n" );
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects equivalence classses of node in the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+stmm_table * Abc_NtkFraigEquiv( Fraig_Man_t * p, Abc_Ntk_t * pNtk, int fUseInv, bool fVerbose )
+{
+ Abc_Obj_t * pList, * pNode, * pNodeAig;
+ Fraig_Node_t * gNode;
+ Abc_Obj_t ** ppSlot;
+ stmm_table * tStrash2Net;
+ stmm_table * tResult;
+ stmm_generator * gen;
+ int c, Counter;
+
+ // create mapping of strashed nodes into the corresponding network nodes
+ tStrash2Net = stmm_init_table(stmm_ptrcmp,stmm_ptrhash);
+ Abc_NtkForEachNode( pNtk, pNode, c )
+ {
+ // get the strashed node
+ pNodeAig = pNode->pCopy;
+ // skip the dangling nodes
+ if ( pNodeAig == NULL )
+ continue;
+ // skip the constant input nodes
+ if ( Abc_ObjFaninNum(pNode) == 0 )
+ continue;
+ // skip the nodes that fanout into POs
+ if ( Abc_NodeHasUniqueCoFanout(pNode) )
+ continue;
+ // get the FRAIG node
+ gNode = Fraig_NotCond( Abc_ObjRegular(pNodeAig)->pCopy, Abc_ObjIsComplement(pNodeAig) );
+ if ( !stmm_find_or_add( tStrash2Net, (char *)Fraig_Regular(gNode), (char ***)&ppSlot ) )
+ *ppSlot = NULL;
+ // add the node to the list
+ pNode->pNext = *ppSlot;
+ *ppSlot = pNode;
+ // mark the node if it is complemented
+ pNode->fPhase = Fraig_IsComplement(gNode);
+ }
+
+ // print the classes
+ c = 0;
+ Counter = 0;
+ tResult = stmm_init_table(stmm_ptrcmp,stmm_ptrhash);
+ stmm_foreach_item( tStrash2Net, gen, (char **)&gNode, (char **)&pList )
+ {
+ // skip the trival classes
+ if ( pList == NULL || pList->pNext == NULL )
+ continue;
+ // add the non-trival class
+ stmm_insert( tResult, (char *)pList, NULL );
+ // count nodes in the non-trival classes
+ for ( pNode = pList; pNode; pNode = pNode->pNext )
+ Counter++;
+/*
+ if ( fVerbose )
+ {
+ printf( "Class %2d : {", c );
+ for ( pNode = pList; pNode; pNode = pNode->pNext )
+ {
+ pNode->pCopy = NULL;
+ printf( " %s", Abc_ObjName(pNode) );
+ if ( pNode->fPhase ) printf( "(*)" );
+ }
+ printf( " }\n" );
+ c++;
+ }
+*/
+ }
+ if ( fVerbose )
+ {
+ printf( "Sweeping stats for network \"%s\":\n", pNtk->pName );
+ printf( "Internal nodes = %d. Different functions (up to compl) = %d.\n", Abc_NtkNodeNum(pNtk), stmm_count(tStrash2Net) );
+ printf( "Non-trivial classes = %d. Nodes in non-trivial classes = %d.\n", stmm_count(tResult), Counter );
+ }
+ stmm_free_table( tStrash2Net );
+ return tResult;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the network using the equivalence relation on nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose )
+{
+ stmm_generator * gen;
+ Abc_Obj_t * pList;
+ if ( stmm_count(tEquiv) == 0 )
+ return;
+ // assign levels to the nodes of the network
+ Abc_NtkGetLevelNum( pNtk );
+ // merge nodes in the classes
+ if ( Abc_NtkHasMapping( pNtk ) )
+ {
+ Abc_NtkDelayTrace( pNtk );
+ stmm_foreach_item( tEquiv, gen, (char **)&pList, NULL )
+ Abc_NtkFraigMergeClassMapped( pNtk, pList, fUseInv, fVerbose );
+ }
+ else
+ {
+ stmm_foreach_item( tEquiv, gen, (char **)&pList, NULL )
+ Abc_NtkFraigMergeClass( pNtk, pList, fUseInv, fVerbose );
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Transforms the list of one-phase equivalent nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose )
+{
+ Abc_Obj_t * pListDir, * pListInv;
+ Abc_Obj_t * pNodeMin, * pNode, * pNext;
+ float Arrival1, Arrival2;
+
+ assert( pChain );
+ assert( pChain->pNext );
+
+ // divide the nodes into two parts:
+ // those that need the invertor and those that don't need
+ pListDir = pListInv = NULL;
+ for ( pNode = pChain, pNext = pChain->pNext;
+ pNode;
+ pNode = pNext, pNext = pNode? pNode->pNext : NULL )
+ {
+ // check to which class the node belongs
+ if ( pNode->fPhase == 1 )
+ {
+ pNode->pNext = pListDir;
+ pListDir = pNode;
+ }
+ else
+ {
+ pNode->pNext = pListInv;
+ pListInv = pNode;
+ }
+ }
+
+ // find the node with the smallest number of logic levels
+ pNodeMin = pListDir;
+ for ( pNode = pListDir; pNode; pNode = pNode->pNext )
+ {
+ Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst;
+ Arrival2 = Abc_NodeReadArrival(pNode )->Worst;
+ assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 );
+ assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 );
+ if ( Arrival1 > Arrival2 ||
+ Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level ||
+ Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level &&
+ Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) )
+ pNodeMin = pNode;
+ }
+
+ // move the fanouts of the direct nodes
+ for ( pNode = pListDir; pNode; pNode = pNode->pNext )
+ if ( pNode != pNodeMin )
+ Abc_ObjTransferFanout( pNode, pNodeMin );
+
+ // find the node with the smallest number of logic levels
+ pNodeMin = pListInv;
+ for ( pNode = pListInv; pNode; pNode = pNode->pNext )
+ {
+ Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst;
+ Arrival2 = Abc_NodeReadArrival(pNode )->Worst;
+ assert( Abc_ObjIsCi(pNodeMin) || Arrival1 > 0 );
+ assert( Abc_ObjIsCi(pNode) || Arrival2 > 0 );
+ if ( Arrival1 > Arrival2 ||
+ Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level ||
+ Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level &&
+ Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) )
+ pNodeMin = pNode;
+ }
+
+ // move the fanouts of the direct nodes
+ for ( pNode = pListInv; pNode; pNode = pNode->pNext )
+ if ( pNode != pNodeMin )
+ Abc_ObjTransferFanout( pNode, pNodeMin );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Process one equivalence class of nodes.]
+
+ Description [This function does not remove the nodes. It only switches
+ around the connections.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose )
+{
+ Abc_Obj_t * pListDir, * pListInv;
+ Abc_Obj_t * pNodeMin, * pNodeMinInv;
+ Abc_Obj_t * pNode, * pNext;
+
+ assert( pChain );
+ assert( pChain->pNext );
+
+ // find the node with the smallest number of logic levels
+ pNodeMin = pChain;
+ for ( pNode = pChain->pNext; pNode; pNode = pNode->pNext )
+ if ( pNodeMin->Level > pNode->Level ||
+ ( pNodeMin->Level == pNode->Level &&
+ Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) ) )
+ pNodeMin = pNode;
+
+ // divide the nodes into two parts:
+ // those that need the invertor and those that don't need
+ pListDir = pListInv = NULL;
+ for ( pNode = pChain, pNext = pChain->pNext;
+ pNode;
+ pNode = pNext, pNext = pNode? pNode->pNext : NULL )
+ {
+ if ( pNode == pNodeMin )
+ continue;
+ // check to which class the node belongs
+ if ( pNodeMin->fPhase == pNode->fPhase )
+ {
+ pNode->pNext = pListDir;
+ pListDir = pNode;
+ }
+ else
+ {
+ pNode->pNext = pListInv;
+ pListInv = pNode;
+ }
+ }
+
+ // move the fanouts of the direct nodes
+ for ( pNode = pListDir; pNode; pNode = pNode->pNext )
+ Abc_ObjTransferFanout( pNode, pNodeMin );
+
+ // skip if there are no inverted nodes
+ if ( pListInv == NULL )
+ return;
+
+ // add the invertor
+ pNodeMinInv = Abc_NodeCreateInv( pNtk, pNodeMin );
+
+ // move the fanouts of the inverted nodes
+ for ( pNode = pListInv; pNode; pNode = pNode->pNext )
+ Abc_ObjTransferFanout( pNode, pNodeMinInv );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Returns the number of literals saved if this node becomes useless.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeDroppingCost( Abc_Obj_t * pNode )
+{
+ return 1;
+}
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Removes dangling nodes.]
+
+ Description [Returns the number of nodes removed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ int fCheck = 1;
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pNode;
+ int i, Counter;
+ // mark the nodes reachable from the POs
+ vNodes = Abc_NtkDfs( pNtk, 0 );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ {
+ pNode = vNodes->pArray[i];
+ pNode->fMarkA = 1;
+ }
+ Vec_PtrFree( vNodes );
+ // if it is an AIG, also mark the constant 1 node
+ if ( Abc_NtkIsStrash(pNtk) )
+ Abc_AigConst1(pNtk->pManFunc)->fMarkA = 1;
+ // remove the non-marked nodes
+ Counter = 0;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ if ( pNode->fMarkA == 0 )
+ {
+ Abc_NtkDeleteObj( pNode );
+ Counter++;
+ }
+ // unmark the remaining nodes
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ pNode->fMarkA = 0;
+ if ( fVerbose )
+ printf( "Cleanup removed %d dangling nodes.\n", Counter );
+ // check
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkCleanup: The network check has failed.\n" );
+ return -1;
+ }
+ return Counter;
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Tranditional sweep of the network.]
+
+ Description [Propagates constant and single-input node, removes dangling nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ int fCheck = 1;
+ Abc_Obj_t * pNode;
+ int i, fConvert, nSwept, nSweptNew;
+ assert( Abc_NtkIsSopLogic(pNtk) || Abc_NtkIsBddLogic(pNtk) );
+ // convert to the BDD representation
+ fConvert = 0;
+ if ( Abc_NtkIsSopLogic(pNtk) )
+ Abc_NtkSopToBdd(pNtk), fConvert = 1;
+ // perform cleanup to get rid of dangling nodes
+ nSwept = Abc_NtkCleanup( pNtk, 0 );
+ // make the network minimum base
+ Abc_NtkRemoveDupFanins(pNtk);
+ Abc_NtkMinimumBase(pNtk);
+ do
+ {
+ // sweep constants and single-input nodes
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ if ( Abc_ObjFaninNum(pNode) < 2 )
+ Abc_NodeSweep( pNode, fVerbose );
+ // make the network minimum base
+ Abc_NtkRemoveDupFanins(pNtk);
+ Abc_NtkMinimumBase(pNtk);
+ // perform final clean up (in case new danglies are created)
+ nSweptNew = Abc_NtkCleanup( pNtk, 0 );
+ nSwept += nSweptNew;
+ }
+ while ( nSweptNew );
+ // conver back to BDD
+ if ( fConvert )
+ Abc_NtkBddToSop(pNtk);
+ // report
+ if ( fVerbose )
+ printf( "Sweep removed %d nodes.\n", nSwept );
+ // check
+ if ( fCheck && !Abc_NtkCheck( pNtk ) )
+ {
+ printf( "Abc_NtkSweep: The network check has failed.\n" );
+ return -1;
+ }
+ return nSwept;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Tranditional sweep of the network.]
+
+ Description [Propagates constant and single-input node, removes dangling nodes.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose )
+{
+ Vec_Ptr_t * vFanout = pNode->pNtk->vPtrTemp;
+ Abc_Obj_t * pFanout, * pDriver;
+ int i;
+ assert( Abc_ObjFaninNum(pNode) < 2 );
+ assert( Abc_ObjFanoutNum(pNode) > 0 );
+ // iterate through the fanouts
+ Abc_NodeCollectFanouts( pNode, vFanout );
+ Vec_PtrForEachEntry( vFanout, pFanout, i )
+ {
+ if ( Abc_ObjIsCo(pFanout) )
+ {
+ if ( Abc_ObjFaninNum(pNode) == 1 )
+ {
+ pDriver = Abc_ObjFanin0(pNode);
+ if ( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 1 || Abc_ObjFanoutNum(pNode) > 1 )
+ continue;
+ // the driver is a node and its only fanout is this node
+ if ( Abc_NodeIsInv(pNode) )
+ pDriver->pData = Cudd_Not(pDriver->pData);
+ // replace the fanin of the fanout
+ Abc_ObjPatchFanin( pFanout, pNode, pDriver );
+ }
+ continue;
+ }
+ // the fanout is a regular node
+ if ( Abc_ObjFaninNum(pNode) == 0 )
+ Abc_NodeConstantInput( pFanout, pNode, Abc_NodeIsConst0(pNode) );
+ else
+ {
+ assert( Abc_ObjFaninNum(pNode) == 1 );
+ pDriver = Abc_ObjFanin0(pNode);
+ if ( Abc_NodeIsInv(pNode) )
+ Abc_NodeComplementInput( pFanout, pNode );
+ Abc_ObjPatchFanin( pFanout, pNode, pDriver );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Replaces the local function by its cofactor.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeConstantInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin, bool fConst0 )
+{
+ DdManager * dd = pNode->pNtk->pManFunc;
+ DdNode * bVar, * bTemp;
+ int iFanin;
+ assert( Abc_NtkIsBddLogic(pNode->pNtk) );
+ if ( (iFanin = Vec_FanFindEntry( &pNode->vFanins, pFanin->Id )) == -1 )
+ {
+ printf( "Node %s should be among", Abc_ObjName(pFanin) );
+ printf( " the fanins of node %s...\n", Abc_ObjName(pNode) );
+ return;
+ }
+ bVar = Cudd_NotCond( Cudd_bddIthVar(dd, iFanin), fConst0 );
+ pNode->pData = Cudd_Cofactor( dd, bTemp = pNode->pData, bVar ); Cudd_Ref( pNode->pData );
+ Cudd_RecursiveDeref( dd, bTemp );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Changes the polarity of one fanin.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin )
+{
+ DdManager * dd = pNode->pNtk->pManFunc;
+ DdNode * bVar, * bCof0, * bCof1;
+ int iFanin;
+ assert( Abc_NtkIsBddLogic(pNode->pNtk) );
+ if ( (iFanin = Vec_FanFindEntry( &pNode->vFanins, pFanin->Id )) == -1 )
+ {
+ printf( "Node %s should be among", Abc_ObjName(pFanin) );
+ printf( " the fanins of node %s...\n", Abc_ObjName(pNode) );
+ return;
+ }
+ bVar = Cudd_bddIthVar( dd, iFanin );
+ bCof0 = Cudd_Cofactor( dd, pNode->pData, Cudd_Not(bVar) ); Cudd_Ref( bCof0 );
+ bCof1 = Cudd_Cofactor( dd, pNode->pData, bVar ); Cudd_Ref( bCof1 );
+ Cudd_RecursiveDeref( dd, pNode->pData );
+ pNode->pData = Cudd_bddIte( dd, bVar, bCof0, bCof1 ); Cudd_Ref( pNode->pData );
+ Cudd_RecursiveDeref( dd, bCof0 );
+ Cudd_RecursiveDeref( dd, bCof1 );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcSymm.c b/src/base/abci/abcSymm.c
new file mode 100644
index 00000000..f9229639
--- /dev/null
+++ b/src/base/abci/abcSymm.c
@@ -0,0 +1,221 @@
+/**CFile****************************************************************
+
+ FileName [abcSymm.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Computation of two-variable symmetries.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcSymm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose );
+static void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose );
+static void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose );
+static void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [The top level procedure to compute symmetries.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose )
+{
+ if ( fUseBdds || fNaive )
+ Abc_NtkSymmetriesUsingBdds( pNtk, fNaive, fVerbose );
+ else
+ Abc_NtkSymmetriesUsingSandS( pNtk, fVerbose );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Symmetry computation using simulation and SAT.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ extern int Sim_ComputeTwoVarSymms( Abc_Ntk_t * pNtk );
+ int nSymms = Sim_ComputeTwoVarSymms( pNtk );
+ printf( "The total number of symmetries is %d.\n", nSymms );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Symmetry computation using BDDs (both naive and smart).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fVerbose )
+{
+ DdManager * dd;
+ int clk, clkBdd, clkSym;
+
+ // compute the global functions
+clk = clock();
+ dd = Abc_NtkGlobalBdds( pNtk, 0 );
+ Cudd_AutodynDisable( dd );
+ Cudd_zddVarsFromBddVars( dd, 2 );
+clkBdd = clock() - clk;
+ // create the collapsed network
+clk = clock();
+ Ntk_NetworkSymmsBdd( dd, pNtk, fNaive, fVerbose );
+clkSym = clock() - clk;
+ // undo the global functions
+ Abc_NtkFreeGlobalBdds( pNtk );
+ Extra_StopManager( dd );
+ pNtk->pManGlob = NULL;
+
+PRT( "Constructing BDDs", clkBdd );
+PRT( "Computing symms ", clkSym );
+PRT( "TOTAL ", clkBdd + clkSym );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Symmetry computation using BDDs (both naive and smart).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose )
+{
+ Extra_SymmInfo_t * pSymms;
+ Abc_Obj_t * pNode;
+ DdNode * bFunc;
+ int nSymms = 0;
+ int i;
+
+ // compute symmetry info for each PO
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ bFunc = pNtk->vFuncsGlob->pArray[i];
+ if ( Cudd_IsConstant(bFunc) )
+ continue;
+ if ( fNaive )
+ pSymms = Extra_SymmPairsComputeNaive( dd, bFunc );
+ else
+ pSymms = Extra_SymmPairsCompute( dd, bFunc );
+ nSymms += pSymms->nSymms;
+ if ( fVerbose )
+ {
+ printf( "Output %6s (%d): ", Abc_ObjName(pNode), pSymms->nSymms );
+ Ntk_NetworkSymmsPrint( pNtk, pSymms );
+ }
+//Extra_SymmPairsPrint( pSymms );
+ Extra_SymmPairsDissolve( pSymms );
+ }
+ printf( "The total number of symmetries is %d.\n", nSymms );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Printing symmetry groups from the symmetry data structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms )
+{
+ char ** pInputNames;
+ int * pVarTaken;
+ int i, k, nVars, nSize, fStart;
+
+ // get variable names
+ nVars = Abc_NtkCiNum(pNtk);
+ pInputNames = Abc_NtkCollectCioNames( pNtk, 0 );
+
+ // alloc the array of marks
+ pVarTaken = ALLOC( int, nVars );
+ memset( pVarTaken, 0, sizeof(int) * nVars );
+
+ // print the groups
+ fStart = 1;
+ nSize = pSymms->nVars;
+ for ( i = 0; i < nSize; i++ )
+ {
+ // skip the variable already considered
+ if ( pVarTaken[i] )
+ continue;
+ // find all the vars symmetric with this one
+ for ( k = 0; k < nSize; k++ )
+ {
+ if ( k == i )
+ continue;
+ if ( pSymms->pSymms[i][k] == 0 )
+ continue;
+ // vars i and k are symmetric
+ assert( pVarTaken[k] == 0 );
+ // there is a new symmetry pair
+ if ( fStart == 1 )
+ { // start a new symmetry class
+ fStart = 0;
+ printf( " { %s", pInputNames[ pSymms->pVars[i] ] );
+ // mark the var as taken
+ pVarTaken[i] = 1;
+ }
+ printf( " %s", pInputNames[ pSymms->pVars[k] ] );
+ // mark the var as taken
+ pVarTaken[k] = 1;
+ }
+ if ( fStart == 0 )
+ {
+ printf( " }" );
+ fStart = 1;
+ }
+ }
+ printf( "\n" );
+
+ free( pInputNames );
+ free( pVarTaken );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcTiming.c b/src/base/abci/abcTiming.c
new file mode 100644
index 00000000..b8524bd5
--- /dev/null
+++ b/src/base/abci/abcTiming.c
@@ -0,0 +1,755 @@
+/**CFile****************************************************************
+
+ FileName [abcTiming.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Computation of timing info for mapped circuits.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcTiming.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "main.h"
+#include "mio.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct Abc_ManTime_t_
+{
+ Abc_Time_t tArrDef;
+ Abc_Time_t tReqDef;
+ Vec_Ptr_t * vArrs;
+ Vec_Ptr_t * vReqs;
+};
+
+// static functions
+static Abc_ManTime_t * Abc_ManTimeStart();
+static void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive );
+static void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk );
+
+static void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode );
+
+// accessing the arrival and required times of a node
+static inline Abc_Time_t * Abc_NodeArrival( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vArrs->pArray[pNode->Id]; }
+static inline Abc_Time_t * Abc_NodeRequired( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vReqs->pArray[pNode->Id]; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode )
+{
+ assert( pNode->pNtk->pManTime );
+ return Abc_NodeArrival(pNode);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode )
+{
+ assert( pNode->pNtk->pManTime );
+ return Abc_NodeRequired(pNode);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NtkReadDefaultArrival( Abc_Ntk_t * pNtk )
+{
+ assert( pNtk->pManTime );
+ return &pNtk->pManTime->tArrDef;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk )
+{
+ assert( pNtk->pManTime );
+ return &pNtk->pManTime->tReqDef;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the default arrival time for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetDefaultArrival( Abc_Ntk_t * pNtk, float Rise, float Fall )
+{
+ if ( Rise == 0.0 && Fall == 0.0 )
+ return;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ pNtk->pManTime->tArrDef.Rise = Rise;
+ pNtk->pManTime->tArrDef.Fall = Fall;
+ pNtk->pManTime->tArrDef.Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the default arrival time for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall )
+{
+ if ( Rise == 0.0 && Fall == 0.0 )
+ return;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ pNtk->pManTime->tReqDef.Rise = Rise;
+ pNtk->pManTime->tReqDef.Rise = Fall;
+ pNtk->pManTime->tReqDef.Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the arrival time for an object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall )
+{
+ Vec_Ptr_t * vTimes;
+ Abc_Time_t * pTime;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ if ( pNtk->pManTime->tArrDef.Rise == Rise && pNtk->pManTime->tArrDef.Fall == Fall )
+ return;
+ Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 );
+ // set the arrival time
+ vTimes = pNtk->pManTime->vArrs;
+ pTime = vTimes->pArray[ObjId];
+ pTime->Rise = Rise;
+ pTime->Fall = Rise;
+ pTime->Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the arrival time for an object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall )
+{
+ Vec_Ptr_t * vTimes;
+ Abc_Time_t * pTime;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ if ( pNtk->pManTime->tReqDef.Rise == Rise && pNtk->pManTime->tReqDef.Fall == Fall )
+ return;
+ Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 );
+ // set the required time
+ vTimes = pNtk->pManTime->vReqs;
+ pTime = vTimes->pArray[ObjId];
+ pTime->Rise = Rise;
+ pTime->Fall = Rise;
+ pTime->Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finalizes the timing manager after setting arr/req times.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ Abc_Time_t ** ppTimes, * pTime;
+ int i;
+ if ( pNtk->pManTime == NULL )
+ return;
+ Abc_ManTimeExpand( pNtk->pManTime, Abc_NtkObjNumMax(pNtk), 0 );
+ // set the default timing
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ if ( pTime->Worst != -ABC_INFINITY )
+ continue;
+ *pTime = pNtk->pManTime->tArrDef;
+ }
+ // set the default timing
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vReqs->pArray;
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ if ( pTime->Worst != -ABC_INFINITY )
+ continue;
+ *pTime = pNtk->pManTime->tReqDef;
+ }
+ // set the 0 arrival times for latches and constant nodes
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ pTime->Fall = pTime->Rise = pTime->Worst = 0.0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the timing manager for delay trace.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ Abc_Time_t ** ppTimes, * pTime;
+ int i;
+ // if there is no timing manager, allocate and initialize
+ if ( pNtk->pManTime == NULL )
+ {
+ pNtk->pManTime = Abc_ManTimeStart();
+ Abc_NtkTimeInitialize( pNtk );
+ return;
+ }
+ // if timing manager is given, expand it if necessary
+ Abc_ManTimeExpand( pNtk->pManTime, Abc_NtkObjNumMax(pNtk), 0 );
+ // clean arrivals except for PIs
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
+ }
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
+ }
+ // clean required except for POs
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_ManTime_t * Abc_ManTimeStart()
+{
+ Abc_ManTime_t * p;
+ p = ALLOC( Abc_ManTime_t, 1 );
+ memset( p, 0, sizeof(Abc_ManTime_t) );
+ p->vArrs = Vec_PtrAlloc( 0 );
+ p->vReqs = Vec_PtrAlloc( 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManTimeStop( Abc_ManTime_t * p )
+{
+ if ( p->vArrs->nSize > 0 )
+ {
+ free( p->vArrs->pArray[0] );
+ Vec_PtrFree( p->vArrs );
+ }
+ if ( p->vReqs->nSize > 0 )
+ {
+ free( p->vReqs->pArray[0] );
+ Vec_PtrFree( p->vReqs );
+ }
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the timing manager with the PI/PO timing info.]
+
+ Description [The PIs/POs of the new network should be allocated.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew )
+{
+ Abc_Obj_t * pObj;
+ Abc_Time_t ** ppTimesOld, ** ppTimesNew;
+ int i;
+ if ( pNtkOld->pManTime == NULL )
+ return;
+ assert( Abc_NtkPiNum(pNtkOld) == Abc_NtkPiNum(pNtkNew) );
+ assert( Abc_NtkPoNum(pNtkOld) == Abc_NtkPoNum(pNtkNew) );
+ assert( Abc_NtkLatchNum(pNtkOld) == Abc_NtkLatchNum(pNtkNew) );
+ // create the new timing manager
+ pNtkNew->pManTime = Abc_ManTimeStart();
+ Abc_ManTimeExpand( pNtkNew->pManTime, Abc_NtkObjNumMax(pNtkNew), 0 );
+ // set the default timing
+ pNtkNew->pManTime->tArrDef = pNtkOld->pManTime->tArrDef;
+ pNtkNew->pManTime->tReqDef = pNtkOld->pManTime->tReqDef;
+ // set the CI timing
+ ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vArrs->pArray;
+ ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vArrs->pArray;
+ Abc_NtkForEachCi( pNtkOld, pObj, i )
+ *ppTimesNew[ Abc_NtkCi(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
+ // set the CO timing
+ ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vReqs->pArray;
+ ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vReqs->pArray;
+ Abc_NtkForEachCo( pNtkOld, pObj, i )
+ *ppTimesNew[ Abc_NtkCo(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Expends the storage for timing information.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive )
+{
+ Vec_Ptr_t * vTimes;
+ Abc_Time_t * ppTimes, * ppTimesOld, * pTime;
+ int nSizeOld, nSizeNew, i;
+
+ nSizeOld = p->vArrs->nSize;
+ if ( nSizeOld >= nSize )
+ return;
+ nSizeNew = fProgressive? 2 * nSize : nSize;
+ if ( nSizeNew < 100 )
+ nSizeNew = 100;
+
+ vTimes = p->vArrs;
+ Vec_PtrGrow( vTimes, nSizeNew );
+ vTimes->nSize = nSizeNew;
+ ppTimesOld = ( nSizeOld == 0 )? NULL : vTimes->pArray[0];
+ ppTimes = REALLOC( Abc_Time_t, ppTimesOld, nSizeNew );
+ for ( i = 0; i < nSizeNew; i++ )
+ vTimes->pArray[i] = ppTimes + i;
+ for ( i = nSizeOld; i < nSizeNew; i++ )
+ {
+ pTime = vTimes->pArray[i];
+ pTime->Rise = -ABC_INFINITY;
+ pTime->Fall = -ABC_INFINITY;
+ pTime->Worst = -ABC_INFINITY;
+ }
+
+ vTimes = p->vReqs;
+ Vec_PtrGrow( vTimes, nSizeNew );
+ vTimes->nSize = nSizeNew;
+ ppTimesOld = ( nSizeOld == 0 )? NULL : vTimes->pArray[0];
+ ppTimes = REALLOC( Abc_Time_t, ppTimesOld, nSizeNew );
+ for ( i = 0; i < nSizeNew; i++ )
+ vTimes->pArray[i] = ppTimes + i;
+ for ( i = nSizeOld; i < nSizeNew; i++ )
+ {
+ pTime = vTimes->pArray[i];
+ pTime->Rise = -ABC_INFINITY;
+ pTime->Fall = -ABC_INFINITY;
+ pTime->Worst = -ABC_INFINITY;
+ }
+}
+
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Sets the CI node levels according to the arrival info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtkOld )
+{
+ Abc_Obj_t * pNodeOld, * pNodeNew;
+ float tAndDelay;
+ int i;
+ if ( pNtkOld->pManTime == NULL )
+ return;
+ if ( Mio_LibraryReadNand2(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) == NULL )
+ return;
+ tAndDelay = Mio_LibraryReadDelayNand2Max(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
+ Abc_NtkForEachPi( pNtkOld, pNodeOld, i )
+ {
+ pNodeNew = pNodeOld->pCopy;
+ pNodeNew->Level = (int)(Abc_NodeArrival(pNodeOld)->Worst / tAndDelay);
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the CI node levels according to the arrival info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NtkGetCiArrivalTimes( Abc_Ntk_t * pNtk )
+{
+ Abc_Time_t * p;
+ Abc_Obj_t * pNode;
+ int i;
+ p = ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtk) );
+ memset( p, 0, sizeof(Abc_Time_t) * Abc_NtkCiNum(pNtk) );
+ if ( pNtk->pManTime == NULL )
+ return p;
+ // set the PI arrival times
+ Abc_NtkForEachPi( pNtk, pNode, i )
+ p[i] = *Abc_NodeArrival(pNode);
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Sets the CI node levels according to the arrival info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk )
+{
+ float * p;
+ Abc_Obj_t * pNode;
+ int i;
+ p = ALLOC( float, Abc_NtkCiNum(pNtk) );
+ memset( p, 0, sizeof(float) * Abc_NtkCiNum(pNtk) );
+ if ( pNtk->pManTime == NULL )
+ return p;
+ // set the PI arrival times
+ Abc_NtkForEachPi( pNtk, pNode, i )
+ p[i] = Abc_NodeArrival(pNode)->Worst;
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode, * pDriver;
+ Vec_Ptr_t * vNodes;
+ Abc_Time_t * pTime;
+ float tArrivalMax;
+ int i;
+
+ assert( Abc_NtkIsMappedLogic(pNtk) );
+
+ Abc_NtkTimePrepare( pNtk );
+ vNodes = Abc_NtkDfs( pNtk, 1 );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ Abc_NodeDelayTraceArrival( vNodes->pArray[i] );
+ Vec_PtrFree( vNodes );
+
+ // get the latest arrival times
+ tArrivalMax = -ABC_INFINITY;
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ pDriver = Abc_ObjFanin0(pNode);
+ pTime = Abc_NodeArrival(pDriver);
+ if ( tArrivalMax < pTime->Worst )
+ tArrivalMax = pTime->Worst;
+ }
+ return tArrivalMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pFanin;
+ Abc_Time_t * pTimeIn, * pTimeOut;
+ float tDelayBlockRise, tDelayBlockFall;
+ Mio_PinPhase_t PinPhase;
+ Mio_Pin_t * pPin;
+ int i;
+
+ // start the arrival time of the node
+ pTimeOut = Abc_NodeArrival(pNode);
+ pTimeOut->Rise = pTimeOut->Fall = 0;
+ // go through the pins of the gate
+ pPin = Mio_GateReadPins(pNode->pData);
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ pTimeIn = Abc_NodeArrival(pFanin);
+ assert( pTimeIn->Worst != -ABC_INFINITY );
+ // get the interesting parameters of this pin
+ PinPhase = Mio_PinReadPhase(pPin);
+ tDelayBlockRise = (float)Mio_PinReadDelayBlockRise( pPin );
+ tDelayBlockFall = (float)Mio_PinReadDelayBlockFall( pPin );
+ // compute the arrival times of the positive phase
+ if ( PinPhase != MIO_PHASE_INV ) // NONINV phase is present
+ {
+ if ( pTimeOut->Rise < pTimeIn->Rise + tDelayBlockRise )
+ pTimeOut->Rise = pTimeIn->Rise + tDelayBlockRise;
+ if ( pTimeOut->Fall < pTimeIn->Fall + tDelayBlockFall )
+ pTimeOut->Fall = pTimeIn->Fall + tDelayBlockFall;
+ }
+ if ( PinPhase != MIO_PHASE_NONINV ) // INV phase is present
+ {
+ if ( pTimeOut->Rise < pTimeIn->Fall + tDelayBlockRise )
+ pTimeOut->Rise = pTimeIn->Fall + tDelayBlockRise;
+ if ( pTimeOut->Fall < pTimeIn->Rise + tDelayBlockFall )
+ pTimeOut->Fall = pTimeIn->Rise + tDelayBlockFall;
+ }
+ pPin = Mio_PinReadNext(pPin);
+ }
+ pTimeOut->Worst = ABC_MAX( pTimeOut->Rise, pTimeOut->Fall );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the AIG for the comptuation of required levels.]
+
+ Description [This procedure should be called before the required times
+ are used. It starts internal data structures, which records the level
+ from the COs of the AIG nodes in reverse topologogical order.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkStartReverseLevels( Abc_Ntk_t * pNtk )
+{
+ Vec_Ptr_t * vNodes;
+ Abc_Obj_t * pObj, * pFanout;
+ int i, k, nLevelsCur;
+ assert( Abc_NtkIsStrash(pNtk) );
+ // remember the maximum number of direct levels
+ pNtk->LevelMax = Abc_AigGetLevelNum(pNtk);
+ // start the reverse levels
+ pNtk->vLevelsR = Vec_IntAlloc( 0 );
+ Vec_IntFill( pNtk->vLevelsR, Abc_NtkObjNumMax(pNtk), 0 );
+ // compute levels in reverse topological order
+ vNodes = Abc_NtkDfsReverse( pNtk );
+ Vec_PtrForEachEntry( vNodes, pObj, i )
+ {
+ nLevelsCur = 0;
+ Abc_ObjForEachFanout( pObj, pFanout, k )
+ if ( nLevelsCur < Vec_IntEntry(pNtk->vLevelsR, pFanout->Id) )
+ nLevelsCur = Vec_IntEntry(pNtk->vLevelsR, pFanout->Id);
+ Vec_IntWriteEntry( pNtk->vLevelsR, pObj->Id, nLevelsCur + 1 );
+ }
+ Vec_PtrFree( vNodes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Cleans the data structures used to compute required levels.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkStopReverseLevels( Abc_Ntk_t * pNtk )
+{
+ assert( pNtk->vLevelsR );
+ Vec_IntFree( pNtk->vLevelsR );
+ pNtk->vLevelsR = NULL;
+ pNtk->LevelMax = 0;
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the reverse level of the node.]
+
+ Description [The reverse level is the level of the node in reverse
+ topological order, starting from the COs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeSetReverseLevel( Abc_Obj_t * pObj, int LevelR )
+{
+ Abc_Ntk_t * pNtk = pObj->pNtk;
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( pNtk->vLevelsR );
+ Vec_IntFillExtra( pNtk->vLevelsR, pObj->Id + 1, 0 );
+ Vec_IntWriteEntry( pNtk->vLevelsR, pObj->Id, LevelR );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the reverse level of the node.]
+
+ Description [The reverse level is the level of the node in reverse
+ topological order, starting from the COs.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeReadReverseLevel( Abc_Obj_t * pObj )
+{
+ Abc_Ntk_t * pNtk = pObj->pNtk;
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( pNtk->vLevelsR );
+ Vec_IntFillExtra( pNtk->vLevelsR, pObj->Id + 1, 0 );
+ return Vec_IntEntry(pNtk->vLevelsR, pObj->Id);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns required level of the node.]
+
+ Description [Converts the reverse levels of the node into its required
+ level as follows: ReqLevel(Node) = MaxLevels(Ntk) + 1 - LevelR(Node).]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NodeReadRequiredLevel( Abc_Obj_t * pObj )
+{
+ Abc_Ntk_t * pNtk = pObj->pNtk;
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( pNtk->vLevelsR );
+ return pNtk->LevelMax + 1 - Vec_IntEntry(pNtk->vLevelsR, pObj->Id);
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcUnreach.c b/src/base/abci/abcUnreach.c
new file mode 100644
index 00000000..0fe3ec63
--- /dev/null
+++ b/src/base/abci/abcUnreach.c
@@ -0,0 +1,336 @@
+/**CFile****************************************************************
+
+ FileName [abcUnreach.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Computes unreachable states for small benchmarks.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcUnreach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose );
+static DdNode * Abc_NtkInitStateAndVarMap( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose );
+static DdNode * Abc_NtkComputeUnreachable( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bRelation, DdNode * bInitial, bool fVerbose );
+static Abc_Ntk_t * Abc_NtkConstructExdc ( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUnreach );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Extracts sequential DCs of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, bool fVerbose )
+{
+ int fCheck = 1;
+ int fReorder = 1;
+ DdManager * dd;
+ DdNode * bRelation, * bInitial, * bUnreach;
+
+ // remove EXDC network if present
+ if ( pNtk->pExdc )
+ {
+ Abc_NtkDelete( pNtk->pExdc );
+ pNtk->pExdc = NULL;
+ }
+
+ // compute the global BDDs of the latches
+ dd = Abc_NtkGlobalBdds( pNtk, 1 );
+ if ( dd == NULL )
+ return 0;
+ if ( fVerbose )
+ printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
+
+ // create the transition relation (dereferenced global BDDs)
+ bRelation = Abc_NtkTransitionRelation( dd, pNtk, fVerbose ); Cudd_Ref( bRelation );
+ // create the initial state and the variable map
+ bInitial = Abc_NtkInitStateAndVarMap( dd, pNtk, fVerbose ); Cudd_Ref( bInitial );
+ // compute the unreachable states
+ bUnreach = Abc_NtkComputeUnreachable( dd, pNtk, bRelation, bInitial, fVerbose ); Cudd_Ref( bUnreach );
+ Cudd_RecursiveDeref( dd, bRelation );
+ Cudd_RecursiveDeref( dd, bInitial );
+
+ // reorder and disable reordering
+ if ( fReorder )
+ {
+ if ( fVerbose )
+ fprintf( stdout, "BDD nodes in the unreachable states before reordering %d.\n", Cudd_DagSize(bUnreach) );
+ Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 );
+ Cudd_AutodynDisable( dd );
+ if ( fVerbose )
+ fprintf( stdout, "BDD nodes in the unreachable states after reordering %d.\n", Cudd_DagSize(bUnreach) );
+ }
+
+ // allocate ZDD variables
+ Cudd_zddVarsFromBddVars( dd, 2 );
+ // create the EXDC network representing the unreachable states
+ pNtk->pExdc = Abc_NtkConstructExdc( dd, pNtk, bUnreach );
+ Cudd_RecursiveDeref( dd, bUnreach );
+ Extra_StopManager( dd );
+ pNtk->pManGlob = NULL;
+
+ // make sure that everything is okay
+ if ( fCheck && !Abc_NtkCheck( pNtk->pExdc ) )
+ {
+ printf( "Abc_NtkExtractSequentialDcs: The network check has failed.\n" );
+ Abc_NtkDelete( pNtk->pExdc );
+ return 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the transition relation of the network.]
+
+ Description [Assumes that the global BDDs are computed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose )
+{
+ DdNode * bRel, * bTemp, * bProd, * bVar, * bInputs;
+ Abc_Obj_t * pNode;
+ int fReorder = 1;
+ int i;
+
+ // extand the BDD manager to represent NS variables
+ assert( dd->size == Abc_NtkCiNum(pNtk) );
+ Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + Abc_NtkLatchNum(pNtk) - 1 );
+
+ // enable reordering
+ if ( fReorder )
+ Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
+ else
+ Cudd_AutodynDisable( dd );
+
+ // compute the transition relation
+ bRel = b1; Cudd_Ref( bRel );
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ {
+ bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i );
+ bProd = Cudd_bddXnor( dd, bVar, pNtk->vFuncsGlob->pArray[i] ); Cudd_Ref( bProd );
+ bRel = Cudd_bddAnd( dd, bTemp = bRel, bProd ); Cudd_Ref( bRel );
+ Cudd_RecursiveDeref( dd, bTemp );
+ Cudd_RecursiveDeref( dd, bProd );
+ }
+ // free the global BDDs
+ Abc_NtkFreeGlobalBdds( pNtk );
+
+ // quantify the PI variables
+ bInputs = Extra_bddComputeRangeCube( dd, 0, Abc_NtkPiNum(pNtk) ); Cudd_Ref( bInputs );
+ bRel = Cudd_bddExistAbstract( dd, bTemp = bRel, bInputs ); Cudd_Ref( bRel );
+ Cudd_RecursiveDeref( dd, bTemp );
+ Cudd_RecursiveDeref( dd, bInputs );
+
+ // reorder and disable reordering
+ if ( fReorder )
+ {
+ if ( fVerbose )
+ fprintf( stdout, "BDD nodes in the transition relation before reordering %d.\n", Cudd_DagSize(bRel) );
+ Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 );
+ Cudd_AutodynDisable( dd );
+ if ( fVerbose )
+ fprintf( stdout, "BDD nodes in the transition relation after reordering %d.\n", Cudd_DagSize(bRel) );
+ }
+ Cudd_Deref( bRel );
+ return bRel;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the initial state and sets up the variable map.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NtkInitStateAndVarMap( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose )
+{
+ DdNode ** pbVarsX, ** pbVarsY;
+ DdNode * bTemp, * bProd, * bVar;
+ Abc_Obj_t * pLatch;
+ int i;
+
+ // set the variable mapping for Cudd_bddVarMap()
+ pbVarsX = ALLOC( DdNode *, dd->size );
+ pbVarsY = ALLOC( DdNode *, dd->size );
+ bProd = b1; Cudd_Ref( bProd );
+ Abc_NtkForEachLatch( pNtk, pLatch, i )
+ {
+ pbVarsX[i] = dd->vars[ Abc_NtkPiNum(pNtk) + i ];
+ pbVarsY[i] = dd->vars[ Abc_NtkCiNum(pNtk) + i ];
+ // get the initial value of the latch
+ bVar = Cudd_NotCond( pbVarsX[i], !Abc_LatchIsInit1(pLatch) );
+ bProd = Cudd_bddAnd( dd, bTemp = bProd, bVar ); Cudd_Ref( bProd );
+ Cudd_RecursiveDeref( dd, bTemp );
+ }
+ Cudd_SetVarMap( dd, pbVarsX, pbVarsY, Abc_NtkLatchNum(pNtk) );
+ FREE( pbVarsX );
+ FREE( pbVarsY );
+
+ Cudd_Deref( bProd );
+ return bProd;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes the set of unreachable states.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+DdNode * Abc_NtkComputeUnreachable( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bTrans, DdNode * bInitial, bool fVerbose )
+{
+ DdNode * bRelation, * bReached, * bCubeCs;
+ DdNode * bCurrent, * bNext, * bTemp;
+ int nIters;
+
+ // perform reachability analisys
+ bCurrent = bInitial; Cudd_Ref( bCurrent );
+ bReached = bInitial; Cudd_Ref( bReached );
+ bRelation = bTrans; Cudd_Ref( bRelation );
+ bCubeCs = Extra_bddComputeRangeCube( dd, Abc_NtkPiNum(pNtk), Abc_NtkCiNum(pNtk) ); Cudd_Ref( bCubeCs );
+ for ( nIters = 1; ; nIters++ )
+ {
+ // compute the next states
+ bNext = Cudd_bddAndAbstract( dd, bRelation, bCurrent, bCubeCs ); Cudd_Ref( bNext );
+ Cudd_RecursiveDeref( dd, bCurrent );
+ // remap these states into the current state vars
+ bNext = Cudd_bddVarMap( dd, bTemp = bNext ); Cudd_Ref( bNext );
+ Cudd_RecursiveDeref( dd, bTemp );
+ // check if there are any new states
+ if ( Cudd_bddLeq( dd, bNext, bReached ) )
+ break;
+ // get the new states
+ bCurrent = Cudd_bddAnd( dd, bNext, Cudd_Not(bReached) ); Cudd_Ref( bCurrent );
+ // minimize the new states with the reached states
+// bCurrent = Cudd_bddConstrain( dd, bTemp = bCurrent, Cudd_Not(bReached) ); Cudd_Ref( bCurrent );
+// Cudd_RecursiveDeref( dd, bTemp );
+ // add to the reached states
+ bReached = Cudd_bddOr( dd, bTemp = bReached, bNext ); Cudd_Ref( bReached );
+ Cudd_RecursiveDeref( dd, bTemp );
+ Cudd_RecursiveDeref( dd, bNext );
+ // minimize the transition relation
+// bRelation = Cudd_bddConstrain( dd, bTemp = bRelation, Cudd_Not(bReached) ); Cudd_Ref( bRelation );
+// Cudd_RecursiveDeref( dd, bTemp );
+ }
+ Cudd_RecursiveDeref( dd, bRelation );
+ Cudd_RecursiveDeref( dd, bCubeCs );
+ Cudd_RecursiveDeref( dd, bNext );
+ // report the stats
+ if ( fVerbose )
+ {
+ fprintf( stdout, "Reachability analysis completed in %d iterations.\n", nIters );
+ fprintf( stdout, "The number of minterms in the reachable state set = %d.\n",
+ (int)Cudd_CountMinterm(dd, bReached, Abc_NtkLatchNum(pNtk) ) );
+ }
+//PRB( dd, bReached );
+ Cudd_Deref( bReached );
+ return Cudd_Not( bReached );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates the EXDC network.]
+
+ Description [The set of unreachable states depends on CS variables.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUnreach )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pNode, * pNodeNew;
+ int * pPermute;
+ int i;
+
+ // start the new network
+ pNtkNew = Abc_NtkAlloc( ABC_TYPE_LOGIC, ABC_FUNC_BDD );
+ // create PIs corresponding to LOs
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ pNode->pCopy = Abc_NtkCreatePi(pNtkNew);
+
+ // create a new node
+ pNodeNew = Abc_NtkCreateNode(pNtkNew);
+ // add the fanins corresponding to latch outputs
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ Abc_ObjAddFanin( pNodeNew, pNode->pCopy );
+
+ // create the logic function
+ pPermute = ALLOC( int, dd->size );
+ for ( i = 0; i < dd->size; i++ )
+ pPermute[i] = -1;
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ pPermute[Abc_NtkPiNum(pNtk) + i] = i;
+ // remap the functions
+ pNodeNew->pData = Extra_TransferPermute( dd, pNtkNew->pManFunc, bUnreach, pPermute ); Cudd_Ref( pNodeNew->pData );
+ free( pPermute );
+ Abc_NodeMinimumBase( pNodeNew );
+
+ // make the new node drive all the COs
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew );
+
+ // store the PI names of the EXDC network
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ Abc_NtkLogicStoreName( Abc_NtkPi(pNtkNew,i), Abc_ObjName(pNode) );
+ // store the PO names of the EXDC network
+ Abc_NtkForEachPo( pNtk, pNode, i )
+ Abc_NtkLogicStoreName( Abc_NtkPo(pNtkNew,i), Abc_ObjName(pNode) );
+ Abc_NtkForEachLatch( pNtk, pNode, i )
+ Abc_NtkLogicStoreName( Abc_NtkCo(pNtkNew,Abc_NtkPoNum(pNtk) + i), Abc_ObjNameSuffix(pNode, "_in") );
+
+ // make the network minimum base
+ Abc_NtkMinimumBase( pNtkNew );
+
+ // fix the problem with complemented and duplicated CO edges
+ Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
+
+ // transform the network to the SOP representation
+ Abc_NtkBddToSop( pNtkNew );
+ return pNtkNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c
new file mode 100644
index 00000000..55d6cf7d
--- /dev/null
+++ b/src/base/abci/abcVerify.c
@@ -0,0 +1,311 @@
+/**CFile****************************************************************
+
+ FileName [abcVerify.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Combinational and sequential verification for two networks.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcVerify.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "fraig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Verifies combinational equivalence by brute-force SAT.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 )
+{
+ Abc_Ntk_t * pMiter;
+ Abc_Ntk_t * pCnf;
+ int RetValue;
+
+ // get the miter of the two networks
+ pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1 );
+ if ( pMiter == NULL )
+ {
+ printf( "Miter computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pMiter );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are equivalent after structural hashing.\n" );
+ return;
+ }
+
+ // convert the miter into a CNF
+ pCnf = Abc_NtkRenode( pMiter, 0, 100, 1, 0, 0 );
+ Abc_NtkDelete( pMiter );
+ if ( pCnf == NULL )
+ {
+ printf( "Renoding for CNF has failed.\n" );
+ return;
+ }
+
+ // solve the CNF using the SAT solver
+ if ( Abc_NtkMiterSat( pCnf, 0 ) )
+ printf( "Networks are NOT EQUIVALENT after SAT.\n" );
+ else
+ printf( "Networks are equivalent after SAT.\n" );
+ Abc_NtkDelete( pCnf );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Verifies sequential equivalence by fraiging followed by SAT.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fVerbose )
+{
+ Fraig_Params_t Params;
+ Abc_Ntk_t * pMiter;
+ Abc_Ntk_t * pFraig;
+ int RetValue;
+
+ // get the miter of the two networks
+ pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1 );
+ if ( pMiter == NULL )
+ {
+ printf( "Miter computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pMiter );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are equivalent after structural hashing.\n" );
+ return;
+ }
+
+ // convert the miter into a FRAIG
+ Fraig_ParamsSetDefault( &Params );
+ Params.fVerbose = fVerbose;
+ pFraig = Abc_NtkFraig( pMiter, &Params, 0 );
+ Abc_NtkDelete( pMiter );
+ if ( pFraig == NULL )
+ {
+ printf( "Fraiging has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pFraig );
+ Abc_NtkDelete( pFraig );
+ if ( RetValue == 0 )
+ {
+ printf( "Networks are equivalent after fraiging.\n" );
+ return;
+ }
+ printf( "Networks are NOT EQUIVALENT after fraiging.\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verifies sequential equivalence by brute-force SAT.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames )
+{
+ Abc_Ntk_t * pMiter;
+ Abc_Ntk_t * pFrames;
+ Abc_Ntk_t * pCnf;
+ int RetValue;
+
+ // get the miter of the two networks
+ pMiter = Abc_NtkMiter( pNtk1, pNtk2, 0 );
+ if ( pMiter == NULL )
+ {
+ printf( "Miter computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pMiter );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are equivalent after structural hashing.\n" );
+ return;
+ }
+
+ // create the timeframes
+ pFrames = Abc_NtkFrames( pMiter, nFrames, 1 );
+ Abc_NtkDelete( pMiter );
+ if ( pFrames == NULL )
+ {
+ printf( "Frames computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pFrames );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pFrames );
+ printf( "Networks are NOT EQUIVALENT after framing.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pFrames );
+ printf( "Networks are equivalent after framing.\n" );
+ return;
+ }
+
+ // convert the miter into a CNF
+ pCnf = Abc_NtkRenode( pFrames, 0, 100, 1, 0, 0 );
+ Abc_NtkDelete( pFrames );
+ if ( pCnf == NULL )
+ {
+ printf( "Renoding for CNF has failed.\n" );
+ return;
+ }
+
+ // solve the CNF using the SAT solver
+ if ( Abc_NtkMiterSat( pCnf, 0 ) )
+ printf( "Networks are NOT EQUIVALENT after SAT.\n" );
+ else
+ printf( "Networks are equivalent after SAT.\n" );
+ Abc_NtkDelete( pCnf );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verifies combinational equivalence by fraiging followed by SAT]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames )
+{
+ Fraig_Params_t Params;
+ Abc_Ntk_t * pMiter;
+ Abc_Ntk_t * pFraig;
+ Abc_Ntk_t * pFrames;
+ int RetValue;
+
+ // get the miter of the two networks
+ pMiter = Abc_NtkMiter( pNtk1, pNtk2, 0 );
+ if ( pMiter == NULL )
+ {
+ printf( "Miter computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pMiter );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pMiter );
+ printf( "Networks are equivalent after structural hashing.\n" );
+ return;
+ }
+
+ // create the timeframes
+ pFrames = Abc_NtkFrames( pMiter, nFrames, 1 );
+ Abc_NtkDelete( pMiter );
+ if ( pFrames == NULL )
+ {
+ printf( "Frames computation has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pFrames );
+ if ( RetValue == 1 )
+ {
+ Abc_NtkDelete( pFrames );
+ printf( "Networks are NOT EQUIVALENT after framing.\n" );
+ return;
+ }
+ if ( RetValue == 0 )
+ {
+ Abc_NtkDelete( pFrames );
+ printf( "Networks are equivalent after framing.\n" );
+ return;
+ }
+
+ // convert the miter into a FRAIG
+ Fraig_ParamsSetDefault( &Params );
+ pFraig = Abc_NtkFraig( pFrames, &Params, 0 );
+ Abc_NtkDelete( pFrames );
+ if ( pFraig == NULL )
+ {
+ printf( "Fraiging has failed.\n" );
+ return;
+ }
+ RetValue = Abc_NtkMiterIsConstant( pFraig );
+ Abc_NtkDelete( pFraig );
+ if ( RetValue == 0 )
+ {
+ printf( "Networks are equivalent after fraiging.\n" );
+ return;
+ }
+ printf( "Networks are NOT EQUIVALENT after fraiging.\n" );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abc_.c b/src/base/abci/abc_.c
new file mode 100644
index 00000000..bef3836f
--- /dev/null
+++ b/src/base/abci/abc_.c
@@ -0,0 +1,47 @@
+/**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 ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/module.make b/src/base/abci/module.make
new file mode 100644
index 00000000..d7c0add2
--- /dev/null
+++ b/src/base/abci/module.make
@@ -0,0 +1,24 @@
+SRC += src/base/abci/abc.c \
+ src/base/abci/abcAttach.c \
+ src/base/abci/abcBalance.c \
+ src/base/abci/abcCollapse.c \
+ src/base/abci/abcCut.c \
+ src/base/abci/abcDsd.c \
+ src/base/abci/abcFpga.c \
+ src/base/abci/abcFraig.c \
+ src/base/abci/abcFxu.c \
+ src/base/abci/abcMap.c \
+ src/base/abci/abcMiter.c \
+ src/base/abci/abcNtbdd.c \
+ src/base/abci/abcPrint.c \
+ src/base/abci/abcReconv.c \
+ src/base/abci/abcRefactor.c \
+ src/base/abci/abcRenode.c \
+ src/base/abci/abcRewrite.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/abcUnreach.c \
+ src/base/abci/abcVerify.c