diff options
Diffstat (limited to 'src')
59 files changed, 4328 insertions, 222 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index cbdf87c7..7ace4880 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -425,7 +425,7 @@ extern void Abc_AigSetNodePhases( Abc_Ntk_t * pNtk ); /*=== abcAttach.c ==========================================================*/ extern int Abc_NtkAttach( Abc_Ntk_t * pNtk ); /*=== abcBalance.c ==========================================================*/ -extern Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate ); +extern Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate, bool fSelective ); /*=== abcCheck.c ==========================================================*/ extern bool Abc_NtkCheck( Abc_Ntk_t * pNtk ); extern bool Abc_NtkCheckRead( Abc_Ntk_t * pNtk ); @@ -587,6 +587,7 @@ extern DdNode * Abc_NodeConeDcs( DdManager * dd, DdNode ** pbVarsX, Dd extern Vec_Ptr_t * Abc_NodeCollectTfoCands( Abc_ManCut_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins, int LevelMax ); /*=== abcRefs.c ==========================================================*/ extern int Abc_NodeMffcSize( Abc_Obj_t * pNode ); +extern int Abc_NodeMffcSizeSupp( Abc_Obj_t * pNode ); extern int Abc_NodeMffcSizeStop( Abc_Obj_t * pNode ); extern int Abc_NodeMffcLabel( Abc_Obj_t * pNode ); extern int Abc_NodeMffcLabelFast( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ); @@ -673,6 +674,7 @@ extern int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk ); extern void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk ); extern void Abc_NtkCleanNext( Abc_Ntk_t * pNtk ); +extern void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk ); extern Abc_Obj_t * Abc_NodeHasUniqueCoFanout( Abc_Obj_t * pNode ); extern bool Abc_NtkLogicHasSimpleCos( Abc_Ntk_t * pNtk ); extern int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, bool fDuplicate ); diff --git a/src/base/abc/abcRefs.c b/src/base/abc/abcRefs.c index 04647d0b..5d0c68d1 100644 --- a/src/base/abc/abcRefs.c +++ b/src/base/abc/abcRefs.c @@ -25,6 +25,7 @@ //////////////////////////////////////////////////////////////////////// static int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel, Vec_Ptr_t * vNodes ); +static int Abc_NodeMffcCountSupp( Vec_Ptr_t * vNodes ); static int Abc_NodeRefDerefStop( Abc_Obj_t * pNode, bool fReference ); static int Abc_NodeDeref( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ); @@ -46,6 +47,7 @@ static int Abc_NodeDeref( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ); int Abc_NodeMffcSize( Abc_Obj_t * pNode ) { int nConeSize1, nConeSize2; + assert( Abc_NtkIsStrash(pNode->pNtk) ); assert( !Abc_ObjIsComplement( pNode ) ); assert( Abc_ObjIsNode( pNode ) ); if ( Abc_ObjFaninNum(pNode) == 0 ) @@ -59,6 +61,36 @@ int Abc_NodeMffcSize( Abc_Obj_t * pNode ) /**Function************************************************************* + Synopsis [Returns the MFFC size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeMffcSizeSupp( Abc_Obj_t * pNode ) +{ + Vec_Ptr_t * vNodes; + int nSuppSize, nConeSize1, nConeSize2; + assert( Abc_NtkIsStrash(pNode->pNtk) ); + assert( !Abc_ObjIsComplement( pNode ) ); + assert( Abc_ObjIsNode( pNode ) ); + if ( Abc_ObjFaninNum(pNode) == 0 ) + return 0; + vNodes = Vec_PtrAlloc( 10 ); + nConeSize1 = Abc_NodeRefDeref( pNode, 0, 0, vNodes ); // dereference + nSuppSize = Abc_NodeMffcCountSupp(vNodes); + nConeSize2 = Abc_NodeRefDeref( pNode, 1, 0, NULL ); // reference + assert( nConeSize1 == nConeSize2 ); + assert( nConeSize1 > 0 ); + Vec_PtrFree(vNodes); + return nSuppSize; +} + +/**Function************************************************************* + Synopsis [Returns the MFFC size while stopping at the complemented edges.] Description [] @@ -71,6 +103,7 @@ int Abc_NodeMffcSize( Abc_Obj_t * pNode ) int Abc_NodeMffcSizeStop( Abc_Obj_t * pNode ) { int nConeSize1, nConeSize2; + assert( Abc_NtkIsStrash(pNode->pNtk) ); assert( !Abc_ObjIsComplement( pNode ) ); assert( Abc_ObjIsNode( pNode ) ); if ( Abc_ObjFaninNum(pNode) == 0 ) @@ -219,6 +252,61 @@ int Abc_NodeRefDeref( Abc_Obj_t * pNode, bool fReference, bool fLabel, Vec_Ptr_t /**Function************************************************************* + Synopsis [References/references the node and returns MFFC supp size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NodeMffcCountSupp( Vec_Ptr_t * vNodes ) +{ + Abc_Obj_t * pNode, * pNode0, * pNode1; + int i, Counter = 0; + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + if ( Abc_ObjIsCi(pNode) ) + { + if ( pNode->fMarkB == 0 ) + { + pNode->fMarkB = 1; + Counter++; + } + continue; + } + pNode0 = Abc_ObjFanin0(pNode); + if ( pNode0->vFanouts.nSize > 0 && pNode0->fMarkB == 0 ) + { + pNode0->fMarkB = 1; + Counter++; + } + pNode1 = Abc_ObjFanin1(pNode); + if ( pNode1->vFanouts.nSize > 0 && pNode1->fMarkB == 0 ) + { + pNode1->fMarkB = 1; + Counter++; + } + } + Vec_PtrForEachEntry( vNodes, pNode, i ) + { + if ( Abc_ObjIsCi(pNode) ) + { + pNode->fMarkB = 0; + continue; + } + pNode0 = Abc_ObjFanin0(pNode); + pNode0->fMarkB = 0; + pNode1 = Abc_ObjFanin1(pNode); + pNode1->fMarkB = 0; + } + return Counter; + +} + +/**Function************************************************************* + Synopsis [References/references the node and returns MFFC size.] Description [] diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c index 4152dd0a..1e59b17b 100644 --- a/src/base/abc/abcSop.c +++ b/src/base/abc/abcSop.c @@ -308,7 +308,7 @@ char * Abc_SopCreateXorSpecial( Extra_MmFlex_t * pMan, int nVars ) char * Abc_SopCreateNxor( Extra_MmFlex_t * pMan, int nVars ) { assert( nVars == 2 ); - return Abc_SopRegister(pMan, "11 1\n11 1\n"); + return Abc_SopRegister(pMan, "11 1\n00 1\n"); } /**Function************************************************************* diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 9d95fade..1e52e4a6 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -335,6 +335,25 @@ void Abc_NtkCleanNext( Abc_Ntk_t * pNtk ) /**Function************************************************************* + Synopsis [Cleans the copy field of all objects.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkCleanMarkA( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i = 0; + Abc_NtkForEachObj( pNtk, pObj, i ) + pObj->fMarkA = 0; +} + +/**Function************************************************************* + Synopsis [Checks if the internal node has a unique CO.] Description [Checks if the internal node can borrow a name from a CO diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 5f5c4b49..119f8cdf 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40,6 +40,8 @@ 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_CommandPrintUnate ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintAuto ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintKMap ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintGates ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintSharing ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -137,6 +139,8 @@ void Abc_Init( Abc_Frame_t * pAbc ) 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", "print_unate", Abc_CommandPrintUnate, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_auto", Abc_CommandPrintAuto, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_kmap", Abc_CommandPrintKMap, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_gates", Abc_CommandPrintGates, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_sharing", Abc_CommandPrintSharing, 0 ); @@ -247,7 +251,7 @@ int Abc_CommandPrintStats( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fFactor; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -310,7 +314,7 @@ int Abc_CommandPrintExdc( Abc_Frame_t * pAbc, int argc, char ** argv ) extern double Abc_NtkSpacePercentage( Abc_Obj_t * pNode ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -398,7 +402,7 @@ int Abc_CommandPrintIo( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Obj_t * pNode; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -467,7 +471,7 @@ int Abc_CommandPrintLatch( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -517,7 +521,7 @@ int Abc_CommandPrintFanio( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -570,7 +574,7 @@ int Abc_CommandPrintFactor( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fUseRealNames; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -653,7 +657,7 @@ int Abc_CommandPrintLevel( Abc_Frame_t * pAbc, int argc, char ** argv ) int fListNodes; int fProfile; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -742,7 +746,7 @@ int Abc_CommandPrintSupport( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Vec_Ptr_t * Sim_ComputeFunSupp( Abc_Ntk_t * pNtk, int fVerbose ); extern void Abc_NtkPrintStrSupports( Abc_Ntk_t * pNtk ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -817,7 +821,7 @@ int Abc_CommandPrintSymms( Abc_Frame_t * pAbc, int argc, char ** argv ) int fVerbose; extern void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -884,6 +888,160 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandPrintUnate( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int fUseBdds; + int fUseNaive; + int fVerbose; + extern void Abc_NtkPrintUnate( Abc_Ntk_t * pNtk, int fUseBdds, int fUseNaive, int fVerbose ); + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + fUseBdds = 1; + fUseNaive = 0; + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "bnvh" ) ) != EOF ) + { + switch ( c ) + { + case 'b': + fUseBdds ^= 1; + break; + case 'n': + fUseNaive ^= 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 works only for AIGs (run \"strash\").\n" ); + return 1; + } + Abc_NtkPrintUnate( pNtk, fUseBdds, fUseNaive, fVerbose ); + return 0; + +usage: + fprintf( pErr, "usage: print_unate [-bnvh]\n" ); + fprintf( pErr, "\t computes unate variables of the PO functions\n" ); + fprintf( pErr, "\t-b : toggle BDD-based or SAT-based computations [default = %s].\n", fUseBdds? "BDD": "SAT" ); + fprintf( pErr, "\t-n : toggle naive BDD-based computation [default = %s].\n", fUseNaive? "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_CommandPrintAuto( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pOut, * pErr; + Abc_Ntk_t * pNtk; + int c; + int Output; + int fNaive; + int fVerbose; + extern void Abc_NtkAutoPrint( Abc_Ntk_t * pNtk, int Output, int fNaive, int fVerbose ); + + pNtk = Abc_FrameReadNtk(pAbc); + pOut = Abc_FrameReadOut(pAbc); + pErr = Abc_FrameReadErr(pAbc); + + // set defaults + Output = -1; + fNaive = 0; + fVerbose = 0; + util_getopt_reset(); + while ( ( c = util_getopt( argc, argv, "Onvh" ) ) != 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 '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_NtkIsStrash(pNtk) ) + { + fprintf( pErr, "This command works only for AIGs (run \"strash\").\n" ); + return 1; + } + + + Abc_NtkAutoPrint( pNtk, Output, fNaive, fVerbose ); + return 0; + +usage: + fprintf( pErr, "usage: print_auto [-O num] [-nvh]\n" ); + fprintf( pErr, "\t computes autosymmetries of the PO functions\n" ); + fprintf( pErr, "\t-O num : (optional) the 0-based number of the output [default = all]\n"); + 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_CommandPrintKMap( Abc_Frame_t * pAbc, int argc, char ** argv ) { FILE * pOut, * pErr; @@ -894,7 +1052,7 @@ int Abc_CommandPrintKMap( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc_NodePrintKMap( Abc_Obj_t * pNode, int fUseRealNames ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -981,7 +1139,7 @@ int Abc_CommandPrintGates( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc_NtkPrintGates( Abc_Ntk_t * pNtk, int fUseLibrary ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1044,7 +1202,7 @@ int Abc_CommandPrintSharing( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc_NtkPrintSharing( Abc_Ntk_t * pNtk ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1106,7 +1264,7 @@ int Abc_CommandShowBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; extern void Abc_NodeShowBdd( Abc_Obj_t * pNode ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1194,7 +1352,7 @@ int Abc_CommandShowCut( Abc_Frame_t * pAbc, int argc, char ** argv ) int nConeSizeMax; extern void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1295,7 +1453,7 @@ int Abc_CommandShowAig( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc_NtkShowAig( Abc_Ntk_t * pNtk ); extern void Abc_NtkShowMulti( Abc_Ntk_t * pNtk ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1369,7 +1527,7 @@ int Abc_CommandShowNtk( Abc_Frame_t * pAbc, int argc, char ** argv ) int fGateNames; extern void Abc_NtkShow( Abc_Ntk_t * pNtk, int fGateNames ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1432,7 +1590,7 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk, * pNtkRes; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1506,7 +1664,7 @@ int Abc_CommandStrash( Abc_Frame_t * pAbc, int argc, char ** argv ) int fAllNodes; int fCleanup; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1573,22 +1731,27 @@ int Abc_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv ) FILE * pOut, * pErr; Abc_Ntk_t * pNtk, * pNtkRes, * pNtkTemp; int c; - int fDuplicate; + bool fDuplicate; + bool fSelective; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); // set defaults fDuplicate = 0; + fSelective = 0; util_getopt_reset(); - while ( ( c = util_getopt( argc, argv, "dh" ) ) != EOF ) + while ( ( c = util_getopt( argc, argv, "dsh" ) ) != EOF ) { switch ( c ) { case 'd': fDuplicate ^= 1; break; + case 's': + fSelective ^= 1; + break; case 'h': goto usage; default: @@ -1610,7 +1773,7 @@ int Abc_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv ) // get the new network if ( Abc_NtkIsStrash(pNtk) ) { - pNtkRes = Abc_NtkBalance( pNtk, fDuplicate ); + pNtkRes = Abc_NtkBalance( pNtk, fDuplicate, fSelective ); } else { @@ -1620,7 +1783,7 @@ int Abc_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Strashing before balancing has failed.\n" ); return 1; } - pNtkRes = Abc_NtkBalance( pNtkTemp, fDuplicate ); + pNtkRes = Abc_NtkBalance( pNtkTemp, fDuplicate, fSelective ); Abc_NtkDelete( pNtkTemp ); } @@ -1635,9 +1798,10 @@ int Abc_CommandBalance( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pErr, "usage: balance [-dh]\n" ); + fprintf( pErr, "usage: balance [-dsh]\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-s : toggle duplication on the critical paths [default = %s]\n", fSelective? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; } @@ -1662,7 +1826,7 @@ int Abc_CommandRenode( Abc_Frame_t * pAbc, int argc, char ** argv ) int fMulti; int fSimple; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1769,7 +1933,7 @@ int Abc_CommandCleanup( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1824,7 +1988,7 @@ int Abc_CommandSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1883,7 +2047,7 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv ) extern bool Abc_NtkFastExtract( Abc_Ntk_t * pNtk, Fxu_Data_t * p ); extern void Abc_NtkFxuFreeInfo( Fxu_Data_t * p ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2010,7 +2174,7 @@ int Abc_CommandDisjoint( Abc_Frame_t * pAbc, int argc, char ** argv ) 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); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2136,7 +2300,7 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Rwr_Precompute(); extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2233,7 +2397,7 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv ) bool fVerbose; extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUpdateLevel, bool fUseZeros, bool fUseDcs, bool fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2351,7 +2515,7 @@ int Abc_CommandLogic( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk, * pNtkRes; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2420,7 +2584,7 @@ int Abc_CommandMiter( Abc_Frame_t * pAbc, int argc, char ** argv ) int fCheck; int fComb; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2491,7 +2655,7 @@ int Abc_CommandFrames( Abc_Frame_t * pAbc, int argc, char ** argv ) int nFrames; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2575,7 +2739,7 @@ int Abc_CommandSop( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2635,7 +2799,7 @@ int Abc_CommandBdd( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2696,7 +2860,7 @@ int Abc_CommandReorder( Abc_Frame_t * pAbc, int argc, char ** argv ) int fVerbose; extern void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2757,7 +2921,7 @@ int Abc_CommandMuxes( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk, * pNtkRes; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2825,7 +2989,7 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv ) int fVerbose; int nSeconds; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -2887,7 +3051,7 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv ) */ if ( Abc_NtkIsStrash(pNtk) ) { - RetValue = Abc_NtkMiterSat2( pNtk, nSeconds, fVerbose ); + RetValue = Abc_NtkMiterSat( pNtk, nSeconds, fVerbose ); if ( RetValue == -1 ) printf( "The miter is UNDECIDED (SAT solver timed out).\n" ); else if ( RetValue == 0 ) @@ -2899,7 +3063,7 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pTemp; pTemp = Abc_NtkStrash( pNtk, 0, 0 ); - RetValue = Abc_NtkMiterSat2( pTemp, nSeconds, fVerbose ); + RetValue = Abc_NtkMiterSat( pTemp, nSeconds, fVerbose ); if ( RetValue == -1 ) printf( "The miter is UNDECIDED (SAT solver timed out).\n" ); else if ( RetValue == 0 ) @@ -2939,7 +3103,7 @@ int Abc_CommandExtSeqDcs( Abc_Frame_t * pAbc, int argc, char ** argv ) int fVerbose; extern int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNet, bool fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3010,7 +3174,7 @@ int Abc_CommandOneOutput( Abc_Frame_t * pAbc, int argc, char ** argv ) int fUseAllCis; int Output; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3122,7 +3286,7 @@ int Abc_CommandOneNode( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Obj_t * pNode; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3202,7 +3366,7 @@ int Abc_CommandShortNames( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3251,7 +3415,7 @@ int Abc_CommandExdcFree( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk, * pNtkRes; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3311,7 +3475,7 @@ int Abc_CommandExdcGet( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk, * pNtkRes; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3369,7 +3533,7 @@ int Abc_CommandExdcSet( Abc_Frame_t * pAbc, int argc, char ** argv ) char * FileName; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3461,7 +3625,7 @@ int Abc_CommandCut( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ); extern void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * pCutOracle ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3591,7 +3755,7 @@ int Abc_CommandScut( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; extern Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3696,7 +3860,7 @@ int Abc_CommandXyz( Abc_Frame_t * pAbc, int argc, char ** argv ) int nFaninMax; extern Abc_Ntk_t * Abc_NtkXyz( Abc_Ntk_t * pNtk, int nFaninMax, bool fUseEsop, bool fUseSop, bool fUseInvs, bool fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3784,9 +3948,9 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) FILE * pOut, * pErr; Abc_Ntk_t * pNtk, * pNtkRes; int c; - extern Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk ); +// extern Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -3819,7 +3983,9 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) // printf( "This command is currently not used.\n" ); // run the command // pNtkRes = Abc_NtkMiterForCofactors( pNtk, 0, 0, -1 ); - pNtkRes = Abc_NtkNewAig( pNtk ); + +// pNtkRes = Abc_NtkNewAig( pNtk ); + pNtkRes = NULL; if ( pNtkRes == NULL ) { fprintf( pErr, "Command has failed.\n" ); @@ -3859,7 +4025,7 @@ int Abc_CommandFraig( Abc_Frame_t * pAbc, int argc, char ** argv ) int fExdc; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4017,7 +4183,7 @@ int Abc_CommandFraigTrust( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fDuplicate; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4081,7 +4247,7 @@ int Abc_CommandFraigStore( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fDuplicate; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4142,7 +4308,7 @@ int Abc_CommandFraigRestore( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fDuplicate; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4206,7 +4372,7 @@ int Abc_CommandFraigClean( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fDuplicate; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4258,7 +4424,7 @@ int Abc_CommandFraigSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) int fVerbose; extern bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4345,7 +4511,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, int fSwitching, int fVerbose ); extern bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4410,7 +4576,7 @@ int Abc_CommandMap( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Strashing before mapping has failed.\n" ); return 1; } - pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 ); + pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0, 0 ); Abc_NtkDelete( pNtkRes ); if ( pNtk == NULL ) { @@ -4481,7 +4647,7 @@ int Abc_CommandUnmap( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4542,7 +4708,7 @@ int Abc_CommandAttach( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; extern int Abc_NtkUnmap( Abc_Ntk_t * pNtk ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4605,7 +4771,7 @@ int Abc_CommandSuperChoice( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; extern Abc_Ntk_t * Abc_NtkSuperChoice( Abc_Ntk_t * pNtk ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4678,7 +4844,7 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4740,7 +4906,7 @@ int Abc_CommandFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Strashing before FPGA mapping has failed.\n" ); return 1; } - pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 ); + pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0, 0 ); Abc_NtkDelete( pNtkRes ); if ( pNtk == NULL ) { @@ -4806,7 +4972,7 @@ int Abc_CommandPga( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; extern Abc_Ntk_t * Abc_NtkPga( Pga_Params_t * pParams ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -4863,7 +5029,7 @@ int Abc_CommandPga( Abc_Frame_t * pAbc, int argc, char ** argv ) fprintf( pErr, "Strashing before FPGA mapping has failed.\n" ); return 1; } - pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0 ); + pNtk = Abc_NtkBalance( pNtkRes = pNtk, 0, 0 ); Abc_NtkDelete( pNtkRes ); if ( pNtk == NULL ) { @@ -4931,7 +5097,7 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv ) int fRandom; int fDontCare; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -5039,7 +5205,7 @@ int Abc_CommandPipe( Abc_Frame_t * pAbc, int argc, char ** argv ) int nLatches; extern void Abc_NtkLatchPipe( Abc_Ntk_t * pNtk, int nLatches ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -5115,7 +5281,7 @@ int Abc_CommandSeq( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk, * pNtkRes; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -5192,7 +5358,7 @@ int Abc_CommandUnseq( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fShare; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -5269,7 +5435,7 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) int fInitial; int fVerbose; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -5395,7 +5561,7 @@ int Abc_CommandSeqFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) int c, nMaxIters; int fVerbose; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -5459,7 +5625,7 @@ int Abc_CommandSeqFpga( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } - pNtkNew = Abc_NtkBalance( pNtkRes = pNtkNew, 0 ); + pNtkNew = Abc_NtkBalance( pNtkRes = pNtkNew, 0, 0 ); Abc_NtkDelete( pNtkRes ); if ( pNtkNew == NULL ) { @@ -5519,7 +5685,7 @@ int Abc_CommandSeqMap( Abc_Frame_t * pAbc, int argc, char ** argv ) int c, nMaxIters; int fVerbose; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -5583,7 +5749,7 @@ int Abc_CommandSeqMap( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } - pNtkNew = Abc_NtkBalance( pNtkRes = pNtkNew, 0 ); + pNtkNew = Abc_NtkBalance( pNtkRes = pNtkNew, 0, 0 ); Abc_NtkDelete( pNtkRes ); if ( pNtkNew == NULL ) { @@ -5649,7 +5815,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Abc_Ntk_t * Abc_NtkVanEijk( Abc_Ntk_t * pNtk, int nFrames, int fExdc, int fVerbose ); extern Abc_Ntk_t * Abc_NtkVanImp( Abc_Ntk_t * pNtk, int nFrames, int fExdc, int fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -5756,7 +5922,7 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Ntk_t * pNtk; int c; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -5822,7 +5988,7 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -5914,7 +6080,7 @@ int Abc_CommandSec( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nFrames, int fVerbose ); - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); diff --git a/src/base/abci/abcAuto.c b/src/base/abci/abcAuto.c new file mode 100644 index 00000000..752943c3 --- /dev/null +++ b/src/base/abci/abcAuto.c @@ -0,0 +1,229 @@ +/**CFile**************************************************************** + + FileName [abcAuto.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Computation of autosymmetries.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcAuto.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Abc_NtkAutoPrintAll( DdManager * dd, int nInputs, DdNode * pbOutputs[], int nOutputs, char * pInputNames[], char * pOutputNames[], int fNaive ); +static void Abc_NtkAutoPrintOne( DdManager * dd, int nInputs, DdNode * pbOutputs[], int Output, char * pInputNames[], char * pOutputNames[], int fNaive ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkAutoPrint( Abc_Ntk_t * pNtk, int Output, int fNaive, int fVerbose ) +{ + DdManager * dd; // the BDD manager used to hold shared BDDs + DdNode ** pbGlobal; // temporary storage for global BDDs + char ** pInputNames; // pointers to the CI names + char ** pOutputNames; // pointers to the CO names + int nOutputs, nInputs, i; + + // compute the global BDDs + if ( Abc_NtkGlobalBdds(pNtk, 0) == NULL ) + return; + + // get information about the network + nInputs = Abc_NtkCiNum(pNtk); + nOutputs = Abc_NtkCoNum(pNtk); + dd = pNtk->pManGlob; + pbGlobal = (DdNode **)Vec_PtrArray( pNtk->vFuncsGlob ); + + // get the network names + pInputNames = Abc_NtkCollectCioNames( pNtk, 0 ); + pOutputNames = Abc_NtkCollectCioNames( pNtk, 1 ); + + // print the size of the BDDs + if ( fVerbose ) + printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); + + // allocate additional variables + for ( i = 0; i < nInputs; i++ ) + Cudd_bddNewVar( dd ); + assert( Cudd_ReadSize(dd) == 2 * nInputs ); + + // create ZDD variables in the manager + Cudd_zddVarsFromBddVars( dd, 2 ); + + // perform the analysis of the primary output functions for auto-symmetry + if ( Output == -1 ) + Abc_NtkAutoPrintAll( dd, nInputs, pbGlobal, nOutputs, pInputNames, pOutputNames, fNaive ); + else + Abc_NtkAutoPrintOne( dd, nInputs, pbGlobal, Output, pInputNames, pOutputNames, fNaive ); + + // deref the PO functions + Abc_NtkFreeGlobalBdds( pNtk ); + // stop the global BDD manager + Extra_StopManager( pNtk->pManGlob ); + pNtk->pManGlob = NULL; + free( pInputNames ); + free( pOutputNames ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkAutoPrintAll( DdManager * dd, int nInputs, DdNode * pbOutputs[], int nOutputs, char * pInputNames[], char * pOutputNames[], int fNaive ) +{ + DdNode * bSpace1, * bSpace2, * bCanVars, * bReduced, * zEquations; + double nMints; + int nSupp, SigCounter, o; + + int nAutos; + int nAutoSyms; + int nAutoSymsMax; + int nAutoSymsMaxSupp; + int nAutoSymOuts; + int nSuppSizeMax; + int clk; + + nAutoSymOuts = 0; + nAutoSyms = 0; + nAutoSymsMax = 0; + nAutoSymsMaxSupp = 0; + nSuppSizeMax = 0; + clk = clock(); + + SigCounter = 0; + for ( o = 0; o < nOutputs; o++ ) + { + bSpace1 = Extra_bddSpaceFromFunctionFast( dd, pbOutputs[o] ); Cudd_Ref( bSpace1 ); +// bSpace1 = Extra_bddSpaceFromFunction( dd, pbOutputs[o], pbOutputs[o] ); Cudd_Ref( bSpace1 ); + bCanVars = Extra_bddSpaceCanonVars( dd, bSpace1 ); Cudd_Ref( bCanVars ); + bReduced = Extra_bddSpaceReduce( dd, pbOutputs[o], bCanVars ); Cudd_Ref( bReduced ); + zEquations = Extra_bddSpaceEquations( dd, bSpace1 ); Cudd_Ref( zEquations ); + + nSupp = Cudd_SupportSize( dd, bSpace1 ); + nMints = Cudd_CountMinterm( dd, bSpace1, nSupp ); + nAutos = Extra_Base2LogDouble(nMints); + printf( "Output #%3d: Inputs = %2d. AutoK = %2d.\n", o, nSupp, nAutos ); + + if ( nAutos > 0 ) + { + nAutoSymOuts++; + nAutoSyms += nAutos; + if ( nAutoSymsMax < nAutos ) + { + nAutoSymsMax = nAutos; + nAutoSymsMaxSupp = nSupp; + } + } + if ( nSuppSizeMax < nSupp ) + nSuppSizeMax = nSupp; + + +//PRB( dd, bCanVars ); +//PRB( dd, bReduced ); +//Cudd_PrintMinterm( dd, bReduced ); +//printf( "The equations are:\n" ); +//Cudd_zddPrintCover( dd, zEquations ); +//printf( "\n" ); +//fflush( stdout ); + + bSpace2 = Extra_bddSpaceFromMatrixPos( dd, zEquations ); Cudd_Ref( bSpace2 ); +//PRB( dd, bSpace1 ); +//PRB( dd, bSpace2 ); + if ( bSpace1 != bSpace2 ) + printf( "Spaces are NOT EQUAL!\n" ); +// else +// printf( "Spaces are equal.\n" ); + + Cudd_RecursiveDeref( dd, bSpace1 ); + Cudd_RecursiveDeref( dd, bSpace2 ); + Cudd_RecursiveDeref( dd, bCanVars ); + Cudd_RecursiveDeref( dd, bReduced ); + Cudd_RecursiveDerefZdd( dd, zEquations ); + } + + printf( "The cumulative statistics for all outputs:\n" ); + printf( "Ins=%3d ", nInputs ); + printf( "InMax=%3d ", nSuppSizeMax ); + printf( "Outs=%3d ", nOutputs ); + printf( "Auto=%3d ", nAutoSymOuts ); + printf( "SumK=%3d ", nAutoSyms ); + printf( "KMax=%2d ", nAutoSymsMax ); + printf( "Supp=%3d ", nAutoSymsMaxSupp ); + printf( "Time=%4.2f ", (float)(clock() - clk)/(float)(CLOCKS_PER_SEC) ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkAutoPrintOne( DdManager * dd, int nInputs, DdNode * pbOutputs[], int Output, char * pInputNames[], char * pOutputNames[], int fNaive ) +{ + DdNode * bSpace1, * bCanVars, * bReduced, * zEquations; + double nMints; + int nSupp, SigCounter; + int nAutos; + + SigCounter = 0; + bSpace1 = Extra_bddSpaceFromFunctionFast( dd, pbOutputs[Output] ); Cudd_Ref( bSpace1 ); +// bSpace1 = Extra_bddSpaceFromFunction( dd, pbOutputs[Output], pbOutputs[Output] ); Cudd_Ref( bSpace1 ); + bCanVars = Extra_bddSpaceCanonVars( dd, bSpace1 ); Cudd_Ref( bCanVars ); + bReduced = Extra_bddSpaceReduce( dd, pbOutputs[Output], bCanVars ); Cudd_Ref( bReduced ); + zEquations = Extra_bddSpaceEquations( dd, bSpace1 ); Cudd_Ref( zEquations ); + + nSupp = Cudd_SupportSize( dd, bSpace1 ); + nMints = Cudd_CountMinterm( dd, bSpace1, nSupp ); + nAutos = Extra_Base2LogDouble(nMints); + printf( "Output #%3d: Inputs = %2d. AutoK = %2d.\n", Output, nSupp, nAutos ); + + Cudd_RecursiveDeref( dd, bSpace1 ); + Cudd_RecursiveDeref( dd, bCanVars ); + Cudd_RecursiveDeref( dd, bReduced ); + Cudd_RecursiveDerefZdd( dd, zEquations ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcBalance.c b/src/base/abci/abcBalance.c index fed89dbb..effae853 100644 --- a/src/base/abci/abcBalance.c +++ b/src/base/abci/abcBalance.c @@ -24,10 +24,11 @@ /// 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, int Level, bool fDuplicate ); -static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vSuper, int Level, int fDuplicate ); -static int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate ); +static void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate, bool fSelective ); +static Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, Vec_Vec_t * vStorage, int Level, bool fDuplicate, bool fSelective ); +static Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vSuper, int Level, int fDuplicate, bool fSelective ); +static int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate, bool fSelective ); +static void Abc_NtkMarkCriticalNodes( Abc_Ntk_t * pNtk ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -44,14 +45,26 @@ static int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSupe SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate ) +Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate, bool fSelective ) { Abc_Ntk_t * pNtkAig; assert( Abc_NtkIsStrash(pNtk) ); + // compute the required times + if ( fSelective ) + { + Abc_NtkStartReverseLevels( pNtk ); + Abc_NtkMarkCriticalNodes( pNtk ); + } // perform balancing pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); - Abc_NtkBalancePerform( pNtk, pNtkAig, fDuplicate ); + Abc_NtkBalancePerform( pNtk, pNtkAig, fDuplicate, fSelective ); Abc_NtkFinalize( pNtk, pNtkAig ); + // undo the required times + if ( fSelective ) + { + Abc_NtkStopReverseLevels( pNtk ); + Abc_NtkCleanMarkA( pNtk ); + } if ( pNtk->pExdc ) pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc ); // make sure everything is okay @@ -75,7 +88,7 @@ Abc_Ntk_t * Abc_NtkBalance( Abc_Ntk_t * pNtk, bool fDuplicate ) SeeAlso [] ***********************************************************************/ -void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate ) +void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplicate, bool fSelective ) { int fCheck = 1; ProgressBar * pProgress; @@ -94,7 +107,7 @@ void Abc_NtkBalancePerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fDuplica Extra_ProgressBarUpdate( pProgress, i, NULL ); // strash the driver node pDriver = Abc_ObjFanin0(pNode); - Abc_NodeBalance_rec( pNtkAig, pDriver, vStorage, 0, fDuplicate ); + Abc_NodeBalance_rec( pNtkAig, pDriver, vStorage, 0, fDuplicate, fSelective ); } Extra_ProgressBarStop( pProgress ); Vec_VecFree( vStorage ); @@ -147,7 +160,7 @@ void Abc_NodeBalanceRandomize( Vec_Ptr_t * vSuper ) SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_Vec_t * vStorage, int Level, bool fDuplicate ) +Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_Vec_t * vStorage, int Level, bool fDuplicate, bool fSelective ) { Abc_Aig_t * pMan = pNtkNew->pManFunc; Abc_Obj_t * pNodeNew, * pNode1, * pNode2; @@ -159,7 +172,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_ return pNodeOld->pCopy; assert( Abc_ObjIsNode(pNodeOld) ); // get the implication supergate - vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, Level, fDuplicate ); + vSuper = Abc_NodeBalanceCone( pNodeOld, vStorage, Level, fDuplicate, fSelective ); if ( vSuper->nSize == 0 ) { // it means that the supergate contains two nodes in the opposite polarity pNodeOld->pCopy = Abc_ObjNot(Abc_NtkConst1(pNtkNew)); @@ -168,7 +181,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_ // 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, Level + 1, fDuplicate ); + pNodeNew = Abc_NodeBalance_rec( pNtkNew, Abc_ObjRegular(vSuper->pArray[i]), vStorage, Level + 1, fDuplicate, fSelective ); vSuper->pArray[i] = Abc_ObjNotCond( pNodeNew, Abc_ObjIsComplement(vSuper->pArray[i]) ); } if ( vSuper->nSize < 2 ) @@ -207,7 +220,7 @@ Abc_Obj_t * Abc_NodeBalance_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, Vec_ SeeAlso [] ***********************************************************************/ -Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vStorage, int Level, int fDuplicate ) +Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vStorage, int Level, int fDuplicate, bool fSelective ) { Vec_Ptr_t * vNodes; int RetValue, i; @@ -219,7 +232,7 @@ Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vStorage, int Le vNodes = Vec_VecEntry( vStorage, Level ); Vec_PtrClear( vNodes ); // collect the nodes in the implication supergate - RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, fDuplicate ); + RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, fDuplicate, fSelective ); assert( vNodes->nSize > 1 ); // unmark the visited nodes for ( i = 0; i < vNodes->nSize; i++ ) @@ -245,7 +258,7 @@ Vec_Ptr_t * Abc_NodeBalanceCone( Abc_Obj_t * pNode, Vec_Vec_t * vStorage, int Le SeeAlso [] ***********************************************************************/ -int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate ) +int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, bool fDuplicate, bool fSelective ) { int RetValue1, RetValue2, i; // check if the node is visited @@ -263,7 +276,7 @@ int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, 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)) ) + if ( !fFirst && (Abc_ObjIsComplement(pNode) || !Abc_ObjIsNode(pNode) || !fDuplicate && !fSelective && (Abc_ObjFanoutNum(pNode) > 1)) ) { Vec_PtrPush( vSuper, pNode ); Abc_ObjRegular(pNode)->fMarkB = 1; @@ -272,8 +285,8 @@ int Abc_NodeBalanceCone_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, bool fFirst, 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 ); + RetValue1 = Abc_NodeBalanceCone_rec( Abc_ObjChild0(pNode), vSuper, 0, fDuplicate, fSelective ); + RetValue2 = Abc_NodeBalanceCone_rec( Abc_ObjChild1(pNode), vSuper, 0, fDuplicate, fSelective ); if ( RetValue1 == -1 || RetValue2 == -1 ) return -1; // return 1 if at least one branch has a duplicate @@ -315,7 +328,7 @@ Vec_Ptr_t * Abc_NodeFindCone_rec( Abc_Obj_t * pNode ) else { // collect the nodes in the implication supergate - RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, 1 ); + RetValue = Abc_NodeBalanceCone_rec( pNode, vNodes, 1, 1, 0 ); assert( vNodes->nSize > 1 ); // unmark the visited nodes Vec_PtrForEachEntry( vNodes, pNode, i ) @@ -442,6 +455,28 @@ void Abc_NtkBalanceLevel( Abc_Ntk_t * pNtk ) } +/**Function************************************************************* + + Synopsis [Marks the nodes on the critical and near critical paths.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkMarkCriticalNodes( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pNode; + int i, Counter = 0; + Abc_NtkForEachNode( pNtk, pNode, i ) + if ( Abc_NodeReadRequiredLevel(pNode) - pNode->Level <= 1 ) + pNode->fMarkA = 1, Counter++; + printf( "The number of nodes on the critical paths = %6d (%5.2f %%)\n", Counter, 100.0 * Counter / Abc_NtkNodeNum(pNtk) ); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abcDsd.c b/src/base/abci/abcDsd.c index 5c7f0d48..a73ab2b5 100644 --- a/src/base/abci/abcDsd.c +++ b/src/base/abci/abcDsd.c @@ -172,6 +172,7 @@ void Abc_NtkDsdConstruct( Dsd_Manager_t * pManDsd, Abc_Ntk_t * pNtk, Abc_Ntk_t * int i, nNodesDsd; // save the CI nodes in the DSD nodes + Dsd_NodeSetMark( Dsd_ManagerReadConst1(pManDsd), (int)Abc_NtkConst1(pNtk)->pCopy ); Abc_NtkForEachCi( pNtk, pNode, i ) { pNodeDsd = Dsd_ManagerReadInput( pManDsd, i ); diff --git a/src/base/abci/abcMap.c b/src/base/abci/abcMap.c index 39bf15aa..128e054a 100644 --- a/src/base/abci/abcMap.c +++ b/src/base/abci/abcMap.c @@ -105,7 +105,7 @@ clk = clock(); Map_ManFree( pMan ); return NULL; } -// Map_ManPrintStatsToFile( pNtk->pSpec, Map_ManReadAreaFinal(pMan), Map_ManReadRequiredGlo(pMan), clock()-clk ); + Map_ManPrintStatsToFile( pNtk->pSpec, Map_ManReadAreaFinal(pMan), Map_ManReadRequiredGlo(pMan), clock()-clk ); // reconstruct the network after mapping pNtkNew = Abc_NtkFromMap( pMan, pNtk ); diff --git a/src/base/abci/abcRenode.c b/src/base/abci/abcRenode.c index c1f83e1f..ea2f808c 100644 --- a/src/base/abci/abcRenode.c +++ b/src/base/abci/abcRenode.c @@ -173,6 +173,8 @@ Abc_Obj_t * Abc_NtkRenode_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld ) assert( !Abc_NodeIsConst(pNodeOld) ); assert( pNodeOld->fMarkA ); +//printf( "%d ", Abc_NodeMffcSizeSupp(pNodeOld) ); + // collect the renoding cone vCone = Vec_PtrAlloc( 10 ); Abc_NtkRenodeCone( pNodeOld, vCone ); diff --git a/src/base/abci/abcSat.c b/src/base/abci/abcSat.c index f7b9892e..9c650aa9 100644 --- a/src/base/abci/abcSat.c +++ b/src/base/abci/abcSat.c @@ -29,6 +29,8 @@ static int Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * static solver * Abc_NtkMiterSatCreate2( Abc_Ntk_t * pNtk ); +static Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk ); + static nMuxes; //////////////////////////////////////////////////////////////////////// @@ -46,7 +48,7 @@ static nMuxes; SeeAlso [] ***********************************************************************/ -int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nSeconds, int fVerbose ) +int Abc_NtkMiterSat_OldAndRusty( Abc_Ntk_t * pNtk, int nSeconds, int fVerbose ) { solver * pSat; lbool status; @@ -317,7 +319,7 @@ int Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars ) SeeAlso [] ***********************************************************************/ -int Abc_NtkMiterSat2( Abc_Ntk_t * pNtk, int nSeconds, int fVerbose ) +int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, int nSeconds, int fVerbose ) { solver * pSat; lbool status; @@ -376,7 +378,8 @@ int Abc_NtkMiterSat2( Abc_Ntk_t * pNtk, int nSeconds, int fVerbose ) // if the problem is SAT, get the counterexample if ( status == l_True ) { - Vec_Int_t * vCiIds = Abc_NtkGetCiIds( pNtk ); +// Vec_Int_t * vCiIds = Abc_NtkGetCiIds( pNtk ); + Vec_Int_t * vCiIds = Abc_NtkGetCiSatVarNums( pNtk ); pNtk->pModel = solver_get_model( pSat, vCiIds->pArray, vCiIds->nSize ); Vec_IntFree( vCiIds ); } @@ -385,6 +388,28 @@ int Abc_NtkMiterSat2( Abc_Ntk_t * pNtk, int nSeconds, int fVerbose ) return RetValue; } +/**Function************************************************************* + + Synopsis [Returns the array of CI IDs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk ) +{ + Vec_Int_t * vCiIds; + Abc_Obj_t * pObj; + int i; + vCiIds = Vec_IntAlloc( Abc_NtkCiNum(pNtk) ); + Abc_NtkForEachCi( pNtk, pObj, i ) + Vec_IntPush( vCiIds, (int)pObj->pCopy ); + return vCiIds; +} + diff --git a/src/base/abci/abcUnate.c b/src/base/abci/abcUnate.c new file mode 100644 index 00000000..08a42623 --- /dev/null +++ b/src/base/abci/abcUnate.c @@ -0,0 +1,150 @@ +/**CFile**************************************************************** + + FileName [abcUnate.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: abcUnate.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static void Abc_NtkPrintUnateBdd( Abc_Ntk_t * pNtk, int fUseNaive, int fVerbose ); +static void Abc_NtkPrintUnateSat( Abc_Ntk_t * pNtk, int fVerbose ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Detects unate variables of the multi-output function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintUnate( Abc_Ntk_t * pNtk, int fUseBdds, int fUseNaive, int fVerbose ) +{ + if ( fUseBdds || fUseNaive ) + Abc_NtkPrintUnateBdd( pNtk, fUseNaive, fVerbose ); + else + Abc_NtkPrintUnateSat( pNtk, fVerbose ); +} + +/**Function************************************************************* + + Synopsis [Detects unate variables using BDDs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintUnateBdd( Abc_Ntk_t * pNtk, int fUseNaive, int fVerbose ) +{ + Abc_Obj_t * pNode; + Extra_UnateInfo_t * p; + DdManager * dd; // the BDD manager used to hold shared BDDs + DdNode ** pbGlobal; // temporary storage for global BDDs + int TotalSupps = 0; + int TotalUnate = 0; + int i, clk = clock(); + int clkBdd, clkUnate; + + // compute the global BDDs + if ( Abc_NtkGlobalBdds(pNtk, 0) == NULL ) + return; +clkBdd = clock() - clk; + + // get information about the network + dd = pNtk->pManGlob; + pbGlobal = (DdNode **)Vec_PtrArray( pNtk->vFuncsGlob ); + + // print the size of the BDDs + printf( "The shared BDD size is %d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); + + // perform naive BDD-based computation + if ( fUseNaive ) + { + Abc_NtkForEachCo( pNtk, pNode, i ) + { + p = Extra_UnateComputeSlow( dd, pbGlobal[i] ); + if ( fVerbose ) + Extra_UnateInfoPrint( p ); + TotalSupps += p->nVars; + TotalUnate += p->nUnate; + Extra_UnateInfoDissolve( p ); + } + } + // perform smart BDD-based computation + else + { + // create ZDD variables in the manager + Cudd_zddVarsFromBddVars( dd, 2 ); + Abc_NtkForEachCo( pNtk, pNode, i ) + { + p = Extra_UnateComputeFast( dd, pbGlobal[i] ); + if ( fVerbose ) + Extra_UnateInfoPrint( p ); + TotalSupps += p->nVars; + TotalUnate += p->nUnate; + Extra_UnateInfoDissolve( p ); + } + } +clkUnate = clock() - clk - clkBdd; + + // print stats + printf( "Ins/Outs = %4d/%4d. Total supp = %5d. Total unate = %5d.\n", + Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), TotalSupps, TotalUnate ); + PRT( "Glob BDDs", clkBdd ); + PRT( "Unateness", clkUnate ); + PRT( "Total ", clock() - clk ); + + // deref the PO functions + Abc_NtkFreeGlobalBdds( pNtk ); + // stop the global BDD manager + Extra_StopManager( pNtk->pManGlob ); + pNtk->pManGlob = NULL; +} + +/**Function************************************************************* + + Synopsis [Detects unate variables using SAT.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_NtkPrintUnateSat( Abc_Ntk_t * pNtk, int fVerbose ) +{ +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcVerify.c b/src/base/abci/abcVerify.c index b30a6452..99392e48 100644 --- a/src/base/abci/abcVerify.c +++ b/src/base/abci/abcVerify.c @@ -148,9 +148,9 @@ void Abc_NtkCecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int fV Fraig_ParamsSetDefault( &Params ); Params.fVerbose = fVerbose; Params.nSeconds = nSeconds; - Params.fFuncRed = 0; - Params.nPatsRand = 0; - Params.nPatsDyna = 0; +// Params.fFuncRed = 0; +// Params.nPatsRand = 0; +// Params.nPatsDyna = 0; pMan = Abc_NtkToFraig( pMiter, &Params, 0, 0 ); Fraig_ManProveMiter( pMan ); @@ -328,9 +328,9 @@ void Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nF Fraig_ParamsSetDefault( &Params ); Params.fVerbose = fVerbose; Params.nSeconds = nSeconds; - Params.fFuncRed = 0; - Params.nPatsRand = 0; - Params.nPatsDyna = 0; +// Params.fFuncRed = 0; +// Params.nPatsRand = 0; +// Params.nPatsDyna = 0; pMan = Abc_NtkToFraig( pFrames, &Params, 0, 0 ); Fraig_ManProveMiter( pMan ); diff --git a/src/base/abci/module.make b/src/base/abci/module.make index 660aee63..5b15641b 100644 --- a/src/base/abci/module.make +++ b/src/base/abci/module.make @@ -1,5 +1,6 @@ SRC += src/base/abci/abc.c \ src/base/abci/abcAttach.c \ + src/base/abci/abcAuto.c \ src/base/abci/abcBalance.c \ src/base/abci/abcCollapse.c \ src/base/abci/abcCut.c \ @@ -21,6 +22,7 @@ SRC += src/base/abci/abc.c \ src/base/abci/abcSweep.c \ src/base/abci/abcSymm.c \ src/base/abci/abcTiming.c \ + src/base/abci/abcUnate.c \ src/base/abci/abcUnreach.c \ src/base/abci/abcVanEijk.c \ src/base/abci/abcVanImp.c \ diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index f20855ab..b2a90806 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -1204,7 +1204,7 @@ int CmdCommandSis( Abc_Frame_t * pAbc, int argc, char **argv ) char * pSisName; int i; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -1340,7 +1340,7 @@ int CmdCommandMvsis( Abc_Frame_t * pAbc, int argc, char **argv ) char * pMvsisName; int i; - pNtk = Abc_FrameReadNet(pAbc); + pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); diff --git a/src/base/io/io.h b/src/base/io/io.h index 286b570c..fe5c237f 100644 --- a/src/base/io/io.h +++ b/src/base/io/io.h @@ -69,6 +69,7 @@ extern Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, extern Abc_Obj_t * Io_ReadCreateConst( Abc_Ntk_t * pNtk, char * pName, bool fConst1 ); extern Abc_Obj_t * Io_ReadCreateInv( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut ); extern Abc_Obj_t * Io_ReadCreateBuf( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut ); +extern FILE * Io_FileOpen( const char * FileName, const char * PathVar, const char * Mode, int fVerbose ); /*=== abcWriteBaf.c ==========================================================*/ extern void Io_WriteBaf( Abc_Ntk_t * pNtk, char * pFileName ); /*=== abcWriteBlif.c ==========================================================*/ diff --git a/src/base/io/ioReadBench.c b/src/base/io/ioReadBench.c index d8ad8f71..1cb0ae5d 100644 --- a/src/base/io/ioReadBench.c +++ b/src/base/io/ioReadBench.c @@ -47,7 +47,7 @@ Abc_Ntk_t * Io_ReadBench( char * pFileName, int fCheck ) Abc_Ntk_t * pNtk; // start the file - p = Extra_FileReaderAlloc( pFileName, "#", "\n", " \t\r,()=" ); + p = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t,()=" ); if ( p == NULL ) return NULL; diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c index b8a2ed01..c05f444e 100644 --- a/src/base/io/ioReadBlif.c +++ b/src/base/io/ioReadBlif.c @@ -135,7 +135,8 @@ Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName ) Io_ReadBlif_t * p; // start the reader - pReader = Extra_FileReaderAlloc( pFileName, "#", "\n", " \t\r" ); + pReader = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t" ); + if ( pReader == NULL ) return NULL; diff --git a/src/base/io/ioReadEdif.c b/src/base/io/ioReadEdif.c index a2a2f527..f100a45f 100644 --- a/src/base/io/ioReadEdif.c +++ b/src/base/io/ioReadEdif.c @@ -47,7 +47,7 @@ Abc_Ntk_t * Io_ReadEdif( char * pFileName, int fCheck ) Abc_Ntk_t * pNtk; // start the file - p = Extra_FileReaderAlloc( pFileName, "#", "\n", " \t\r()" ); + p = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t()" ); if ( p == NULL ) return NULL; diff --git a/src/base/io/ioReadPla.c b/src/base/io/ioReadPla.c index 387f8730..0413dc8f 100644 --- a/src/base/io/ioReadPla.c +++ b/src/base/io/ioReadPla.c @@ -47,7 +47,7 @@ Abc_Ntk_t * Io_ReadPla( char * pFileName, int fCheck ) Abc_Ntk_t * pNtk; // start the file - p = Extra_FileReaderAlloc( pFileName, "#", "\n", " \t\r|" ); + p = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t|" ); if ( p == NULL ) return NULL; diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c index 342dfbaf..e817bee8 100644 --- a/src/base/io/ioUtil.c +++ b/src/base/io/ioUtil.c @@ -194,6 +194,61 @@ Abc_Obj_t * Io_ReadCreateBuf( Abc_Ntk_t * pNtk, char * pNameIn, char * pNameOut return pNet; } + +/**Function************************************************************* + + Synopsis [Provide an fopen replacement with path lookup] + + Description [Provide an fopen replacement where the path stored + in pathvar MVSIS variable is used to look up the path + for name. Returns NULL if file cannot be opened.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +FILE * Io_FileOpen( const char * FileName, const char * PathVar, const char * Mode, int fVerbose ) +{ + char * t = 0, * c = 0, * i; + extern char * Abc_FrameReadFlag( char * pFlag ); + + if ( PathVar == 0 ) + { + return fopen( FileName, Mode ); + } + else + { + if ( c = Abc_FrameReadFlag( (char*)PathVar ) ) + { + char ActualFileName[4096]; + FILE * fp = 0; + t = util_strsav( c ); + for (i = strtok( t, ":" ); i != 0; i = strtok( 0, ":") ) + { +#ifdef WIN32 + _snprintf ( ActualFileName, 4096, "%s/%s", i, FileName ); +#else + snprintf ( ActualFileName, 4096, "%s/%s", i, FileName ); +#endif + if ( ( fp = fopen ( ActualFileName, Mode ) ) ) + { + if ( fVerbose ) + fprintf ( stdout, "Using file %s\n", ActualFileName ); + free( t ); + return fp; + } + } + free( t ); + return 0; + } + else + { + return fopen( FileName, Mode ); + } + } +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/io/module.make b/src/base/io/module.make index 21579266..8693c8eb 100644 --- a/src/base/io/module.make +++ b/src/base/io/module.make @@ -16,4 +16,5 @@ SRC += src/base/io/io.c \ src/base/io/ioWriteEqn.c \ src/base/io/ioWriteGml.c \ src/base/io/ioWriteList.c \ - src/base/io/ioWritePla.c + src/base/io/ioWritePla.c \ + src/base/io/ioWriteVerilog.c diff --git a/src/base/main/main.c b/src/base/main/main.c index 4c572a07..a9f27bf8 100644 --- a/src/base/main/main.c +++ b/src/base/main/main.c @@ -217,7 +217,7 @@ int main( int argc, char * argv[] ) break; } } - + // if the memory should be freed, quit packages if ( fStatus < 0 ) { diff --git a/src/base/main/main.h b/src/base/main/main.h index 4280808d..c5f311aa 100644 --- a/src/base/main/main.h +++ b/src/base/main/main.h @@ -78,7 +78,7 @@ extern void Abc_Start(); extern void Abc_Stop(); /*=== mainFrame.c ===========================================================*/ -extern Abc_Ntk_t * Abc_FrameReadNet( Abc_Frame_t * p ); +extern Abc_Ntk_t * Abc_FrameReadNtk( Abc_Frame_t * p ); extern FILE * Abc_FrameReadOut( Abc_Frame_t * p ); extern FILE * Abc_FrameReadErr( Abc_Frame_t * p ); extern bool Abc_FrameReadMode( Abc_Frame_t * p ); diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c index f75df49e..e9e243af 100644 --- a/src/base/main/mainFrame.c +++ b/src/base/main/mainFrame.c @@ -164,7 +164,7 @@ void Abc_FrameRestart( Abc_Frame_t * p ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_FrameReadNet( Abc_Frame_t * p ) +Abc_Ntk_t * Abc_FrameReadNtk( Abc_Frame_t * p ) { return p->pNtkCur; } diff --git a/src/base/seq/seqAigCore.c b/src/base/seq/seqAigCore.c index b1f66721..ed2a33fc 100644 --- a/src/base/seq/seqAigCore.c +++ b/src/base/seq/seqAigCore.c @@ -351,11 +351,13 @@ int Seq_NtkImplementRetimingBackward( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMoves, int printf( "The number of ANDs in the AIG = %5d.\n", Abc_NtkNodeNum(pNtkMiter) ); // transform the miter into a logic network for efficient CNF construction - pNtkCnf = Abc_NtkRenode( pNtkMiter, 0, 100, 1, 0, 0 ); - Abc_NtkDelete( pNtkMiter ); +// pNtkCnf = Abc_NtkRenode( pNtkMiter, 0, 100, 1, 0, 0 ); +// Abc_NtkDelete( pNtkMiter ); + pNtkCnf = pNtkMiter; // solve the miter clk = clock(); +// RetValue = Abc_NtkMiterSat_OldAndRusty( pNtkCnf, 30, 0 ); RetValue = Abc_NtkMiterSat( pNtkCnf, 30, 0 ); if ( fVerbose ) if ( clock() - clk > 100 ) diff --git a/src/bdd/dsd/dsd.h b/src/bdd/dsd/dsd.h index 6e180fac..3fd365d7 100644 --- a/src/bdd/dsd/dsd.h +++ b/src/bdd/dsd/dsd.h @@ -91,6 +91,7 @@ extern void Dsd_NodeSetMark( Dsd_Node_t * p, int Mark ); extern DdManager * Dsd_ManagerReadDd( Dsd_Manager_t * pMan ); extern Dsd_Node_t * Dsd_ManagerReadRoot( Dsd_Manager_t * pMan, int i ); extern Dsd_Node_t * Dsd_ManagerReadInput( Dsd_Manager_t * pMan, int i ); +extern Dsd_Node_t * Dsd_ManagerReadConst1( Dsd_Manager_t * pMan ); /*=== dsdMan.c =======================================================*/ extern Dsd_Manager_t * Dsd_ManagerStart( DdManager * dd, int nSuppMax, int fVerbose ); extern void Dsd_ManagerStop( Dsd_Manager_t * dMan ); diff --git a/src/bdd/dsd/dsdApi.c b/src/bdd/dsd/dsdApi.c index c7675f8e..d1c90e23 100644 --- a/src/bdd/dsd/dsdApi.c +++ b/src/bdd/dsd/dsdApi.c @@ -89,6 +89,7 @@ void Dsd_NodeSetMark( Dsd_Node_t * p, int Mark ){ p->Mark = Mark; } ***********************************************************************/ Dsd_Node_t * Dsd_ManagerReadRoot( Dsd_Manager_t * pMan, int i ) { return pMan->pRoots[i]; } Dsd_Node_t * Dsd_ManagerReadInput( Dsd_Manager_t * pMan, int i ) { return pMan->pInputs[i]; } +Dsd_Node_t * Dsd_ManagerReadConst1( Dsd_Manager_t * pMan ) { return pMan->pConst1; } DdManager * Dsd_ManagerReadDd( Dsd_Manager_t * pMan ) { return pMan->dd; } //////////////////////////////////////////////////////////////////////// diff --git a/src/bdd/dsd/dsdInt.h b/src/bdd/dsd/dsdInt.h index 8eaa0969..5569c443 100644 --- a/src/bdd/dsd/dsdInt.h +++ b/src/bdd/dsd/dsdInt.h @@ -42,6 +42,7 @@ struct Dsd_Manager_t_ int nRootsAlloc;// the number of primary outputs Dsd_Node_t ** pInputs; // the primary input nodes Dsd_Node_t ** pRoots; // the primary output nodes + Dsd_Node_t * pConst1; // the constant node int fVerbose; // the verbosity level }; diff --git a/src/bdd/dsd/dsdMan.c b/src/bdd/dsd/dsdMan.c index 4529e75a..6e43f0f4 100644 --- a/src/bdd/dsd/dsdMan.c +++ b/src/bdd/dsd/dsdMan.c @@ -73,6 +73,7 @@ Dsd_Manager_t * Dsd_ManagerStart( DdManager * dd, int nSuppMax, int fVerbose ) pNode->G = b1; Cudd_Ref( pNode->G ); pNode->S = b1; Cudd_Ref( pNode->S ); st_insert( dMan->Table, (char*)b1, (char*)pNode ); + dMan->pConst1 = pNode; Dsd_CheckCacheAllocate( 5000 ); return dMan; diff --git a/src/map/fpga/fpga.c b/src/map/fpga/fpga.c index d9629ecc..31894590 100644 --- a/src/map/fpga/fpga.c +++ b/src/map/fpga/fpga.c @@ -105,7 +105,7 @@ int Fpga_CommandReadLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) int fVerbose; int c; - pNet = Abc_FrameReadNet(pAbc); + pNet = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -195,7 +195,7 @@ int Fpga_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) int fVerbose; int c; - pNet = Abc_FrameReadNet(pAbc); + pNet = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); diff --git a/src/map/mapper/mapper.c b/src/map/mapper/mapper.c index f6cceda1..4d77df8f 100644 --- a/src/map/mapper/mapper.c +++ b/src/map/mapper/mapper.c @@ -87,7 +87,7 @@ int Map_CommandReadLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) int fAlgorithm; int c; - pNet = Abc_FrameReadNet(pAbc); + pNet = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -128,8 +128,8 @@ int Map_CommandReadLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) // get the input file name FileName = argv[util_optind]; -// if ( (pFile = Io_FileOpen( FileName, "open_path", "r" )) == NULL ) - if ( (pFile = fopen( FileName, "r" )) == NULL ) + if ( (pFile = Io_FileOpen( FileName, "open_path", "r", 0 )) == NULL ) +// if ( (pFile = fopen( FileName, "r" )) == NULL ) { fprintf( pErr, "Cannot open input file \"%s\". ", FileName ); if ( FileName = Extra_FileGetSimilarName( FileName, ".genlib", ".lib", ".gen", ".g", NULL ) ) diff --git a/src/map/mapper/mapperCreate.c b/src/map/mapper/mapperCreate.c index bc7346b5..ec1c095e 100644 --- a/src/map/mapper/mapperCreate.c +++ b/src/map/mapper/mapperCreate.c @@ -314,7 +314,7 @@ void Map_ManPrintTimeStats( Map_Man_t * p ) void Map_ManPrintStatsToFile( char * pName, float Area, float Delay, int Time ) { FILE * pTable; - pTable = fopen( "stats.txt", "a+" ); + pTable = fopen( "map_stats.txt", "a+" ); fprintf( pTable, "%s ", pName ); fprintf( pTable, "%4.2f ", Area ); fprintf( pTable, "%4.2f ", Delay ); diff --git a/src/map/mapper/mapperTree.c b/src/map/mapper/mapperTree.c index 9656b0f5..ef66082d 100644 --- a/src/map/mapper/mapperTree.c +++ b/src/map/mapper/mapperTree.c @@ -60,8 +60,8 @@ int Map_LibraryReadTree( Map_SuperLib_t * pLib, char * pFileName, char * pExclud // read the beginning of the file assert( pLib->pGenlib == NULL ); -// pFile = Io_FileOpen( pFileName, "open_path", "r" ); - pFile = fopen( pFileName, "r" ); + pFile = Io_FileOpen( pFileName, "open_path", "r", 1 ); +// pFile = fopen( pFileName, "r" ); if ( pFile == NULL ) { printf( "Cannot open input file \"%s\".\n", pFileName ); @@ -149,8 +149,8 @@ int Map_LibraryReadFileTree( Map_SuperLib_t * pLib, FILE * pFile, char *pFileNam } #endif -// pFileGen = Io_FileOpen( pLibFile, "open_path", "r" ); - pFileGen = fopen( pLibFile, "r" ); + pFileGen = Io_FileOpen( pLibFile, "open_path", "r", 1 ); +// pFileGen = fopen( pLibFile, "r" ); if ( pFileGen == NULL ) { printf( "Cannot open the GENLIB file \"%s\".\n", pLibFile ); diff --git a/src/map/mio/mio.c b/src/map/mio/mio.c index ba05f7ec..a5dd8f95 100644 --- a/src/map/mio/mio.c +++ b/src/map/mio/mio.c @@ -133,7 +133,7 @@ int Mio_CommandReadLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) int fVerbose; int c; - pNet = Abc_FrameReadNet(pAbc); + pNet = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); @@ -163,7 +163,7 @@ int Mio_CommandReadLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) // get the input file name FileName = argv[util_optind]; - if ( (pFile = fopen( FileName, "r" )) == NULL ) + if ( (pFile = Io_FileOpen( FileName, "open_path", "r", 0 )) == NULL ) { fprintf( pErr, "Cannot open input file \"%s\". ", FileName ); if ( (FileName = Extra_FileGetSimilarName( FileName, ".genlib", ".lib", ".gen", ".g", NULL )) ) @@ -223,7 +223,7 @@ int Mio_CommandPrintLibrary( Abc_Frame_t * pAbc, int argc, char **argv ) int fVerbose; int c; - pNet = Abc_FrameReadNet(pAbc); + pNet = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); pErr = Abc_FrameReadErr(pAbc); diff --git a/src/map/mio/mioRead.c b/src/map/mio/mioRead.c index 93b214b5..0c2000a3 100644 --- a/src/map/mio/mioRead.c +++ b/src/map/mio/mioRead.c @@ -114,8 +114,8 @@ Mio_Library_t * Mio_LibraryReadOne( Abc_Frame_t * pAbc, char * FileName, bool fE int nFileSize; // open the BLIF file for binary reading -// pFile = Io_FileOpen( FileName, "open_path", "rb" ); - pFile = fopen( FileName, "rb" ); + pFile = Io_FileOpen( FileName, "open_path", "rb", 1 ); +// pFile = fopen( FileName, "rb" ); // if we got this far, file should be okay otherwise would // have been detected by caller assert ( pFile != NULL ); diff --git a/src/map/super/super.c b/src/map/super/super.c index a3fbc98c..4b4968dd 100644 --- a/src/map/super/super.c +++ b/src/map/super/super.c @@ -245,8 +245,8 @@ int Super_CommandSupergates( Abc_Frame_t * pAbc, int argc, char **argv ) // get the input file name FileName = argv[util_optind]; -// if ( (pFile = Io_FileOpen( FileName, "open_path", "r" )) == NULL ) - if ( (pFile = fopen( FileName, "r" )) == NULL ) + if ( (pFile = Io_FileOpen( FileName, "open_path", "r", 0 )) == NULL ) +// if ( (pFile = fopen( FileName, "r" )) == NULL ) { fprintf( pErr, "Cannot open input file \"%s\". ", FileName ); if (( FileName = Extra_FileGetSimilarName( FileName, ".genlib", ".lib", ".gen", ".g", NULL ) )) diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h index bb776ab7..0d0c93a8 100644 --- a/src/misc/extra/extra.h +++ b/src/misc/extra/extra.h @@ -106,7 +106,35 @@ typedef unsigned long long uint64; /* Various Utilities */ /*===========================================================================*/ +/*=== extraBddAuto.c ========================================================*/ + +extern DdNode * Extra_bddSpaceFromFunctionFast( DdManager * dd, DdNode * bFunc ); +extern DdNode * Extra_bddSpaceFromFunction( DdManager * dd, DdNode * bF, DdNode * bG ); +extern DdNode * extraBddSpaceFromFunction( DdManager * dd, DdNode * bF, DdNode * bG ); +extern DdNode * Extra_bddSpaceFromFunctionPos( DdManager * dd, DdNode * bFunc ); +extern DdNode * extraBddSpaceFromFunctionPos( DdManager * dd, DdNode * bFunc ); +extern DdNode * Extra_bddSpaceFromFunctionNeg( DdManager * dd, DdNode * bFunc ); +extern DdNode * extraBddSpaceFromFunctionNeg( DdManager * dd, DdNode * bFunc ); + +extern DdNode * Extra_bddSpaceCanonVars( DdManager * dd, DdNode * bSpace ); +extern DdNode * extraBddSpaceCanonVars( DdManager * dd, DdNode * bSpace ); + +extern DdNode * Extra_bddSpaceEquations( DdManager * dd, DdNode * bSpace ); +extern DdNode * Extra_bddSpaceEquationsNeg( DdManager * dd, DdNode * bSpace ); +extern DdNode * extraBddSpaceEquationsNeg( DdManager * dd, DdNode * bSpace ); +extern DdNode * Extra_bddSpaceEquationsPos( DdManager * dd, DdNode * bSpace ); +extern DdNode * extraBddSpaceEquationsPos( DdManager * dd, DdNode * bSpace ); + +extern DdNode * Extra_bddSpaceFromMatrixPos( DdManager * dd, DdNode * zA ); +extern DdNode * extraBddSpaceFromMatrixPos( DdManager * dd, DdNode * zA ); +extern DdNode * Extra_bddSpaceFromMatrixNeg( DdManager * dd, DdNode * zA ); +extern DdNode * extraBddSpaceFromMatrixNeg( DdManager * dd, DdNode * zA ); + +extern DdNode * Extra_bddSpaceReduce( DdManager * dd, DdNode * bFunc, DdNode * bCanonVars ); +extern DdNode ** Extra_bddSpaceExorGates( DdManager * dd, DdNode * bFuncRed, DdNode * zEquations ); + /*=== extraBddMisc.c ========================================================*/ + extern DdNode * Extra_TransferPermute( DdManager * ddSource, DdManager * ddDestination, DdNode * f, int * Permute ); extern DdNode * Extra_TransferLevelByLevel( DdManager * ddSource, DdManager * ddDestination, DdNode * f ); extern DdNode * Extra_bddRemapUp( DdManager * dd, DdNode * bF ); @@ -126,6 +154,7 @@ extern DdNode * Extra_bddFindOneCube( DdManager * dd, DdNode * bF ); extern DdNode * Extra_bddGetOneCube( DdManager * dd, DdNode * bFunc ); extern DdNode * Extra_bddComputeRangeCube( DdManager * dd, int iStart, int iStop ); extern DdNode * Extra_bddBitsToCube( DdManager * dd, int Code, int CodeWidth, DdNode ** pbVars, int fMsbFirst ); +extern DdNode * Extra_bddSupportNegativeCube( DdManager * dd, DdNode * f ); /*=== extraBddKmap.c ================================================================*/ @@ -185,6 +214,46 @@ extern DdNode * extraZddTuplesFromBdd( DdManager * dd, DdNode * bVarsK, DdNo extern DdNode * Extra_zddSelectOneSubset( DdManager * dd, DdNode * zS ); extern DdNode * extraZddSelectOneSubset( DdManager * dd, DdNode * zS ); +/*=== extraBddUnate.c =================================================================*/ + +typedef struct Extra_UnateVar_t_ Extra_UnateVar_t; +struct Extra_UnateVar_t_ { + unsigned iVar : 30; // index of the variable + unsigned Pos : 1; // 1 if positive unate + unsigned Neg : 1; // 1 if negative unate +}; + +typedef struct Extra_UnateInfo_t_ Extra_UnateInfo_t; +struct Extra_UnateInfo_t_ { + int nVars; // the number of variables in the support + int nVarsMax; // the number of variables in the DD manager + int nUnate; // the number of unate variables + Extra_UnateVar_t * pVars; // the array of variables present in the support +}; + +/* allocates the data structure */ +extern Extra_UnateInfo_t * Extra_UnateInfoAllocate( int nVars ); +/* deallocates the data structure */ +extern void Extra_UnateInfoDissolve( Extra_UnateInfo_t * ); +/* print the contents the data structure */ +extern void Extra_UnateInfoPrint( Extra_UnateInfo_t * ); +/* converts the ZDD into the Extra_SymmInfo_t structure */ +extern Extra_UnateInfo_t * Extra_UnateInfoCreateFromZdd( DdManager * dd, DdNode * zUnate, DdNode * bVars ); +/* naive check of unateness of one variable */ +extern int Extra_bddCheckUnateNaive( DdManager * dd, DdNode * bF, int iVar ); + +/* computes the unateness information for the function */ +extern Extra_UnateInfo_t * Extra_UnateComputeFast( DdManager * dd, DdNode * bFunc ); +extern Extra_UnateInfo_t * Extra_UnateComputeSlow( DdManager * dd, DdNode * bFunc ); + +/* computes the classical symmetry information as a ZDD */ +extern DdNode * Extra_zddUnateInfoCompute( DdManager * dd, DdNode * bF, DdNode * bVars ); +extern DdNode * extraZddUnateInfoCompute( DdManager * dd, DdNode * bF, DdNode * bVars ); + +/* converts a set of variables into a set of singleton subsets */ +extern DdNode * Extra_zddGetSingletonsBoth( DdManager * dd, DdNode * bVars ); +extern DdNode * extraZddGetSingletonsBoth( DdManager * dd, DdNode * bVars ); + /*=== extraUtilBitMatrix.c ================================================================*/ typedef struct Extra_BitMat_t_ Extra_BitMat_t; diff --git a/src/misc/extra/extraBddAuto.c b/src/misc/extra/extraBddAuto.c new file mode 100644 index 00000000..21a969ba --- /dev/null +++ b/src/misc/extra/extraBddAuto.c @@ -0,0 +1,1558 @@ +/**CFile**************************************************************** + + FileName [extraBddAuto.c] + + PackageName [extra] + + Synopsis [Computation of autosymmetries.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 2.0. Started - September 1, 2003.] + + Revision [$Id: extraBddAuto.c,v 1.0 2003/05/21 18:03:50 alanmi Exp $] + +***********************************************************************/ + +#include "extra.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticEnd***************************************************************/ + + +/* + LinearSpace(f) = Space(f,f) + + Space(f,g) + { + if ( f = const ) + { + if ( f = g ) return 1; + else return 0; + } + if ( g = const ) return 0; + return x' * Space(fx',gx') * Space(fx,gx) + x * Space(fx',gx) * Space(fx,gx'); + } + + Equations(s) = Pos(s) + Neg(s); + + Pos(s) + { + if ( s = 0 ) return 1; + if ( s = 1 ) return 0; + if ( sx'= 0 ) return Pos(sx) + x; + if ( sx = 0 ) return Pos(sx'); + return 1 * [Pos(sx') & Pos(sx)] + x * [Pos(sx') & Neg(sx)]; + } + + Neg(s) + { + if ( s = 0 ) return 1; + if ( s = 1 ) return 0; + if ( sx'= 0 ) return Neg(sx); + if ( sx = 0 ) return Neg(sx') + x; + return 1 * [Neg(sx') & Neg(sx)] + x * [Neg(sx') & Pos(sx)]; + } + + + SpaceP(A) + { + if ( A = 0 ) return 1; + if ( A = 1 ) return 1; + return x' * SpaceP(Ax') * SpaceP(Ax) + x * SpaceP(Ax') * SpaceN(Ax); + } + + SpaceN(A) + { + if ( A = 0 ) return 1; + if ( A = 1 ) return 0; + return x' * SpaceN(Ax') * SpaceN(Ax) + x * SpaceN(Ax') * SpaceP(Ax); + } + + + LinInd(A) + { + if ( A = const ) return 1; + if ( !LinInd(Ax') ) return 0; + if ( !LinInd(Ax) ) return 0; + if ( LinSumOdd(Ax') & LinSumEven(Ax) != 0 ) return 0; + if ( LinSumEven(Ax') & LinSumEven(Ax) != 0 ) return 0; + return 1; + } + + LinSumOdd(A) + { + if ( A = 0 ) return 0; // Odd0 ---e-- Odd1 + if ( A = 1 ) return 1; // \ o + Odd0 = LinSumOdd(Ax'); // x is absent // \ + Even0 = LinSumEven(Ax'); // x is absent // / o + Odd1 = LinSumOdd(Ax); // x is present // Even0 ---e-- Even1 + Even1 = LinSumEven(Ax); // x is absent + return 1 * [Odd0 + ExorP(Odd0, Even1)] + x * [Odd1 + ExorP(Odd1, Even0)]; + } + + LinSumEven(A) + { + if ( A = 0 ) return 0; + if ( A = 1 ) return 0; + Odd0 = LinSumOdd(Ax'); // x is absent + Even0 = LinSumEven(Ax'); // x is absent + Odd1 = LinSumOdd(Ax); // x is present + Even1 = LinSumEven(Ax); // x is absent + return 1 * [Even0 + Even1 + ExorP(Even0, Even1)] + x * [ExorP(Odd0, Odd1)]; + } + +*/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceFromFunctionFast( DdManager * dd, DdNode * bFunc ) +{ + int * pSupport; + int * pPermute; + int * pPermuteBack; + DdNode ** pCompose; + DdNode * bCube, * bTemp; + DdNode * bSpace, * bFunc1, * bFunc2, * bSpaceShift; + int nSupp, Counter; + int i, lev; + + // get the support + pSupport = ALLOC( int, ddMax(dd->size,dd->sizeZ) ); + Extra_SupportArray( dd, bFunc, pSupport ); + nSupp = 0; + for ( i = 0; i < dd->size; i++ ) + if ( pSupport[i] ) + nSupp++; + + // make sure the manager has enough variables + if ( 2*nSupp > dd->size ) + { + printf( "Cannot derive linear space, because DD manager does not have enough variables.\n" ); + fflush( stdout ); + free( pSupport ); + return NULL; + } + + // create the permutation arrays + pPermute = ALLOC( int, dd->size ); + pPermuteBack = ALLOC( int, dd->size ); + pCompose = ALLOC( DdNode *, dd->size ); + for ( i = 0; i < dd->size; i++ ) + { + pPermute[i] = i; + pPermuteBack[i] = i; + pCompose[i] = dd->vars[i]; Cudd_Ref( pCompose[i] ); + } + + // remap the function in such a way that the variables are interleaved + Counter = 0; + bCube = b1; Cudd_Ref( bCube ); + for ( lev = 0; lev < dd->size; lev++ ) + if ( pSupport[ dd->invperm[lev] ] ) + { // var "dd->invperm[lev]" on level "lev" should go to level 2*Counter; + pPermute[ dd->invperm[lev] ] = dd->invperm[2*Counter]; + // var from level 2*Counter+1 should go back to the place of this var + pPermuteBack[ dd->invperm[2*Counter+1] ] = dd->invperm[lev]; + // the permutation should be defined in such a way that variable + // on level 2*Counter is replaced by an EXOR of itself and var on the next level + Cudd_Deref( pCompose[ dd->invperm[2*Counter] ] ); + pCompose[ dd->invperm[2*Counter] ] = + Cudd_bddXor( dd, dd->vars[ dd->invperm[2*Counter] ], dd->vars[ dd->invperm[2*Counter+1] ] ); + Cudd_Ref( pCompose[ dd->invperm[2*Counter] ] ); + // add this variable to the cube + bCube = Cudd_bddAnd( dd, bTemp = bCube, dd->vars[ dd->invperm[2*Counter] ] ); Cudd_Ref( bCube ); + Cudd_RecursiveDeref( dd, bTemp ); + // increment the counter + Counter ++; + } + + // permute the functions + bFunc1 = Cudd_bddPermute( dd, bFunc, pPermute ); Cudd_Ref( bFunc1 ); + // compose to gate the function depending on both vars + bFunc2 = Cudd_bddVectorCompose( dd, bFunc1, pCompose ); Cudd_Ref( bFunc2 ); + // gate the vector space + // L(a) = ForAll x [ F(x) = F(x+a) ] = Not( Exist x [ F(x) (+) F(x+a) ] ) + bSpaceShift = Cudd_bddXorExistAbstract( dd, bFunc1, bFunc2, bCube ); Cudd_Ref( bSpaceShift ); + bSpaceShift = Cudd_Not( bSpaceShift ); + // permute the space back into the original mapping + bSpace = Cudd_bddPermute( dd, bSpaceShift, pPermuteBack ); Cudd_Ref( bSpace ); + Cudd_RecursiveDeref( dd, bFunc1 ); + Cudd_RecursiveDeref( dd, bFunc2 ); + Cudd_RecursiveDeref( dd, bSpaceShift ); + Cudd_RecursiveDeref( dd, bCube ); + + for ( i = 0; i < dd->size; i++ ) + Cudd_RecursiveDeref( dd, pCompose[i] ); + free( pPermute ); + free( pPermuteBack ); + free( pCompose ); + free( pSupport ); + + Cudd_Deref( bSpace ); + return bSpace; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceFromFunction( DdManager * dd, DdNode * bF, DdNode * bG ) +{ + DdNode * bRes; + do { + dd->reordered = 0; + bRes = extraBddSpaceFromFunction( dd, bF, bG ); + } while (dd->reordered == 1); + return bRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceFromFunctionPos( DdManager * dd, DdNode * bFunc ) +{ + DdNode * bRes; + do { + dd->reordered = 0; + bRes = extraBddSpaceFromFunctionPos( dd, bFunc ); + } while (dd->reordered == 1); + return bRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceFromFunctionNeg( DdManager * dd, DdNode * bFunc ) +{ + DdNode * bRes; + do { + dd->reordered = 0; + bRes = extraBddSpaceFromFunctionNeg( dd, bFunc ); + } while (dd->reordered == 1); + return bRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceCanonVars( DdManager * dd, DdNode * bSpace ) +{ + DdNode * bRes; + do { + dd->reordered = 0; + bRes = extraBddSpaceCanonVars( dd, bSpace ); + } while (dd->reordered == 1); + return bRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceReduce( DdManager * dd, DdNode * bFunc, DdNode * bCanonVars ) +{ + DdNode * bNegCube; + DdNode * bResult; + bNegCube = Extra_bddSupportNegativeCube( dd, bCanonVars ); Cudd_Ref( bNegCube ); + bResult = Cudd_Cofactor( dd, bFunc, bNegCube ); Cudd_Ref( bResult ); + Cudd_RecursiveDeref( dd, bNegCube ); + Cudd_Deref( bResult ); + return bResult; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceEquations( DdManager * dd, DdNode * bSpace ) +{ + DdNode * zRes; + DdNode * zEquPos; + DdNode * zEquNeg; + zEquPos = Extra_bddSpaceEquationsPos( dd, bSpace ); Cudd_Ref( zEquPos ); + zEquNeg = Extra_bddSpaceEquationsNeg( dd, bSpace ); Cudd_Ref( zEquNeg ); + zRes = Cudd_zddUnion( dd, zEquPos, zEquNeg ); Cudd_Ref( zRes ); + Cudd_RecursiveDerefZdd( dd, zEquPos ); + Cudd_RecursiveDerefZdd( dd, zEquNeg ); + Cudd_Deref( zRes ); + return zRes; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceEquationsPos( DdManager * dd, DdNode * bSpace ) +{ + DdNode * zRes; + do { + dd->reordered = 0; + zRes = extraBddSpaceEquationsPos( dd, bSpace ); + } while (dd->reordered == 1); + return zRes; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceEquationsNeg( DdManager * dd, DdNode * bSpace ) +{ + DdNode * zRes; + do { + dd->reordered = 0; + zRes = extraBddSpaceEquationsNeg( dd, bSpace ); + } while (dd->reordered == 1); + return zRes; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceFromMatrixPos( DdManager * dd, DdNode * zA ) +{ + DdNode * bRes; + do { + dd->reordered = 0; + bRes = extraBddSpaceFromMatrixPos( dd, zA ); + } while (dd->reordered == 1); + return bRes; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Extra_bddSpaceFromMatrixNeg( DdManager * dd, DdNode * zA ) +{ + DdNode * bRes; + do { + dd->reordered = 0; + bRes = extraBddSpaceFromMatrixNeg( dd, zA ); + } while (dd->reordered == 1); + return bRes; +} + +/**Function************************************************************* + + Synopsis [Counts the number of literals in one combination.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Extra_zddLitCountComb( DdManager * dd, DdNode * zComb ) +{ + int Counter; + if ( zComb == z0 ) + return 0; + Counter = 0; + for ( ; zComb != z1; zComb = cuddT(zComb) ) + Counter++; + return Counter; +} + +/**Function************************************************************* + + Synopsis [] + + Description [Returns the array of ZDDs with the number equal to the number of + vars in the DD manager. If the given var is non-canonical, this array contains + the referenced ZDD representing literals in the corresponding EXOR equation.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode ** Extra_bddSpaceExorGates( DdManager * dd, DdNode * bFuncRed, DdNode * zEquations ) +{ + DdNode ** pzRes; + int * pVarsNonCan; + DdNode * zEquRem; + int iVarNonCan; + DdNode * zExor, * zTemp; + + // get the set of non-canonical variables + pVarsNonCan = ALLOC( int, ddMax(dd->size,dd->sizeZ) ); + Extra_SupportArray( dd, bFuncRed, pVarsNonCan ); + + // allocate storage for the EXOR sets + pzRes = ALLOC( DdNode *, dd->size ); + memset( pzRes, 0, sizeof(DdNode *) * dd->size ); + + // go through all the equations + zEquRem = zEquations; Cudd_Ref( zEquRem ); + while ( zEquRem != z0 ) + { + // extract one product + zExor = Extra_zddSelectOneSubset( dd, zEquRem ); Cudd_Ref( zExor ); + // remove it from the set + zEquRem = Cudd_zddDiff( dd, zTemp = zEquRem, zExor ); Cudd_Ref( zEquRem ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + + // locate the non-canonical variable + iVarNonCan = -1; + for ( zTemp = zExor; zTemp != z1; zTemp = cuddT(zTemp) ) + { + if ( pVarsNonCan[zTemp->index/2] == 1 ) + { + assert( iVarNonCan == -1 ); + iVarNonCan = zTemp->index/2; + } + } + assert( iVarNonCan != -1 ); + + if ( Extra_zddLitCountComb( dd, zExor ) > 1 ) + pzRes[ iVarNonCan ] = zExor; // takes ref + else + Cudd_RecursiveDerefZdd( dd, zExor ); + } + Cudd_RecursiveDerefZdd( dd, zEquRem ); + + free( pVarsNonCan ); + return pzRes; +} + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs the recursive steps of Extra_bddSpaceFromFunction.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * extraBddSpaceFromFunction( DdManager * dd, DdNode * bF, DdNode * bG ) +{ + DdNode * bRes; + DdNode * bFR, * bGR; + + bFR = Cudd_Regular( bF ); + bGR = Cudd_Regular( bG ); + if ( cuddIsConstant(bFR) ) + { + if ( bF == bG ) + return b1; + else + return b0; + } + if ( cuddIsConstant(bGR) ) + return b0; + // both bFunc and bCore are not constants + + // the operation is commutative - normalize the problem + if ( (unsigned)bF > (unsigned)bG ) + return extraBddSpaceFromFunction(dd, bG, bF); + + + if ( bRes = cuddCacheLookup2(dd, extraBddSpaceFromFunction, bF, bG) ) + return bRes; + else + { + DdNode * bF0, * bF1; + DdNode * bG0, * bG1; + DdNode * bTemp1, * bTemp2; + DdNode * bRes0, * bRes1; + int LevelF, LevelG; + int index; + + LevelF = dd->perm[bFR->index]; + LevelG = dd->perm[bGR->index]; + if ( LevelF <= LevelG ) + { + index = dd->invperm[LevelF]; + if ( bFR != bF ) + { + bF0 = Cudd_Not( cuddE(bFR) ); + bF1 = Cudd_Not( cuddT(bFR) ); + } + else + { + bF0 = cuddE(bFR); + bF1 = cuddT(bFR); + } + } + else + { + index = dd->invperm[LevelG]; + bF0 = bF1 = bF; + } + + if ( LevelG <= LevelF ) + { + if ( bGR != bG ) + { + bG0 = Cudd_Not( cuddE(bGR) ); + bG1 = Cudd_Not( cuddT(bGR) ); + } + else + { + bG0 = cuddE(bGR); + bG1 = cuddT(bGR); + } + } + else + bG0 = bG1 = bG; + + bTemp1 = extraBddSpaceFromFunction( dd, bF0, bG0 ); + if ( bTemp1 == NULL ) + return NULL; + cuddRef( bTemp1 ); + + bTemp2 = extraBddSpaceFromFunction( dd, bF1, bG1 ); + if ( bTemp2 == NULL ) + { + Cudd_RecursiveDeref( dd, bTemp1 ); + return NULL; + } + cuddRef( bTemp2 ); + + + bRes0 = cuddBddAndRecur( dd, bTemp1, bTemp2 ); + if ( bRes0 == NULL ) + { + Cudd_RecursiveDeref( dd, bTemp1 ); + Cudd_RecursiveDeref( dd, bTemp2 ); + return NULL; + } + cuddRef( bRes0 ); + Cudd_RecursiveDeref( dd, bTemp1 ); + Cudd_RecursiveDeref( dd, bTemp2 ); + + + bTemp1 = extraBddSpaceFromFunction( dd, bF0, bG1 ); + if ( bTemp1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + return NULL; + } + cuddRef( bTemp1 ); + + bTemp2 = extraBddSpaceFromFunction( dd, bF1, bG0 ); + if ( bTemp2 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + Cudd_RecursiveDeref( dd, bTemp1 ); + return NULL; + } + cuddRef( bTemp2 ); + + bRes1 = cuddBddAndRecur( dd, bTemp1, bTemp2 ); + if ( bRes1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + Cudd_RecursiveDeref( dd, bTemp1 ); + Cudd_RecursiveDeref( dd, bTemp2 ); + return NULL; + } + cuddRef( bRes1 ); + Cudd_RecursiveDeref( dd, bTemp1 ); + Cudd_RecursiveDeref( dd, bTemp2 ); + + + + // consider the case when Res0 and Res1 are the same node + if ( bRes0 == bRes1 ) + bRes = bRes1; + // consider the case when Res1 is complemented + else if ( Cudd_IsComplement(bRes1) ) + { + bRes = cuddUniqueInter(dd, index, Cudd_Not(bRes1), Cudd_Not(bRes0)); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + bRes = Cudd_Not(bRes); + } + else + { + bRes = cuddUniqueInter( dd, index, bRes1, bRes0 ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + } + cuddDeref( bRes0 ); + cuddDeref( bRes1 ); + + // insert the result into cache + cuddCacheInsert2(dd, extraBddSpaceFromFunction, bF, bG, bRes); + return bRes; + } +} /* end of extraBddSpaceFromFunction */ + + + +/**Function************************************************************* + + Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * extraBddSpaceFromFunctionPos( DdManager * dd, DdNode * bF ) +{ + DdNode * bRes, * bFR; + statLine( dd ); + + bFR = Cudd_Regular(bF); + if ( cuddIsConstant(bFR) ) + return b1; + + if ( bRes = cuddCacheLookup1(dd, extraBddSpaceFromFunctionPos, bF) ) + return bRes; + else + { + DdNode * bF0, * bF1; + DdNode * bPos0, * bPos1; + DdNode * bNeg0, * bNeg1; + DdNode * bRes0, * bRes1; + + if ( bFR != bF ) // bF is complemented + { + bF0 = Cudd_Not( cuddE(bFR) ); + bF1 = Cudd_Not( cuddT(bFR) ); + } + else + { + bF0 = cuddE(bFR); + bF1 = cuddT(bFR); + } + + + bPos0 = extraBddSpaceFromFunctionPos( dd, bF0 ); + if ( bPos0 == NULL ) + return NULL; + cuddRef( bPos0 ); + + bPos1 = extraBddSpaceFromFunctionPos( dd, bF1 ); + if ( bPos1 == NULL ) + { + Cudd_RecursiveDeref( dd, bPos0 ); + return NULL; + } + cuddRef( bPos1 ); + + bRes0 = cuddBddAndRecur( dd, bPos0, bPos1 ); + if ( bRes0 == NULL ) + { + Cudd_RecursiveDeref( dd, bPos0 ); + Cudd_RecursiveDeref( dd, bPos1 ); + return NULL; + } + cuddRef( bRes0 ); + Cudd_RecursiveDeref( dd, bPos0 ); + Cudd_RecursiveDeref( dd, bPos1 ); + + + bNeg0 = extraBddSpaceFromFunctionNeg( dd, bF0 ); + if ( bNeg0 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + return NULL; + } + cuddRef( bNeg0 ); + + bNeg1 = extraBddSpaceFromFunctionNeg( dd, bF1 ); + if ( bNeg1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + Cudd_RecursiveDeref( dd, bNeg0 ); + return NULL; + } + cuddRef( bNeg1 ); + + bRes1 = cuddBddAndRecur( dd, bNeg0, bNeg1 ); + if ( bRes1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + Cudd_RecursiveDeref( dd, bNeg0 ); + Cudd_RecursiveDeref( dd, bNeg1 ); + return NULL; + } + cuddRef( bRes1 ); + Cudd_RecursiveDeref( dd, bNeg0 ); + Cudd_RecursiveDeref( dd, bNeg1 ); + + + // consider the case when Res0 and Res1 are the same node + if ( bRes0 == bRes1 ) + bRes = bRes1; + // consider the case when Res1 is complemented + else if ( Cudd_IsComplement(bRes1) ) + { + bRes = cuddUniqueInter( dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0) ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + bRes = Cudd_Not(bRes); + } + else + { + bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + } + cuddDeref( bRes0 ); + cuddDeref( bRes1 ); + + cuddCacheInsert1( dd, extraBddSpaceFromFunctionPos, bF, bRes ); + return bRes; + } +} + + + +/**Function************************************************************* + + Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * extraBddSpaceFromFunctionNeg( DdManager * dd, DdNode * bF ) +{ + DdNode * bRes, * bFR; + statLine( dd ); + + bFR = Cudd_Regular(bF); + if ( cuddIsConstant(bFR) ) + return b0; + + if ( bRes = cuddCacheLookup1(dd, extraBddSpaceFromFunctionNeg, bF) ) + return bRes; + else + { + DdNode * bF0, * bF1; + DdNode * bPos0, * bPos1; + DdNode * bNeg0, * bNeg1; + DdNode * bRes0, * bRes1; + + if ( bFR != bF ) // bF is complemented + { + bF0 = Cudd_Not( cuddE(bFR) ); + bF1 = Cudd_Not( cuddT(bFR) ); + } + else + { + bF0 = cuddE(bFR); + bF1 = cuddT(bFR); + } + + + bPos0 = extraBddSpaceFromFunctionNeg( dd, bF0 ); + if ( bPos0 == NULL ) + return NULL; + cuddRef( bPos0 ); + + bPos1 = extraBddSpaceFromFunctionNeg( dd, bF1 ); + if ( bPos1 == NULL ) + { + Cudd_RecursiveDeref( dd, bPos0 ); + return NULL; + } + cuddRef( bPos1 ); + + bRes0 = cuddBddAndRecur( dd, bPos0, bPos1 ); + if ( bRes0 == NULL ) + { + Cudd_RecursiveDeref( dd, bPos0 ); + Cudd_RecursiveDeref( dd, bPos1 ); + return NULL; + } + cuddRef( bRes0 ); + Cudd_RecursiveDeref( dd, bPos0 ); + Cudd_RecursiveDeref( dd, bPos1 ); + + + bNeg0 = extraBddSpaceFromFunctionPos( dd, bF0 ); + if ( bNeg0 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + return NULL; + } + cuddRef( bNeg0 ); + + bNeg1 = extraBddSpaceFromFunctionPos( dd, bF1 ); + if ( bNeg1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + Cudd_RecursiveDeref( dd, bNeg0 ); + return NULL; + } + cuddRef( bNeg1 ); + + bRes1 = cuddBddAndRecur( dd, bNeg0, bNeg1 ); + if ( bRes1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + Cudd_RecursiveDeref( dd, bNeg0 ); + Cudd_RecursiveDeref( dd, bNeg1 ); + return NULL; + } + cuddRef( bRes1 ); + Cudd_RecursiveDeref( dd, bNeg0 ); + Cudd_RecursiveDeref( dd, bNeg1 ); + + + // consider the case when Res0 and Res1 are the same node + if ( bRes0 == bRes1 ) + bRes = bRes1; + // consider the case when Res1 is complemented + else if ( Cudd_IsComplement(bRes1) ) + { + bRes = cuddUniqueInter( dd, bFR->index, Cudd_Not(bRes1), Cudd_Not(bRes0) ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + bRes = Cudd_Not(bRes); + } + else + { + bRes = cuddUniqueInter( dd, bFR->index, bRes1, bRes0 ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + } + cuddDeref( bRes0 ); + cuddDeref( bRes1 ); + + cuddCacheInsert1( dd, extraBddSpaceFromFunctionNeg, bF, bRes ); + return bRes; + } +} + + + +/**Function************************************************************* + + Synopsis [Performs the recursive step of Extra_bddSpaceCanonVars().] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * extraBddSpaceCanonVars( DdManager * dd, DdNode * bF ) +{ + DdNode * bRes, * bFR; + statLine( dd ); + + bFR = Cudd_Regular(bF); + if ( cuddIsConstant(bFR) ) + return bF; + + if ( bRes = cuddCacheLookup1(dd, extraBddSpaceCanonVars, bF) ) + return bRes; + else + { + DdNode * bF0, * bF1; + DdNode * bRes, * bRes0; + + if ( bFR != bF ) // bF is complemented + { + bF0 = Cudd_Not( cuddE(bFR) ); + bF1 = Cudd_Not( cuddT(bFR) ); + } + else + { + bF0 = cuddE(bFR); + bF1 = cuddT(bFR); + } + + if ( bF0 == b0 ) + { + bRes = extraBddSpaceCanonVars( dd, bF1 ); + if ( bRes == NULL ) + return NULL; + } + else if ( bF1 == b0 ) + { + bRes = extraBddSpaceCanonVars( dd, bF0 ); + if ( bRes == NULL ) + return NULL; + } + else + { + bRes0 = extraBddSpaceCanonVars( dd, bF0 ); + if ( bRes0 == NULL ) + return NULL; + cuddRef( bRes0 ); + + bRes = cuddUniqueInter( dd, bFR->index, bRes0, b0 ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref( dd,bRes0 ); + return NULL; + } + cuddDeref( bRes0 ); + } + + cuddCacheInsert1( dd, extraBddSpaceCanonVars, bF, bRes ); + return bRes; + } +} + +/**Function************************************************************* + + Synopsis [Performs the recursive step of Extra_bddSpaceEquationsPos().] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * extraBddSpaceEquationsPos( DdManager * dd, DdNode * bF ) +{ + DdNode * zRes; + statLine( dd ); + + if ( bF == b0 ) + return z1; + if ( bF == b1 ) + return z0; + + if ( zRes = cuddCacheLookup1Zdd(dd, extraBddSpaceEquationsPos, bF) ) + return zRes; + else + { + DdNode * bFR, * bF0, * bF1; + DdNode * zPos0, * zPos1, * zNeg1; + DdNode * zRes, * zRes0, * zRes1; + + bFR = Cudd_Regular(bF); + if ( bFR != bF ) // bF is complemented + { + bF0 = Cudd_Not( cuddE(bFR) ); + bF1 = Cudd_Not( cuddT(bFR) ); + } + else + { + bF0 = cuddE(bFR); + bF1 = cuddT(bFR); + } + + if ( bF0 == b0 ) + { + zRes1 = extraBddSpaceEquationsPos( dd, bF1 ); + if ( zRes1 == NULL ) + return NULL; + cuddRef( zRes1 ); + + // add the current element to the set + zRes = cuddZddGetNode( dd, 2*bFR->index, z1, zRes1 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes1); + return NULL; + } + cuddDeref( zRes1 ); + } + else if ( bF1 == b0 ) + { + zRes = extraBddSpaceEquationsPos( dd, bF0 ); + if ( zRes == NULL ) + return NULL; + } + else + { + zPos0 = extraBddSpaceEquationsPos( dd, bF0 ); + if ( zPos0 == NULL ) + return NULL; + cuddRef( zPos0 ); + + zPos1 = extraBddSpaceEquationsPos( dd, bF1 ); + if ( zPos1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zPos0); + return NULL; + } + cuddRef( zPos1 ); + + zNeg1 = extraBddSpaceEquationsNeg( dd, bF1 ); + if ( zNeg1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zPos0); + Cudd_RecursiveDerefZdd(dd, zPos1); + return NULL; + } + cuddRef( zNeg1 ); + + + zRes0 = cuddZddIntersect( dd, zPos0, zPos1 ); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zNeg1); + Cudd_RecursiveDerefZdd(dd, zPos0); + Cudd_RecursiveDerefZdd(dd, zPos1); + return NULL; + } + cuddRef( zRes0 ); + + zRes1 = cuddZddIntersect( dd, zPos0, zNeg1 ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes0); + Cudd_RecursiveDerefZdd(dd, zNeg1); + Cudd_RecursiveDerefZdd(dd, zPos0); + Cudd_RecursiveDerefZdd(dd, zPos1); + return NULL; + } + cuddRef( zRes1 ); + Cudd_RecursiveDerefZdd(dd, zNeg1); + Cudd_RecursiveDerefZdd(dd, zPos0); + Cudd_RecursiveDerefZdd(dd, zPos1); + // only zRes0 and zRes1 are refed at this point + + zRes = cuddZddGetNode( dd, 2*bFR->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes0); + Cudd_RecursiveDerefZdd(dd, zRes1); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + + cuddCacheInsert1( dd, extraBddSpaceEquationsPos, bF, zRes ); + return zRes; + } +} + + +/**Function************************************************************* + + Synopsis [Performs the recursive step of Extra_bddSpaceEquationsNev().] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * extraBddSpaceEquationsNeg( DdManager * dd, DdNode * bF ) +{ + DdNode * zRes; + statLine( dd ); + + if ( bF == b0 ) + return z1; + if ( bF == b1 ) + return z0; + + if ( zRes = cuddCacheLookup1Zdd(dd, extraBddSpaceEquationsNeg, bF) ) + return zRes; + else + { + DdNode * bFR, * bF0, * bF1; + DdNode * zPos0, * zPos1, * zNeg1; + DdNode * zRes, * zRes0, * zRes1; + + bFR = Cudd_Regular(bF); + if ( bFR != bF ) // bF is complemented + { + bF0 = Cudd_Not( cuddE(bFR) ); + bF1 = Cudd_Not( cuddT(bFR) ); + } + else + { + bF0 = cuddE(bFR); + bF1 = cuddT(bFR); + } + + if ( bF0 == b0 ) + { + zRes = extraBddSpaceEquationsNeg( dd, bF1 ); + if ( zRes == NULL ) + return NULL; + } + else if ( bF1 == b0 ) + { + zRes0 = extraBddSpaceEquationsNeg( dd, bF0 ); + if ( zRes0 == NULL ) + return NULL; + cuddRef( zRes0 ); + + // add the current element to the set + zRes = cuddZddGetNode( dd, 2*bFR->index, z1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes0); + return NULL; + } + cuddDeref( zRes0 ); + } + else + { + zPos0 = extraBddSpaceEquationsNeg( dd, bF0 ); + if ( zPos0 == NULL ) + return NULL; + cuddRef( zPos0 ); + + zPos1 = extraBddSpaceEquationsNeg( dd, bF1 ); + if ( zPos1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zPos0); + return NULL; + } + cuddRef( zPos1 ); + + zNeg1 = extraBddSpaceEquationsPos( dd, bF1 ); + if ( zNeg1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zPos0); + Cudd_RecursiveDerefZdd(dd, zPos1); + return NULL; + } + cuddRef( zNeg1 ); + + + zRes0 = cuddZddIntersect( dd, zPos0, zPos1 ); + if ( zRes0 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zNeg1); + Cudd_RecursiveDerefZdd(dd, zPos0); + Cudd_RecursiveDerefZdd(dd, zPos1); + return NULL; + } + cuddRef( zRes0 ); + + zRes1 = cuddZddIntersect( dd, zPos0, zNeg1 ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes0); + Cudd_RecursiveDerefZdd(dd, zNeg1); + Cudd_RecursiveDerefZdd(dd, zPos0); + Cudd_RecursiveDerefZdd(dd, zPos1); + return NULL; + } + cuddRef( zRes1 ); + Cudd_RecursiveDerefZdd(dd, zNeg1); + Cudd_RecursiveDerefZdd(dd, zPos0); + Cudd_RecursiveDerefZdd(dd, zPos1); + // only zRes0 and zRes1 are refed at this point + + zRes = cuddZddGetNode( dd, 2*bFR->index, zRes1, zRes0 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd(dd, zRes0); + Cudd_RecursiveDerefZdd(dd, zRes1); + return NULL; + } + cuddDeref( zRes0 ); + cuddDeref( zRes1 ); + } + + cuddCacheInsert1( dd, extraBddSpaceEquationsNeg, bF, zRes ); + return zRes; + } +} + + + + +/**Function************************************************************* + + Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * extraBddSpaceFromMatrixPos( DdManager * dd, DdNode * zA ) +{ + DdNode * bRes; + statLine( dd ); + + if ( zA == z0 ) + return b1; + if ( zA == z1 ) + return b1; + + if ( bRes = cuddCacheLookup1(dd, extraBddSpaceFromMatrixPos, zA) ) + return bRes; + else + { + DdNode * bP0, * bP1; + DdNode * bN0, * bN1; + DdNode * bRes0, * bRes1; + + bP0 = extraBddSpaceFromMatrixPos( dd, cuddE(zA) ); + if ( bP0 == NULL ) + return NULL; + cuddRef( bP0 ); + + bP1 = extraBddSpaceFromMatrixPos( dd, cuddT(zA) ); + if ( bP1 == NULL ) + { + Cudd_RecursiveDeref( dd, bP0 ); + return NULL; + } + cuddRef( bP1 ); + + bRes0 = cuddBddAndRecur( dd, bP0, bP1 ); + if ( bRes0 == NULL ) + { + Cudd_RecursiveDeref( dd, bP0 ); + Cudd_RecursiveDeref( dd, bP1 ); + return NULL; + } + cuddRef( bRes0 ); + Cudd_RecursiveDeref( dd, bP0 ); + Cudd_RecursiveDeref( dd, bP1 ); + + + bN0 = extraBddSpaceFromMatrixPos( dd, cuddE(zA) ); + if ( bN0 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + return NULL; + } + cuddRef( bN0 ); + + bN1 = extraBddSpaceFromMatrixNeg( dd, cuddT(zA) ); + if ( bN1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + Cudd_RecursiveDeref( dd, bN0 ); + return NULL; + } + cuddRef( bN1 ); + + bRes1 = cuddBddAndRecur( dd, bN0, bN1 ); + if ( bRes1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + Cudd_RecursiveDeref( dd, bN0 ); + Cudd_RecursiveDeref( dd, bN1 ); + return NULL; + } + cuddRef( bRes1 ); + Cudd_RecursiveDeref( dd, bN0 ); + Cudd_RecursiveDeref( dd, bN1 ); + + + // consider the case when Res0 and Res1 are the same node + if ( bRes0 == bRes1 ) + bRes = bRes1; + // consider the case when Res1 is complemented + else if ( Cudd_IsComplement(bRes1) ) + { + bRes = cuddUniqueInter( dd, zA->index/2, Cudd_Not(bRes1), Cudd_Not(bRes0) ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + bRes = Cudd_Not(bRes); + } + else + { + bRes = cuddUniqueInter( dd, zA->index/2, bRes1, bRes0 ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + } + cuddDeref( bRes0 ); + cuddDeref( bRes1 ); + + cuddCacheInsert1( dd, extraBddSpaceFromMatrixPos, zA, bRes ); + return bRes; + } +} + + +/**Function************************************************************* + + Synopsis [Performs the recursive step of Extra_bddSpaceFromFunctionPos().] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * extraBddSpaceFromMatrixNeg( DdManager * dd, DdNode * zA ) +{ + DdNode * bRes; + statLine( dd ); + + if ( zA == z0 ) + return b1; + if ( zA == z1 ) + return b0; + + if ( bRes = cuddCacheLookup1(dd, extraBddSpaceFromMatrixNeg, zA) ) + return bRes; + else + { + DdNode * bP0, * bP1; + DdNode * bN0, * bN1; + DdNode * bRes0, * bRes1; + + bP0 = extraBddSpaceFromMatrixNeg( dd, cuddE(zA) ); + if ( bP0 == NULL ) + return NULL; + cuddRef( bP0 ); + + bP1 = extraBddSpaceFromMatrixNeg( dd, cuddT(zA) ); + if ( bP1 == NULL ) + { + Cudd_RecursiveDeref( dd, bP0 ); + return NULL; + } + cuddRef( bP1 ); + + bRes0 = cuddBddAndRecur( dd, bP0, bP1 ); + if ( bRes0 == NULL ) + { + Cudd_RecursiveDeref( dd, bP0 ); + Cudd_RecursiveDeref( dd, bP1 ); + return NULL; + } + cuddRef( bRes0 ); + Cudd_RecursiveDeref( dd, bP0 ); + Cudd_RecursiveDeref( dd, bP1 ); + + + bN0 = extraBddSpaceFromMatrixNeg( dd, cuddE(zA) ); + if ( bN0 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + return NULL; + } + cuddRef( bN0 ); + + bN1 = extraBddSpaceFromMatrixPos( dd, cuddT(zA) ); + if ( bN1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + Cudd_RecursiveDeref( dd, bN0 ); + return NULL; + } + cuddRef( bN1 ); + + bRes1 = cuddBddAndRecur( dd, bN0, bN1 ); + if ( bRes1 == NULL ) + { + Cudd_RecursiveDeref( dd, bRes0 ); + Cudd_RecursiveDeref( dd, bN0 ); + Cudd_RecursiveDeref( dd, bN1 ); + return NULL; + } + cuddRef( bRes1 ); + Cudd_RecursiveDeref( dd, bN0 ); + Cudd_RecursiveDeref( dd, bN1 ); + + + // consider the case when Res0 and Res1 are the same node + if ( bRes0 == bRes1 ) + bRes = bRes1; + // consider the case when Res1 is complemented + else if ( Cudd_IsComplement(bRes1) ) + { + bRes = cuddUniqueInter( dd, zA->index/2, Cudd_Not(bRes1), Cudd_Not(bRes0) ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + bRes = Cudd_Not(bRes); + } + else + { + bRes = cuddUniqueInter( dd, zA->index/2, bRes1, bRes0 ); + if ( bRes == NULL ) + { + Cudd_RecursiveDeref(dd,bRes0); + Cudd_RecursiveDeref(dd,bRes1); + return NULL; + } + } + cuddDeref( bRes0 ); + cuddDeref( bRes1 ); + + cuddCacheInsert1( dd, extraBddSpaceFromMatrixNeg, zA, bRes ); + return bRes; + } +} + + +/*---------------------------------------------------------------------------*/ +/* Definition of static functions */ +/*---------------------------------------------------------------------------*/ + diff --git a/src/misc/extra/extraBddMisc.c b/src/misc/extra/extraBddMisc.c index 932ed525..7d806ec7 100644 --- a/src/misc/extra/extraBddMisc.c +++ b/src/misc/extra/extraBddMisc.c @@ -719,6 +719,83 @@ DdNode * Extra_bddBitsToCube( DdManager * dd, int Code, int CodeWidth, DdNode ** return bResult; } /* end of Extra_bddBitsToCube */ +/**Function******************************************************************** + + Synopsis [Finds the support as a negative polarity cube.] + + Description [Finds the variables on which a DD depends. Returns a BDD + consisting of the product of the variables in the negative polarity + if successful; NULL otherwise.] + + SideEffects [None] + + SeeAlso [Cudd_VectorSupport Cudd_Support] + +******************************************************************************/ +DdNode * Extra_bddSupportNegativeCube( DdManager * dd, DdNode * f ) +{ + int *support; + DdNode *res, *tmp, *var; + int i, j; + int size; + + /* Allocate and initialize support array for ddSupportStep. */ + size = ddMax( dd->size, dd->sizeZ ); + support = ALLOC( int, size ); + if ( support == NULL ) + { + dd->errorCode = CUDD_MEMORY_OUT; + return ( NULL ); + } + for ( i = 0; i < size; i++ ) + { + support[i] = 0; + } + + /* Compute support and clean up markers. */ + ddSupportStep( Cudd_Regular( f ), support ); + ddClearFlag( Cudd_Regular( f ) ); + + /* Transform support from array to cube. */ + do + { + dd->reordered = 0; + res = DD_ONE( dd ); + cuddRef( res ); + for ( j = size - 1; j >= 0; j-- ) + { /* for each level bottom-up */ + i = ( j >= dd->size ) ? j : dd->invperm[j]; + if ( support[i] == 1 ) + { + var = cuddUniqueInter( dd, i, dd->one, Cudd_Not( dd->one ) ); + ////////////////////////////////////////////////////////////////// + var = Cudd_Not(var); + ////////////////////////////////////////////////////////////////// + cuddRef( var ); + tmp = cuddBddAndRecur( dd, res, var ); + if ( tmp == NULL ) + { + Cudd_RecursiveDeref( dd, res ); + Cudd_RecursiveDeref( dd, var ); + res = NULL; + break; + } + cuddRef( tmp ); + Cudd_RecursiveDeref( dd, res ); + Cudd_RecursiveDeref( dd, var ); + res = tmp; + } + } + } + while ( dd->reordered == 1 ); + + FREE( support ); + if ( res != NULL ) + cuddDeref( res ); + return ( res ); + +} /* end of Extra_SupportNeg */ + /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ diff --git a/src/misc/extra/extraBddUnate.c b/src/misc/extra/extraBddUnate.c new file mode 100644 index 00000000..b0297c77 --- /dev/null +++ b/src/misc/extra/extraBddUnate.c @@ -0,0 +1,641 @@ +/**CFile**************************************************************** + + FileName [extraBddUnate.c] + + PackageName [extra] + + Synopsis [Efficient methods to compute the information about + unate variables using an algorithm that is conceptually similar to + the algorithm for two-variable symmetry computation presented in: + A. Mishchenko. Fast Computation of Symmetries in Boolean Functions. + Transactions on CAD, Nov. 2003.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 2.0. Started - September 1, 2003.] + + Revision [$Id: extraBddUnate.c,v 1.0 2003/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "extra.h" + +/*---------------------------------------------------------------------------*/ +/* Constant declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Stucture declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Type declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Variable declarations */ +/*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*/ +/* Macro declarations */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticStart*************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Static function prototypes */ +/*---------------------------------------------------------------------------*/ + +/**AutomaticEnd***************************************************************/ + +/*---------------------------------------------------------------------------*/ +/* Definition of exported functions */ +/*---------------------------------------------------------------------------*/ + + +/**Function******************************************************************** + + Synopsis [Computes the classical symmetry information for the function.] + + Description [Returns the symmetry information in the form of Extra_UnateInfo_t structure.] + + SideEffects [If the ZDD variables are not derived from BDD variables with + multiplicity 2, this function may derive them in a wrong way.] + + SeeAlso [] + +******************************************************************************/ +Extra_UnateInfo_t * Extra_UnateComputeFast( + DdManager * dd, /* the manager */ + DdNode * bFunc) /* the function whose symmetries are computed */ +{ + DdNode * bSupp; + DdNode * zRes; + Extra_UnateInfo_t * p; + + bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp ); + zRes = Extra_zddUnateInfoCompute( dd, bFunc, bSupp ); Cudd_Ref( zRes ); + + p = Extra_UnateInfoCreateFromZdd( dd, zRes, bSupp ); + + Cudd_RecursiveDeref( dd, bSupp ); + Cudd_RecursiveDerefZdd( dd, zRes ); + + return p; + +} /* end of Extra_UnateInfoCompute */ + + +/**Function******************************************************************** + + Synopsis [Computes the classical symmetry information as a ZDD.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * Extra_zddUnateInfoCompute( + DdManager * dd, /* the DD manager */ + DdNode * bF, + DdNode * bVars) +{ + DdNode * res; + do { + dd->reordered = 0; + res = extraZddUnateInfoCompute( dd, bF, bVars ); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddUnateInfoCompute */ + + +/**Function******************************************************************** + + Synopsis [Converts a set of variables into a set of singleton subsets.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * Extra_zddGetSingletonsBoth( + DdManager * dd, /* the DD manager */ + DdNode * bVars) /* the set of variables */ +{ + DdNode * res; + do { + dd->reordered = 0; + res = extraZddGetSingletonsBoth( dd, bVars ); + } while (dd->reordered == 1); + return(res); + +} /* end of Extra_zddGetSingletonsBoth */ + +/**Function******************************************************************** + + Synopsis [Allocates unateness information structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +Extra_UnateInfo_t * Extra_UnateInfoAllocate( int nVars ) +{ + Extra_UnateInfo_t * p; + // allocate and clean the storage for unateness info + p = ALLOC( Extra_UnateInfo_t, 1 ); + memset( p, 0, sizeof(Extra_UnateInfo_t) ); + p->nVars = nVars; + p->pVars = ALLOC( Extra_UnateVar_t, nVars ); + memset( p->pVars, 0, nVars * sizeof(Extra_UnateVar_t) ); + return p; +} /* end of Extra_UnateInfoAllocate */ + +/**Function******************************************************************** + + Synopsis [Deallocates symmetry information structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Extra_UnateInfoDissolve( Extra_UnateInfo_t * p ) +{ + free( p->pVars ); + free( p ); +} /* end of Extra_UnateInfoDissolve */ + +/**Function******************************************************************** + + Synopsis [Allocates symmetry information structure.] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Extra_UnateInfoPrint( Extra_UnateInfo_t * p ) +{ + char * pBuffer; + int i; + pBuffer = ALLOC( char, p->nVarsMax+1 ); + memset( pBuffer, ' ', p->nVarsMax ); + pBuffer[p->nVarsMax] = 0; + for ( i = 0; i < p->nVars; i++ ) + if ( p->pVars[i].Neg ) + pBuffer[ p->pVars[i].iVar ] = 'n'; + else if ( p->pVars[i].Pos ) + pBuffer[ p->pVars[i].iVar ] = 'p'; + else + pBuffer[ p->pVars[i].iVar ] = '.'; + printf( "%s\n", pBuffer ); + free( pBuffer ); +} /* end of Extra_UnateInfoPrint */ + + +/**Function******************************************************************** + + Synopsis [Creates the symmetry information structure from ZDD.] + + Description [ZDD representation of symmetries is the set of cubes, each + of which has two variables in the positive polarity. These variables correspond + to the symmetric variable pair.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +Extra_UnateInfo_t * Extra_UnateInfoCreateFromZdd( DdManager * dd, DdNode * zPairs, DdNode * bSupp ) +{ + Extra_UnateInfo_t * p; + DdNode * bTemp, * zSet, * zCube, * zTemp; + int * pMapVars2Nums; + int i, nSuppSize; + + nSuppSize = Extra_bddSuppSize( dd, bSupp ); + + // allocate and clean the storage for symmetry info + p = Extra_UnateInfoAllocate( nSuppSize ); + + // allocate the storage for the temporary map + pMapVars2Nums = ALLOC( int, dd->size ); + memset( pMapVars2Nums, 0, dd->size * sizeof(int) ); + + // assign the variables + p->nVarsMax = dd->size; + for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ ) + { + p->pVars[i].iVar = bTemp->index; + pMapVars2Nums[bTemp->index] = i; + } + + // write the symmetry info into the structure + zSet = zPairs; Cudd_Ref( zSet ); +// Cudd_zddPrintCover( dd, zPairs ); printf( "\n" ); + while ( zSet != z0 ) + { + // get the next cube + zCube = Extra_zddSelectOneSubset( dd, zSet ); Cudd_Ref( zCube ); + + // add this var to the data structure + assert( cuddT(zCube) == z1 && cuddE(zCube) == z0 ); + if ( zCube->index & 1 ) // neg + p->pVars[ pMapVars2Nums[zCube->index/2] ].Neg = 1; + else + p->pVars[ pMapVars2Nums[zCube->index/2] ].Pos = 1; + // count the unate vars + p->nUnate++; + + // update the cuver and deref the cube + zSet = Cudd_zddDiff( dd, zTemp = zSet, zCube ); Cudd_Ref( zSet ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zCube ); + + } // for each cube + Cudd_RecursiveDerefZdd( dd, zSet ); + FREE( pMapVars2Nums ); + return p; + +} /* end of Extra_UnateInfoCreateFromZdd */ + + + +/**Function******************************************************************** + + Synopsis [Computes the classical unateness information for the function.] + + Description [Uses the naive way of comparing cofactors.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +Extra_UnateInfo_t * Extra_UnateComputeSlow( DdManager * dd, DdNode * bFunc ) +{ + int nSuppSize; + DdNode * bSupp, * bTemp; + Extra_UnateInfo_t * p; + int i, Res; + + // compute the support + bSupp = Cudd_Support( dd, bFunc ); Cudd_Ref( bSupp ); + nSuppSize = Extra_bddSuppSize( dd, bSupp ); +//printf( "Support = %d. ", nSuppSize ); +//Extra_bddPrint( dd, bSupp ); +//printf( "%d ", nSuppSize ); + + // allocate the storage for symmetry info + p = Extra_UnateInfoAllocate( nSuppSize ); + + // assign the variables + p->nVarsMax = dd->size; + for ( i = 0, bTemp = bSupp; bTemp != b1; bTemp = cuddT(bTemp), i++ ) + { + Res = Extra_bddCheckUnateNaive( dd, bFunc, bTemp->index ); + p->pVars[i].iVar = bTemp->index; + if ( Res == -1 ) + p->pVars[i].Neg = 1; + else if ( Res == 1 ) + p->pVars[i].Pos = 1; + p->nUnate += (Res != 0); + } + Cudd_RecursiveDeref( dd, bSupp ); + return p; + +} /* end of Extra_UnateComputeSlow */ + +/**Function******************************************************************** + + Synopsis [Checks if the two variables are symmetric.] + + Description [Returns 0 if vars are not unate. Return -1/+1 if the var is neg/pos unate.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Extra_bddCheckUnateNaive( + DdManager * dd, /* the DD manager */ + DdNode * bF, + int iVar) +{ + DdNode * bCof0, * bCof1; + int Res; + + assert( iVar < dd->size ); + + bCof0 = Cudd_Cofactor( dd, bF, Cudd_Not(Cudd_bddIthVar(dd,iVar)) ); Cudd_Ref( bCof0 ); + bCof1 = Cudd_Cofactor( dd, bF, Cudd_bddIthVar(dd,iVar) ); Cudd_Ref( bCof1 ); + + if ( Cudd_bddLeq( dd, bCof0, bCof1 ) ) + Res = 1; + else if ( Cudd_bddLeq( dd, bCof1, bCof0 ) ) + Res =-1; + else + Res = 0; + + Cudd_RecursiveDeref( dd, bCof0 ); + Cudd_RecursiveDeref( dd, bCof1 ); + return Res; +} /* end of Extra_bddCheckUnateNaive */ + + + +/*---------------------------------------------------------------------------*/ +/* Definition of internal functions */ +/*---------------------------------------------------------------------------*/ + +/**Function******************************************************************** + + Synopsis [Performs a recursive step of Extra_UnateInfoCompute.] + + Description [Returns the set of symmetric variable pairs represented as a set + of two-literal ZDD cubes. Both variables always appear in the positive polarity + in the cubes. This function works without building new BDD nodes. Some relatively + small number of ZDD nodes may be built to ensure proper bookkeeping of the + symmetry information.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * +extraZddUnateInfoCompute( + DdManager * dd, /* the manager */ + DdNode * bFunc, /* the function whose symmetries are computed */ + DdNode * bVars ) /* the set of variables on which this function depends */ +{ + DdNode * zRes; + DdNode * bFR = Cudd_Regular(bFunc); + + if ( cuddIsConstant(bFR) ) + { + if ( cuddIsConstant(bVars) ) + return z0; + return extraZddGetSingletonsBoth( dd, bVars ); + } + assert( bVars != b1 ); + + if ( zRes = cuddCacheLookup2Zdd(dd, extraZddUnateInfoCompute, bFunc, bVars) ) + return zRes; + else + { + DdNode * zRes0, * zRes1; + DdNode * zTemp, * zPlus; + DdNode * bF0, * bF1; + DdNode * bVarsNew; + int nVarsExtra; + int LevelF; + int AddVar; + + // every variable in bF should be also in bVars, therefore LevelF cannot be above LevelV + // if LevelF is below LevelV, scroll through the vars in bVars to the same level as F + // count how many extra vars are there in bVars + nVarsExtra = 0; + LevelF = dd->perm[bFR->index]; + for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) ) + nVarsExtra++; + // the indexes (level) of variables should be synchronized now + assert( bFR->index == bVarsNew->index ); + + // cofactor the function + if ( bFR != bFunc ) // bFunc is complemented + { + bF0 = Cudd_Not( cuddE(bFR) ); + bF1 = Cudd_Not( cuddT(bFR) ); + } + else + { + bF0 = cuddE(bFR); + bF1 = cuddT(bFR); + } + + // solve subproblems + zRes0 = extraZddUnateInfoCompute( dd, bF0, cuddT(bVarsNew) ); + if ( zRes0 == NULL ) + return NULL; + cuddRef( zRes0 ); + + // if there is no symmetries in the negative cofactor + // there is no need to test the positive cofactor + if ( zRes0 == z0 ) + zRes = zRes0; // zRes takes reference + else + { + zRes1 = extraZddUnateInfoCompute( dd, bF1, cuddT(bVarsNew) ); + if ( zRes1 == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + return NULL; + } + cuddRef( zRes1 ); + + // only those variables are pair-wise symmetric + // that are pair-wise symmetric in both cofactors + // therefore, intersect the solutions + zRes = cuddZddIntersect( dd, zRes0, zRes1 ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + return NULL; + } + cuddRef( zRes ); + Cudd_RecursiveDerefZdd( dd, zRes0 ); + Cudd_RecursiveDerefZdd( dd, zRes1 ); + } + + // consider the current top-most variable + AddVar = -1; + if ( Cudd_bddLeq( dd, bF0, bF1 ) ) // pos + AddVar = 0; + else if ( Cudd_bddLeq( dd, bF1, bF0 ) ) // neg + AddVar = 1; + if ( AddVar >= 0 ) + { + // create the singleton + zPlus = cuddZddGetNode( dd, 2*bFR->index + AddVar, z1, z0 ); + if ( zPlus == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes ); + return NULL; + } + cuddRef( zPlus ); + + // add these to the result + zRes = cuddZddUnion( dd, zTemp = zRes, zPlus ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zPlus ); + return NULL; + } + cuddRef( zRes ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zPlus ); + } + // only zRes is referenced at this point + + // if we skipped some variables, these variables cannot be symmetric with + // any variables that are currently in the support of bF, but they can be + // symmetric with the variables that are in bVars but not in the support of bF + for ( bVarsNew = bVars; LevelF > dd->perm[bVarsNew->index]; bVarsNew = cuddT(bVarsNew) ) + { + // create the negative singleton + zPlus = cuddZddGetNode( dd, 2*bVarsNew->index+1, z1, z0 ); + if ( zPlus == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes ); + return NULL; + } + cuddRef( zPlus ); + + // add these to the result + zRes = cuddZddUnion( dd, zTemp = zRes, zPlus ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zPlus ); + return NULL; + } + cuddRef( zRes ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zPlus ); + + + // create the positive singleton + zPlus = cuddZddGetNode( dd, 2*bVarsNew->index, z1, z0 ); + if ( zPlus == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes ); + return NULL; + } + cuddRef( zPlus ); + + // add these to the result + zRes = cuddZddUnion( dd, zTemp = zRes, zPlus ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zPlus ); + return NULL; + } + cuddRef( zRes ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zPlus ); + } + cuddDeref( zRes ); + + /* insert the result into cache */ + cuddCacheInsert2(dd, extraZddUnateInfoCompute, bFunc, bVars, zRes); + return zRes; + } +} /* end of extraZddUnateInfoCompute */ + + +/**Function******************************************************************** + + Synopsis [Performs a recursive step of Extra_zddGetSingletons.] + + Description [Returns the set of ZDD singletons, containing those pos/neg + polarity ZDD variables that correspond to the BDD variables in bVars.] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +DdNode * extraZddGetSingletonsBoth( + DdManager * dd, /* the DD manager */ + DdNode * bVars) /* the set of variables */ +{ + DdNode * zRes; + + if ( bVars == b1 ) + return z1; + + if ( zRes = cuddCacheLookup1Zdd(dd, extraZddGetSingletonsBoth, bVars) ) + return zRes; + else + { + DdNode * zTemp, * zPlus; + + // solve subproblem + zRes = extraZddGetSingletonsBoth( dd, cuddT(bVars) ); + if ( zRes == NULL ) + return NULL; + cuddRef( zRes ); + + + // create the negative singleton + zPlus = cuddZddGetNode( dd, 2*bVars->index+1, z1, z0 ); + if ( zPlus == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes ); + return NULL; + } + cuddRef( zPlus ); + + // add these to the result + zRes = cuddZddUnion( dd, zTemp = zRes, zPlus ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zPlus ); + return NULL; + } + cuddRef( zRes ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zPlus ); + + + // create the positive singleton + zPlus = cuddZddGetNode( dd, 2*bVars->index, z1, z0 ); + if ( zPlus == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zRes ); + return NULL; + } + cuddRef( zPlus ); + + // add these to the result + zRes = cuddZddUnion( dd, zTemp = zRes, zPlus ); + if ( zRes == NULL ) + { + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zPlus ); + return NULL; + } + cuddRef( zRes ); + Cudd_RecursiveDerefZdd( dd, zTemp ); + Cudd_RecursiveDerefZdd( dd, zPlus ); + + cuddDeref( zRes ); + cuddCacheInsert1( dd, extraZddGetSingletonsBoth, bVars, zRes ); + return zRes; + } +} /* end of extraZddGetSingletonsBoth */ + + +/*---------------------------------------------------------------------------*/ +/* Definition of static Functions */ +/*---------------------------------------------------------------------------*/ diff --git a/src/misc/extra/extraUtilCanon.c b/src/misc/extra/extraUtilCanon.c index 9d4e5b5d..fcc7d84d 100644 --- a/src/misc/extra/extraUtilCanon.c +++ b/src/misc/extra/extraUtilCanon.c @@ -99,7 +99,8 @@ int Extra_TruthCanonFastN( int nVarsMax, int nVarsReal, unsigned * pt, unsigned Description [] - SideEffects [] + SideEffects [This procedure has a bug, which shows on Solaris. + Most likely has something to do with the casts, i.g *((unsigned *)pt0)] SeeAlso [] @@ -129,21 +130,22 @@ int Extra_TruthCanonN_rec( int nVars, unsigned char * pt, unsigned ** pptRes, ch pt0 = pt; pt1 = pt + (1 << nVarsN) / 8; // 5-var truth tables for this call - uInit0 = *((unsigned *)pt0); - uInit1 = *((unsigned *)pt1); +// uInit0 = *((unsigned *)pt0); +// uInit1 = *((unsigned *)pt1); if ( nVarsN == 3 ) { - uInit0 &= 0xFF; - uInit1 &= 0xFF; - uInit0 = (uInit0 << 24) | (uInit0 << 16) | (uInit0 << 8) | uInit0; - uInit1 = (uInit1 << 24) | (uInit1 << 16) | (uInit1 << 8) | uInit1; + uInit0 = (pt0[0] << 24) | (pt0[0] << 16) | (pt0[0] << 8) | pt0[0]; + uInit1 = (pt1[0] << 24) | (pt1[0] << 16) | (pt1[0] << 8) | pt1[0]; } else if ( nVarsN == 4 ) { - uInit0 &= 0xFFFF; - uInit1 &= 0xFFFF; - uInit0 = (uInit0 << 16) | uInit0; - uInit1 = (uInit1 << 16) | uInit1; + uInit0 = (pt0[1] << 24) | (pt0[0] << 16) | (pt0[1] << 8) | pt0[0]; + uInit1 = (pt1[1] << 24) | (pt1[0] << 16) | (pt1[1] << 8) | pt1[0]; + } + else + { + uInit0 = (pt0[3] << 24) | (pt0[2] << 16) | (pt0[1] << 8) | pt0[0]; + uInit1 = (pt1[3] << 24) | (pt1[2] << 16) | (pt1[1] << 8) | pt1[0]; } // storage for truth tables and phases diff --git a/src/misc/extra/extraUtilReader.c b/src/misc/extra/extraUtilReader.c index 016f01e3..6e16b399 100644 --- a/src/misc/extra/extraUtilReader.c +++ b/src/misc/extra/extraUtilReader.c @@ -262,6 +262,9 @@ void * Extra_FileReaderGetTokens_int( Extra_FileReader_t * p ) // check if the new data should to be loaded if ( p->pBufferCur > p->pBufferStop ) Extra_FileReaderReload( p ); + +// printf( "%d\n", p->pBufferEnd - p->pBufferCur ); + // process the string starting from the current position for ( pChar = p->pBufferCur; pChar < p->pBufferEnd; pChar++ ) { @@ -270,6 +273,10 @@ void * Extra_FileReaderGetTokens_int( Extra_FileReader_t * p ) p->nLineCounter++; // switch depending on the character MapValue = p->pCharMap[*pChar]; + +// printf( "Char value = %d. Map value = %d.\n", *pChar, MapValue ); + + switch ( MapValue ) { case EXTRA_CHAR_COMMENT: @@ -326,6 +333,14 @@ void * Extra_FileReaderGetTokens_int( Extra_FileReader_t * p ) return p->vTokens; } printf( "Extra_FileReader failed to parse the file \"%s\".\n", p->pFileName ); +/* + { + int i; + for ( i = 0; i < p->vTokens->nSize; i++ ) + printf( "%s ", p->vTokens->pArray[i] ); + printf( "\n" ); + } +*/ return NULL; } diff --git a/src/misc/extra/module.make b/src/misc/extra/module.make index 42a0d84f..8e7b1772 100644 --- a/src/misc/extra/module.make +++ b/src/misc/extra/module.make @@ -1,4 +1,5 @@ -SRC += src/misc/extra/extraBddKmap.c \ +SRC += src/misc/extra/extraBddAuto.c \ + src/misc/extra/extraBddKmap.c \ src/misc/extra/extraBddMisc.c \ src/misc/extra/extraBddSymm.c \ src/misc/extra/extraUtilBitMatrix.c \ diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h index 2d36addd..7a96b0d7 100644 --- a/src/misc/vec/vecInt.h +++ b/src/misc/vec/vecInt.h @@ -345,6 +345,7 @@ static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin ) if ( p->nCap >= nCapMin ) return; p->pArray = REALLOC( int, p->pArray, nCapMin ); + assert( p->pArray ); p->nCap = nCapMin; } diff --git a/src/opt/dec/decAbc.c b/src/opt/dec/decAbc.c index b24773be..af76cd84 100644 --- a/src/opt/dec/decAbc.c +++ b/src/opt/dec/decAbc.c @@ -18,7 +18,7 @@ #include "abc.h" #include "dec.h" -#include "aig.h" +//#include "aig.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// @@ -214,6 +214,7 @@ void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, bool fUpda SeeAlso [] ***********************************************************************/ +/* Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph ) { Dec_Node_t * pNode; @@ -235,6 +236,7 @@ Aig_Node_t * Dec_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph ) // complement the result if necessary return Aig_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); } +*/ //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/sat/aig/aig.h b/src/sat/aig/aig.h index 55a75cf5..ee029789 100644 --- a/src/sat/aig/aig.h +++ b/src/sat/aig/aig.h @@ -160,6 +160,7 @@ struct Aig_Man_t_ Aig_SimInfo_t * pInfo; // random and systematic sim info for PIs Aig_SimInfo_t * pInfoPi; // temporary sim info for the PI nodes Aig_SimInfo_t * pInfoTemp; // temporary sim info for all nodes + Aig_Pattern_t * pPatMask; // the mask which shows what patterns are used // simulation patterns int nPiWords; // the number of words in the PI info int nPatsMax; // the max number of patterns @@ -169,6 +170,7 @@ struct Aig_Man_t_ // temporary data Vec_Ptr_t * vFanouts; // temporary storage for fanouts of a node Vec_Ptr_t * vToReplace; // the nodes to replace + Vec_Int_t * vClassTemp; // temporary class representatives }; // the simulation patter @@ -254,6 +256,7 @@ static inline int Aig_NodeWhatFanin( Aig_Node_t * pNode, Aig_Node_t * p static inline int Aig_NodeGetLevelNew( Aig_Node_t * pNode ) { return 1 + AIG_MAX(Aig_NodeFanin0(pNode)->Level, Aig_NodeFanin1(pNode)->Level); } static inline int Aig_NodeRequiredLevel( Aig_Node_t * pNode ) { return pNode->pMan->nLevelMax + 1 - pNode->LevelR; } +static inline unsigned * Aig_SimInfoForNodeId( Aig_SimInfo_t * p, int NodeId ) { assert( p->Type ); return p->pData + p->nWords * NodeId; } static inline unsigned * Aig_SimInfoForNode( Aig_SimInfo_t * p, Aig_Node_t * pNode ) { assert( p->Type ); return p->pData + p->nWords * pNode->Id; } static inline unsigned * Aig_SimInfoForPi( Aig_SimInfo_t * p, int Num ) { assert( !p->Type ); return p->pData + p->nWords * Num; } @@ -332,15 +335,16 @@ extern Aig_Node_t * Aig_NodeRecognizeMux( Aig_Node_t * pNode, Aig_Node_t extern Aig_ProofType_t Aig_FraigProve( Aig_Man_t * pMan ); /*=== fraigClasses.c ==========================================================*/ extern Vec_Vec_t * Aig_ManDeriveClassesFirst( Aig_Man_t * p, Aig_SimInfo_t * pInfoAll ); -extern void Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses ); +extern int Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses, Aig_Pattern_t * pPatMask ); +extern void Aig_ManCollectPatterns( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Aig_Pattern_t * pMask, Vec_Ptr_t * vPats ); /*=== fraigCnf.c ==========================================================*/ extern Aig_ProofType_t Aig_ClauseSolverStart( Aig_Man_t * pMan ); /*=== fraigEngine.c ==========================================================*/ +extern void Aig_EngineSimulateRandomFirst( Aig_Man_t * p ); extern void Aig_EngineSimulateFirst( Aig_Man_t * p ); extern int Aig_EngineSimulate( Aig_Man_t * p ); -extern void Aig_EngineSimulateRandomFirst( Aig_Man_t * p ); /*=== fraigSim.c ==========================================================*/ -extern Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nWords, int Type ); +extern Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nBits, int Type ); extern void Aig_SimInfoClean( Aig_SimInfo_t * p ); extern void Aig_SimInfoRandom( Aig_SimInfo_t * p ); extern void Aig_SimInfoFromPattern( Aig_SimInfo_t * p, Aig_Pattern_t * pPat ); @@ -349,6 +353,8 @@ extern void Aig_SimInfoFree( Aig_SimInfo_t * p ); extern void Aig_ManSimulateInfo( Aig_Man_t * p, Aig_SimInfo_t * pInfoPi, Aig_SimInfo_t * pInfoAll ); extern Aig_Pattern_t * Aig_PatternAlloc( int nBits ); extern void Aig_PatternClean( Aig_Pattern_t * pPat ); +extern void Aig_PatternFill( Aig_Pattern_t * pPat ); +extern int Aig_PatternCount( Aig_Pattern_t * pPat ); extern void Aig_PatternRandom( Aig_Pattern_t * pPat ); extern void Aig_PatternFree( Aig_Pattern_t * pPat ); diff --git a/src/sat/aig/aigMan.c b/src/sat/aig/aigMan.c index 3807d28a..4c64c897 100644 --- a/src/sat/aig/aigMan.c +++ b/src/sat/aig/aigMan.c @@ -42,7 +42,7 @@ void Aig_ManSetDefaultParams( Aig_Param_t * pParam ) { memset( pParam, 0, sizeof(Aig_Param_t) ); - pParam->nPatsRand = 1024; // the number of random patterns + pParam->nPatsRand = 4096; // the number of random patterns pParam->nBTLimit = 99; // backtrack limit at the intermediate nodes pParam->nSeconds = 1; // the timeout for the final miter in seconds } @@ -67,8 +67,8 @@ Aig_Man_t * Aig_ManStart( Aig_Param_t * pParam ) p = ALLOC( Aig_Man_t, 1 ); memset( p, 0, sizeof(Aig_Man_t) ); p->pParam = &p->Param; - p->nTravIds = 1; - p->nPatsMax = 20; + p->nTravIds = 1; + p->nPatsMax = 25; // set the defaults *p->pParam = *pParam; // start memory managers @@ -84,6 +84,8 @@ Aig_Man_t * Aig_ManStart( Aig_Param_t * pParam ) // initialize other variables p->vFanouts = Vec_PtrAlloc( 10 ); p->vToReplace = Vec_PtrAlloc( 10 ); + p->vClassTemp = Vec_IntAlloc( 10 ); + p->vPats = Vec_PtrAlloc( p->nPatsMax ); return p; } @@ -132,6 +134,9 @@ void Aig_ManStop( Aig_Man_t * p ) if ( p->vFanFans0 ) Vec_PtrFree( p->vFanFans0 ); if ( p->vFanFans1 ) Vec_PtrFree( p->vFanFans1 ); if ( p->vClasses ) Vec_VecFree( p->vClasses ); + // patterns + if ( p->vPats ) Vec_PtrFree( p->vPats ); + if ( p->pPatMask ) Aig_PatternFree( p->pPatMask ); // nodes Aig_MemFixedStop( p->mmNodes, 0 ); Vec_PtrFree( p->vNodes ); @@ -140,6 +145,7 @@ void Aig_ManStop( Aig_Man_t * p ) // temporary Vec_PtrFree( p->vFanouts ); Vec_PtrFree( p->vToReplace ); + Vec_IntFree( p->vClassTemp ); Aig_TableFree( p->pTable ); free( p ); } diff --git a/src/sat/aig/fraigClass.c b/src/sat/aig/fraigClass.c index 2f2d3e0c..a8df9a72 100644 --- a/src/sat/aig/fraigClass.c +++ b/src/sat/aig/fraigClass.c @@ -80,7 +80,7 @@ Vec_Vec_t * Aig_ManDeriveClassesFirst( Aig_Man_t * p, Aig_SimInfo_t * pInfo ) } } stmm_free_table( tSim2Node ); - +/* // print the classes { Vec_Ptr_t * vVec; @@ -93,6 +93,8 @@ Vec_Vec_t * Aig_ManDeriveClassesFirst( Aig_Man_t * p, Aig_SimInfo_t * pInfo ) printf( "%d ", Vec_PtrSize(vVec) ); printf( "\n" ); } +*/ + printf( "Classes = %6d. Pairs = %6d.\n", Vec_VecSize(vClasses), Vec_VecSizeSize(vClasses) - Vec_VecSize(vClasses) ); return vClasses; } @@ -115,14 +117,86 @@ unsigned Aig_ManHashKey( unsigned * pData, int nWords, bool fPhase ) uKey = 0; if ( fPhase ) for ( i = 0; i < nWords; i++ ) - uKey ^= Primes[i%10] * pData[i]; + uKey ^= i * Primes[i%10] * pData[i]; else for ( i = 0; i < nWords; i++ ) - uKey ^= Primes[i%10] * ~pData[i]; + uKey ^= i * Primes[i%10] * ~pData[i]; return uKey; } + +/**Function************************************************************* + + Synopsis [Splits the equivalence class.] + + Description [Given an equivalence class (vClass) and the simulation info, + split the class into two based on the info.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManSplitClass( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Int_t * vClass, Vec_Int_t * vClass2, Aig_Pattern_t * pPat ) +{ + int NodeId, i, k, w; + Aig_Node_t * pRoot, * pTemp; + unsigned * pRootData, * pTempData; + assert( Vec_IntSize(vClass) > 1 ); + assert( pInfo->nPatsCur == pPat->nBits ); +// printf( "Class = %5d. --> ", Vec_IntSize(vClass) ); + // clear storage for the new classes + Vec_IntClear( vClass2 ); + // get the root member of the class + pRoot = Aig_ManNode( p, Vec_IntEntry(vClass, 0) ); + pRootData = Aig_SimInfoForNode( pInfo, pRoot ); + // sort the class members: + // (1) with the same siminfo as pRoot remain in vClass + // (2) nodes with other siminfo go to vClass2 + k = 1; + Vec_IntForEachEntryStart( vClass, NodeId, i, 1 ) + { + NodeId = Vec_IntEntry(vClass, i); + pTemp = Aig_ManNode( p, NodeId ); + pTempData = Aig_SimInfoForNode( pInfo, pTemp ); + if ( pRoot->fPhase == pTemp->fPhase ) + { + for ( w = 0; w < pInfo->nWords; w++ ) + if ( pRootData[w] != pTempData[w] ) + break; + if ( w == pInfo->nWords ) // the same info + Vec_IntWriteEntry( vClass, k++, NodeId ); + else + { + Vec_IntPush( vClass2, NodeId ); + // record the diffs if they are not distinguished by the first pattern + if ( ((pRootData[0] ^ pTempData[0]) & 1) == 0 ) + for ( w = 0; w < pInfo->nWords; w++ ) + pPat->pData[w] |= (pRootData[w] ^ pTempData[w]); + } + } + else + { + for ( w = 0; w < pInfo->nWords; w++ ) + if ( pRootData[w] != ~pTempData[w] ) + break; + if ( w == pInfo->nWords ) // the same info + Vec_IntWriteEntry( vClass, k++, NodeId ); + else + { + Vec_IntPush( vClass2, NodeId ); + // record the diffs if they are not distinguished by the first pattern + if ( ((pRootData[0] ^ ~pTempData[0]) & 1) == 0 ) + for ( w = 0; w < pInfo->nWords; w++ ) + pPat->pData[w] |= (pRootData[w] ^ ~pTempData[w]); + } + } + } + Vec_IntShrink( vClass, k ); +// printf( "Class1 = %5d. Class2 = %5d.\n", Vec_IntSize(vClass), Vec_IntSize(vClass2) ); +} + /**Function************************************************************* Synopsis [Updates the equivalence classes using the simulation info.] @@ -135,8 +209,108 @@ unsigned Aig_ManHashKey( unsigned * pData, int nWords, bool fPhase ) SeeAlso [] ***********************************************************************/ -void Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses ) +int Aig_ManUpdateClasses( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Vec_Vec_t * vClasses, Aig_Pattern_t * pPatMask ) +{ + Vec_Ptr_t * vClass; + int i, k, fSplit = 0; + assert( Vec_VecSize(vClasses) > 0 ); + // collect patterns that lead to changes + Aig_PatternClean( pPatMask ); + // split the classes using the new symmetry info + Vec_VecForEachLevel( vClasses, vClass, i ) + { + if ( i == 0 ) + continue; + // split vClass into two parts (vClass and vClassTemp) + Aig_ManSplitClass( p, pInfo, (Vec_Int_t *)vClass, p->vClassTemp, pPatMask ); + // check if there is any splitting + if ( Vec_IntSize(p->vClassTemp) > 0 ) + fSplit = 1; + // skip the new class if it is empty or trivial + if ( Vec_IntSize(p->vClassTemp) < 2 ) + continue; + // consider replacing the current class with the new one + if ( Vec_PtrSize(vClass) == 1 ) + { + assert( vClasses->pArray[i] == vClass ); + vClasses->pArray[i] = p->vClassTemp; + p->vClassTemp = (Vec_Int_t *)vClass; + i--; + continue; + } + // add the new non-trival class in the end + Vec_PtrPush( (Vec_Ptr_t *)vClasses, p->vClassTemp ); + p->vClassTemp = Vec_IntAlloc( 10 ); + } + // free trivial classes + k = 0; + Vec_VecForEachLevel( vClasses, vClass, i ) + { + assert( Vec_PtrSize(vClass) > 0 ); + if ( Vec_PtrSize(vClass) == 1 ) + Vec_PtrFree(vClass); + else + vClasses->pArray[k++] = vClass; + } + Vec_PtrShrink( (Vec_Ptr_t *)vClasses, k ); + // catch the patterns which led to splitting + printf( "Classes = %6d. Pairs = %6d. Patterns = %3d.\n", + Vec_VecSize(vClasses), + Vec_VecSizeSize(vClasses) - Vec_VecSize(vClasses), + Vec_PtrSize(p->vPats) ); + return fSplit; +} + +/**Function************************************************************* + + Synopsis [Collects useful patterns.] + + Description [If the flag fAddToVector is 1, creates and adds new patterns + to the internal storage of patterns.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManCollectPatterns( Aig_Man_t * p, Aig_SimInfo_t * pInfo, Aig_Pattern_t * pMask, Vec_Ptr_t * vPats ) { + Aig_SimInfo_t * pInfoRes = p->pInfo; + Aig_Pattern_t * pPatNew; + Aig_Node_t * pNode; + int i, k; + + assert( Aig_InfoHasBit(pMask->pData, 0) == 0 ); + for ( i = 0; i < pMask->nBits; i++ ) + { + if ( vPats && Vec_PtrSize(vPats) >= p->nPatsMax ) + break; + if ( i == 0 || Aig_InfoHasBit(pMask->pData, i) ) + { + // expand storage if needed + if ( pInfoRes->nPatsCur == pInfoRes->nPatsMax ) + Aig_SimInfoResize( pInfoRes ); + // create a new pattern + if ( vPats ) + { + pPatNew = Aig_PatternAlloc( Aig_ManPiNum(p) ); + Aig_PatternClean( pPatNew ); + } + // go through the PIs + Aig_ManForEachPi( p, pNode, k ) + { + if ( Aig_InfoHasBit( Aig_SimInfoForNode(pInfo, pNode), i ) ) + { + Aig_InfoSetBit( Aig_SimInfoForPi(pInfoRes, k), pInfoRes->nPatsCur ); + if ( vPats ) Aig_InfoSetBit( pPatNew->pData, k ); + } + } + // store the new pattern + if ( vPats ) Vec_PtrPush( vPats, pPatNew ); + // increment the number of patterns stored + pInfoRes->nPatsCur++; + } + } } //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/aig/fraigCore.c b/src/sat/aig/fraigCore.c index e7df1335..decf05ee 100644 --- a/src/sat/aig/fraigCore.c +++ b/src/sat/aig/fraigCore.c @@ -68,6 +68,8 @@ Aig_ProofType_t Aig_FraigProve( Aig_Man_t * pMan ) // create equivalence classes Aig_EngineSimulateRandomFirst( pMan ); + // reduce equivalence classes using simulation + Aig_EngineSimulateFirst( pMan ); return RetValue; } diff --git a/src/sat/aig/fraigEngine.c b/src/sat/aig/fraigEngine.c index 6214bf3b..17468e8f 100644 --- a/src/sat/aig/fraigEngine.c +++ b/src/sat/aig/fraigEngine.c @@ -30,6 +30,39 @@ /**Function************************************************************* + Synopsis [Simulates all nodes using random simulation for the first time.] + + Description [Assigns the original simulation info and the storage for the + future simulation info.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_EngineSimulateRandomFirst( Aig_Man_t * p ) +{ + Aig_SimInfo_t * pInfoPi, * pInfoAll; + assert( !p->pInfo && !p->pInfoTemp ); + // create random PI info + pInfoPi = Aig_SimInfoAlloc( Aig_ManPiNum(p), p->pParam->nPatsRand, 0 ); + Aig_SimInfoRandom( pInfoPi ); + // allocate sim info for all nodes + pInfoAll = Aig_SimInfoAlloc( Aig_ManNodeNum(p), p->pParam->nPatsRand, 1 ); + // simulate though the circuit + Aig_ManSimulateInfo( p, pInfoPi, pInfoAll ); + // detect classes + p->vClasses = Aig_ManDeriveClassesFirst( p, pInfoAll ); + Aig_SimInfoFree( pInfoAll ); + // save simulation info + p->pInfo = pInfoPi; + p->pInfoPi = Aig_SimInfoAlloc( Aig_ManPiNum(p), Aig_ManPiNum(p)+1, 0 ); + p->pInfoTemp = Aig_SimInfoAlloc( Aig_ManNodeNum(p), Aig_ManPiNum(p)+1, 1 ); + p->pPatMask = Aig_PatternAlloc( Aig_ManPiNum(p)+1 ); +} + +/**Function************************************************************* + Synopsis [Starts the simulation engine for the first time.] Description [Tries several random patterns and their distance-1 @@ -43,15 +76,55 @@ void Aig_EngineSimulateFirst( Aig_Man_t * p ) { Aig_Pattern_t * pPat; - int i; - assert( Vec_PtrSize(p->vPats) == 0 ); - for ( i = 0; i < p->nPatsMax; i++ ) + int i, Counter; + + // simulate the pattern of all zeros + pPat = Aig_PatternAlloc( Aig_ManPiNum(p) ); + Aig_PatternClean( pPat ); + Vec_PtrPush( p->vPats, pPat ); + if ( !Aig_EngineSimulate( p ) ) + return; + + // simulate the pattern of all ones + pPat = Aig_PatternAlloc( Aig_ManPiNum(p) ); + Aig_PatternFill( pPat ); + Vec_PtrPush( p->vPats, pPat ); + if ( !Aig_EngineSimulate( p ) ) + return; + + // simulate random until the number of new patterns is reasonable + do { + // generate random PI siminfo + Aig_SimInfoRandom( p->pInfoPi ); + // simulate this info + Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp ); + // split the classes and collect the new patterns + if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) ) + Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, NULL ); + if ( Vec_VecSize(p->vClasses) == 0 ) + return; + // count the number of useful patterns + Counter = Aig_PatternCount(p->pPatMask); + } + while ( Counter > p->nPatsMax/2 ); + + // perform targetted simulation + for ( i = 0; i < 3; i++ ) { - pPat = Aig_PatternAlloc( Aig_ManPiNum(p) ); - Aig_PatternRandom( pPat ); - Vec_PtrPush( p->vPats, pPat ); - if ( !Aig_EngineSimulate( p ) ) + assert( Vec_PtrSize(p->vPats) == 0 ); + // generate random PI siminfo + Aig_SimInfoRandom( p->pInfoPi ); + // simulate this info + Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp ); + // split the classes and collect the new patterns + if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) ) + Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, p->vPats ); + if ( Vec_VecSize(p->vClasses) == 0 ) return; + // simulate the remaining patters + if ( Vec_PtrSize(p->vPats) > 0 ) + if ( !Aig_EngineSimulate( p ) ) + return; } } @@ -79,51 +152,21 @@ int Aig_EngineSimulate( Aig_Man_t * p ) { // get the pattern and create new siminfo pPat = Vec_PtrPop(p->vPats); + assert( pPat->nBits == Aig_ManPiNum(p) ); // create the new siminfo Aig_SimInfoFromPattern( p->pInfoPi, pPat ); - // free the patter + // free the pattern Aig_PatternFree( pPat ); // simulate this info Aig_ManSimulateInfo( p, p->pInfoPi, p->pInfoTemp ); // split the classes and collect the new patterns - Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses ); + if ( Aig_ManUpdateClasses( p, p->pInfoTemp, p->vClasses, p->pPatMask ) ) + Aig_ManCollectPatterns( p, p->pInfoTemp, p->pPatMask, p->vPats ); } return Vec_VecSize(p->vClasses) > 0; } -/**Function************************************************************* - - Synopsis [Simulates all nodes using random simulation for the first time.] - - Description [Assigns the original simulation info and the storage for the - future simulation info.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Aig_EngineSimulateRandomFirst( Aig_Man_t * p ) -{ - Aig_SimInfo_t * pInfoPi, * pInfoAll; - assert( !p->pInfo && !p->pInfoTemp ); - // create random PI info - pInfoPi = Aig_SimInfoAlloc( p->vPis->nSize, Aig_BitWordNum(p->pParam->nPatsRand), 0 ); - Aig_SimInfoRandom( pInfoPi ); - // allocate sim info for all nodes - pInfoAll = Aig_SimInfoAlloc( p->vNodes->nSize, pInfoPi->nWords, 1 ); - // simulate though the circuit - Aig_ManSimulateInfo( p, pInfoPi, pInfoAll ); - // detect classes - p->vClasses = Aig_ManDeriveClassesFirst( p, pInfoAll ); - Aig_SimInfoFree( pInfoAll ); - // save simulation info - p->pInfo = pInfoPi; - p->pInfoPi = Aig_SimInfoAlloc( p->vPis->nSize, Aig_BitWordNum(p->vPis->nSize), 0 ); - p->pInfoTemp = Aig_SimInfoAlloc( p->vNodes->nSize, Aig_BitWordNum(p->vPis->nSize), 1 ); -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/aig/fraigSim.c b/src/sat/aig/fraigSim.c index 415b6918..6d4f214c 100644 --- a/src/sat/aig/fraigSim.c +++ b/src/sat/aig/fraigSim.c @@ -80,7 +80,7 @@ void Aig_ManSimulateInfo( Aig_Man_t * p, Aig_SimInfo_t * pInfoPi, Aig_SimInfo_t pDataAnd[k] = pData0[k] & pData1[k]; } // derive the PO siminfo - Aig_ManForEachPi( p, pNode, i ) + Aig_ManForEachPo( p, pNode, i ) { pDataPo = Aig_SimInfoForNode( pInfoAll, pNode ); pDataAnd = Aig_SimInfoForNode( pInfoAll, Aig_NodeFanin0(pNode) ); @@ -106,16 +106,17 @@ void Aig_ManSimulateInfo( Aig_Man_t * p, Aig_SimInfo_t * pInfoPi, Aig_SimInfo_t SeeAlso [] ***********************************************************************/ -Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nWords, int Type ) +Aig_SimInfo_t * Aig_SimInfoAlloc( int nNodes, int nBits, int Type ) { Aig_SimInfo_t * p; p = ALLOC( Aig_SimInfo_t, 1 ); memset( p, 0, sizeof(Aig_SimInfo_t) ); p->Type = Type; p->nNodes = nNodes; - p->nWords = nWords; - p->nPatsMax = nWords * sizeof(unsigned) * 8; - p->pData = ALLOC( unsigned, nNodes * nWords ); + p->nWords = Aig_BitWordNum(nBits); + p->nPatsCur = nBits; + p->nPatsMax = p->nWords * sizeof(unsigned) * 8; + p->pData = ALLOC( unsigned, nNodes * p->nWords ); return p; } @@ -161,7 +162,6 @@ void Aig_SimInfoRandom( Aig_SimInfo_t * p ) pData = p->pData + p->nWords * i; *pData <<= 1; } - p->nPatsCur = p->nPatsMax; } /**Function************************************************************* @@ -180,8 +180,8 @@ void Aig_SimInfoFromPattern( Aig_SimInfo_t * p, Aig_Pattern_t * pPat ) unsigned * pData; int i, k; assert( p->Type == 0 ); - assert( p->nNodes == pPat->nBits ); - for ( i = 0; i < p->nNodes; i++ ) + assert( p->nPatsCur == pPat->nBits+1 ); + for ( i = 0; i < p->nPatsCur; i++ ) { // get the pointer to the bitdata for node i pData = p->pData + p->nWords * i; @@ -192,8 +192,8 @@ void Aig_SimInfoFromPattern( Aig_SimInfo_t * p, Aig_Pattern_t * pPat ) else for ( k = 0; k < p->nWords; k++ ) pData[k] = 0; - // flip one bit - Aig_InfoXorBit( pData, i ); + // flip one bit, starting from the first pattern + if ( i ) Aig_InfoXorBit( pData, i-1 ); } } @@ -285,6 +285,22 @@ void Aig_PatternClean( Aig_Pattern_t * pPat ) /**Function************************************************************* + Synopsis [Cleans the pattern.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_PatternFill( Aig_Pattern_t * pPat ) +{ + memset( pPat->pData, 0xff, sizeof(unsigned) * pPat->nWords ); +} + +/**Function************************************************************* + Synopsis [Sets the random pattern.] Description [] @@ -303,6 +319,25 @@ void Aig_PatternRandom( Aig_Pattern_t * pPat ) /**Function************************************************************* + Synopsis [Counts the number of 1s in the pattern.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Aig_PatternCount( Aig_Pattern_t * pPat ) +{ + int i, Counter = 0; + for ( i = 0; i < pPat->nBits; i++ ) + Counter += Aig_InfoHasBit( pPat->pData, i ); + return Counter; +} + +/**Function************************************************************* + Synopsis [Deallocates the pattern.] Description [] diff --git a/src/sat/aig/rwrTruth.c b/src/sat/aig/rwrTruth.c new file mode 100644 index 00000000..2c402184 --- /dev/null +++ b/src/sat/aig/rwrTruth.c @@ -0,0 +1,454 @@ +/**CFile**************************************************************** + + FileName [rwrTruth.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [And-Inverter Graph package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: rwrTruth.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" + +/* The code in this file was written with portability to 64-bits in mind. + The type "unsigned" is assumed to be 32-bit on any platform. +*/ + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define ABCTMAX 8 // the max number of vars + +typedef struct Aig_Truth_t_ Aig_Truth_t; +struct Aig_Truth_t_ +{ + short nVars; // the number of variables + short nWords; // the number of 32-bit words + unsigned Truth[1<<(ABCTMAX-5)]; // the truth table + unsigned Cofs[2][1<<(ABCTMAX-6)]; // the truth table of cofactors + unsigned Data[4][1<<(ABCTMAX-7)]; // the truth table of cofactors + short Counts[ABCTMAX][2]; // the minterm counters + Aig_Node_t * pLeaves[ABCTMAX]; // the pointers to leaves + Aig_Man_t * pMan; // the AIG manager +}; + +static void Aig_TruthCount( Aig_Truth_t * p ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates the function given the truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Truth_t * Aig_TruthCreate( int nVars, unsigned * pTruth, Aig_Node_t ** pLeaves ) +{ + Aig_Truth_t * p; + int i; + p = ALLOC( Aig_Truth_t, 1 ); + memset( p, 0, sizeof(Aig_Truth_t) ); + p->nVars = nVars; + p->nWords = (nVars < 5)? 1 : (1 << (nVars-5)); + for ( i = 0; i < p->nWords; i++ ) + p->Truth[i] = pTruth[i]; + if ( nVars < 5 ) + p->Truth[0] &= (~0u >> (32-(1<<nVars))); + for ( i = 0; i < p->nVars; i++ ) + p->pLeaves[i] = pLeaves[i]; + Aig_TruthCount( p ); + return p; +} + +/**Function************************************************************* + + Synopsis [Counts the number of miterms in the cofactors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Aig_WordCountOnes( unsigned val ) +{ + val = (val & 0x55555555) + ((val>>1) & 0x55555555); + val = (val & 0x33333333) + ((val>>2) & 0x33333333); + val = (val & 0x0F0F0F0F) + ((val>>4) & 0x0F0F0F0F); + val = (val & 0x00FF00FF) + ((val>>8) & 0x00FF00FF); + return (val & 0x0000FFFF) + (val>>8); +} + +/**Function************************************************************* + + Synopsis [Counts the number of miterms in the cofactors.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_TruthCount( Aig_Truth_t * p ) +{ + static unsigned Masks[5][2] = { + { 0x33333333, 0xAAAAAAAA }, + { 0x55555555, 0xCCCCCCCC }, + { 0x0F0F0F0F, 0xF0F0F0F0 }, + { 0x00FF00FF, 0xFF00FF00 }, + { 0x0000FFFF, 0xFFFF0000 } + }; + + int i, k; + assert( p->Counts[0][0] == 0 && p->Counts[0][1] == 0 ); + for ( i = 0; i < p->nVars; i++ ) + { + p->Counts[i][0] = p->Counts[i][1] = 0; + if ( i < 5 ) + { + for ( k = 0; k < p->nWords; k++ ) + { + p->Counts[i][0] += Aig_WordCountOnes( p->Truth[k] & Masks[i][0] ); + p->Counts[i][1] += Aig_WordCountOnes( p->Truth[k] & Masks[i][1] ); + } + } + else + { + for ( k = 0; k < p->nWords; k++ ) + if ( i & (1 << (k-5)) ) + p->Counts[i][1] += Aig_WordCountOnes( p->Truth[k] ); + else + p->Counts[i][0] += Aig_WordCountOnes( p->Truth[k] ); + } + } +/* + // normalize the variables + for ( i = 0; i < p->nVars; i++ ) + if ( p->Counts[i][0] > p->Counts[i][1] ) + { + k = p->Counts[i][0]; + p->Counts[i][0] = p->Counts[i][1]; + p->Counts[i][1] = k; + p->pLeaves[i] = Aig_Not( p->pLeaves[i] ); + } +*/ +} + +/**Function************************************************************* + + Synopsis [Extracts one part of the bitstring.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned Aig_WordGetPart( unsigned * p, int Start, int Size ) +{ + return (p[Start/5] >> (Start%32)) & (~0u >> (32-Size)); +} + +/**Function************************************************************* + + Synopsis [Inserts one part of the bitstring.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Aig_WordSetPart( unsigned * p, int Start, unsigned Part ) +{ + p[Start/5] |= (Part << (Start%32)); +} + +/**Function************************************************************* + + Synopsis [Computes the cofactor with respect to one variable.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_TruthCofactor( int Var, int Pol, int nVars, unsigned * pTruth, unsigned * pResult ) +{ + if ( Var < 5 ) + { + int nPartSize = ( 1 << Var ); + int nParts = ( 1 << (nVars-Var-1) ); + unsigned uPart; + int i; + for ( i = 0; i < nParts; i++ ) + { + uPart = Aig_WordGetPart( pTruth, (2*i+Pol)*nPartSize, nPartSize ); + Aig_WordSetPart( pResult, i*nPartSize, uPart ); + } + if ( nVars <= 5 ) + pResult[0] &= (~0u >> (32-(1<<(nVars-1)))); + } + else + { + int nWords = (1 << (nVars-5)); + int i, k = 0; + for ( i = 0; i < nWords; i++ ) + if ( (i & (1 << (Var-5))) == Pol ) + pResult[k++] = pTruth[i]; + assert( k == nWords/2 ); + } +} + + + + +/**Function************************************************************* + + Synopsis [Computes the BDD of the truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Aig_TruthToBdd_rec( DdManager * dd, unsigned * pTruth, int Shift, int nVars, int iVar ) +{ + DdNode * bCof0, * bCof1, * bRes; + if ( nVars == 1 ) + return Cudd_NotCond( Cudd_ReadOne(dd), !Aig_WordGetPart(pTruth, Shift, 1) ); + if ( nVars == 3 ) + { + unsigned char * pChar = ((char *)pTruth) + Shift/8; + assert( Shift % 8 == 0 ); + if ( *pChar == 0 ) + return Cudd_ReadLogicZero(dd); + if ( *pChar == 0xFF ) + return Cudd_ReadOne(dd); + } + if ( nVars == 5 ) + { + unsigned * pWord = pTruth + Shift/32; + assert( Shift % 32 == 0 ); + if ( *pWord == 0 ) + return Cudd_ReadLogicZero(dd); + if ( *pWord == 0xFFFFFFFF ) + return Cudd_ReadOne(dd); + } + bCof0 = Aig_TruthToBdd_rec( dd, pTruth, Shift, nVars-1, iVar+1 ); Cudd_Ref( bCof0 ); + bCof1 = Aig_TruthToBdd_rec( dd, pTruth, Shift + (1 << (nVars-1)), nVars-1, iVar+1 ); Cudd_Ref( bCof1 ); + bRes = Cudd_bddIte( dd, Cudd_bddIthVar(dd, iVar), bCof1, bCof0 ); Cudd_Ref( bRes ); + Cudd_RecursiveDeref( dd, bCof0 ); + Cudd_RecursiveDeref( dd, bCof1 ); + Cudd_Deref( bRes ); + return bRes; +} + +/**Function************************************************************* + + Synopsis [Computes the BDD of the truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +DdNode * Aig_TruthToBdd( DdManager * dd, Aig_Truth_t * p ) +{ + return Aig_TruthToBdd_rec( dd, p->Truth, 0, p->nVars, 0 ); +} + + + + +/**Function************************************************************* + + Synopsis [Compare bistrings.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Aig_WordCompare( unsigned * p0, unsigned * p1, int nWords ) +{ + int i; + for ( i = 0; i < nWords; i++ ) + if ( p0[i] != p1[i] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Compare bistrings.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Aig_WordCompareCompl( unsigned * p0, unsigned * p1, int nWords ) +{ + int i; + for ( i = 0; i < nWords; i++ ) + if ( p0[i] != ~p1[i] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes the cofactor with respect to one variable.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_TruthReplaceByCofactor( Aig_Truth_t * p, int iVar, unsigned * pTruth ) +{ +} + + +/**Function************************************************************* + + Synopsis [Computes the cofactor with respect to one variable.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Node_t * Aig_TruthDecompose( Aig_Truth_t * p ) +{ + Aig_Node_t * pVar; + int nOnesCof = ( 1 << (p->nVars-1) ); + int nWordsCof = (p->nWords == 1 ? 1 : p->nWords/2); + int i; + + // check for constant function + if ( p->nVars == 0 ) + return Aig_NotCond( Aig_ManConst1(p->pMan), (p->Truth[0]&1)==0 ); + + // count the number of minterms in the cofactors + Aig_TruthCount( p ); + + // remove redundant variables and EXORs + for ( i = p->nVars - 1; i >= 0; i-- ) + { + if ( p->Counts[i][0] == p->Counts[i][1] ) + { + // compute cofactors + Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); + Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); + if ( Aig_WordCompare( p->Cofs[0], p->Cofs[1], nWordsCof ) ) + { // equal + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); + return Aig_TruthDecompose( p ); + } + } + // check the case of EXOR + if ( p->Counts[i][0] == nOnesCof - p->Counts[i][1] ) + { + // compute cofactors + Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); + Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); + if ( Aig_WordCompareCompl( p->Cofs[0], p->Cofs[1], nWordsCof ) ) + { // equal + pVar = p->pLeaves[i]; + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); + // F = x' * F0 + x * F1 = x <+> F0 assuming that F0 == ~F1 + return Aig_Xor( p->pMan, pVar, Aig_TruthDecompose( p ) ); + } + } + } + + // process variables with constant cofactors + for ( i = p->nVars - 1; i >= 0; i-- ) + { + if ( p->Counts[i][0] != 0 && p->Counts[i][1] != 0 && + p->Counts[i][0] != nOnesCof && p->Counts[i][1] != nOnesCof ) + continue; + pVar = p->pLeaves[i]; + if ( p->Counts[i][0] == 0 ) + { + Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[1] ); + // F = x' * 0 + x * F1 = x * F1 + return Aig_And( p->pMan, pVar, Aig_TruthDecompose( p ) ); + } + if ( p->Counts[i][1] == 0 ) + { + Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); + // F = x' * F0 + x * 0 = x' * F0 + return Aig_And( p->pMan, Aig_Not(pVar), Aig_TruthDecompose( p ) ); + } + if ( p->Counts[i][0] == nOnesCof ) + { + Aig_TruthCofactor( i, 1, p->nVars, p->Truth, p->Cofs[1] ); + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[1] ); + // F = x' * 1 + x * F1 = x' + F1 + return Aig_Or( p->pMan, Aig_Not(pVar), Aig_TruthDecompose( p ) ); + } + if ( p->Counts[i][1] == nOnesCof ) + { + Aig_TruthCofactor( i, 0, p->nVars, p->Truth, p->Cofs[0] ); + // remove redundant variable + Aig_TruthReplaceByCofactor( p, i, p->Cofs[0] ); + // F = x' * F0 + x * 1 = x + F0 + return Aig_Or( p->pMan, pVar, Aig_TruthDecompose( p ) ); + } + assert( 0 ); + } + +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/sat/csat/csat_apis.c b/src/sat/csat/csat_apis.c index 3fadd457..d25e42db 100644 --- a/src/sat/csat/csat_apis.c +++ b/src/sat/csat/csat_apis.c @@ -34,6 +34,7 @@ struct ABC_ManagerStruct_t Abc_Ntk_t * pNtk; // the starting ABC network Abc_Ntk_t * pTarget; // the AIG representing the target char * pDumpFileName; // the name of the file to dump the target network + Extra_MmFlex_t * pMmNames; // memory manager for signal names // solving parameters int mode; // 0 = brute-force SAT; 1 = resource-aware FRAIG int nSeconds; // time limit for pure SAT solving @@ -76,6 +77,7 @@ ABC_Manager ABC_InitManager() mng->pNtk->pName = util_strsav("csat_network"); mng->tName2Node = stmm_init_table(strcmp, stmm_strhash); mng->tNode2Name = stmm_init_table(stmm_ptrcmp, stmm_ptrhash); + mng->pMmNames = Extra_MmFlexStart(); mng->vNodes = Vec_PtrAlloc( 100 ); mng->vValues = Vec_IntAlloc( 100 ); mng->nSeconds = ABC_DEFAULT_TIMEOUT; @@ -97,6 +99,7 @@ void ABC_QuitManager( ABC_Manager mng ) { if ( mng->tNode2Name ) stmm_free_table( mng->tNode2Name ); if ( mng->tName2Node ) stmm_free_table( mng->tName2Node ); + if ( mng->pMmNames ) Extra_MmFlexStop( mng->pMmNames, 0 ); if ( mng->pNtk ) Abc_NtkDelete( mng->pNtk ); if ( mng->pTarget ) Abc_NtkDelete( mng->pTarget ); if ( mng->vNodes ) Vec_PtrFree( mng->vNodes ); @@ -146,9 +149,15 @@ void ABC_SetSolveOption( ABC_Manager mng, enum ABC_OptionT option ) int ABC_AddGate( ABC_Manager mng, enum GateType type, char * name, int nofi, char ** fanins, int dc_attr ) { Abc_Obj_t * pObj, * pFanin; - char * pSop; + char * pSop, * pNewName; int i; + // save the name in the local memory manager + pNewName = Extra_MmFlexEntryFetch( mng->pMmNames, strlen(name) + 1 ); + strcpy( pNewName, name ); + name = pNewName; + + // consider different cases, create the node, and map the node into the name switch( type ) { case ABC_BPI: @@ -250,6 +259,8 @@ int ABC_AddGate( ABC_Manager mng, enum GateType type, char * name, int nofi, cha printf( "ABC_AddGate: Unknown gate type.\n" ); break; } + + // map the name into the node if ( stmm_insert( mng->tName2Node, name, (char *)pObj ) ) { printf( "ABC_AddGate: The same gate \"%s\" is added twice.\n", name ); return 0; } return 1; @@ -690,6 +701,101 @@ char * ABC_GetNodeName( ABC_Manager mng, Abc_Obj_t * pNode ) return pName; } + + +/**Function************************************************************* + + Synopsis [This procedure applies a rewriting script to the network.] + + Description [Rewriting is performed without regard for the number of + logic levels. This corresponds to "circuit compression for formal + verification" (Per Bjesse et al, ICCAD 2004) but implemented in a more + exhaustive way than in the above paper.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void ABC_PerformRewriting( ABC_Manager mng ) +{ + void * pAbc; + char Command[1000]; + int clkBalan, clkResyn, clk; + int fPrintStats = 1; + int fUseResyn = 1; + + // procedures to get the ABC framework and execute commands in it + extern void * Abc_FrameGetGlobalFrame(); + extern void Abc_FrameReplaceCurrentNetwork( void * p, Abc_Ntk_t * pNtk ); + extern int Cmd_CommandExecute( void * p, char * sCommand ); + extern Abc_Ntk_t * Abc_FrameReadNtk( void * p ); + + + // get the pointer to the ABC framework + pAbc = Abc_FrameGetGlobalFrame(); + assert( pAbc != NULL ); + + // replace the current network by the target network + Abc_FrameReplaceCurrentNetwork( pAbc, mng->pTarget ); + +clk = clock(); + ////////////////////////////////////////////////////////////////////////// + // balance + sprintf( Command, "balance" ); + if ( Cmd_CommandExecute( pAbc, Command ) ) + { + fprintf( stdout, "Cannot execute command \"%s\".\n", Command ); + return; + } +clkBalan = clock() - clk; + + ////////////////////////////////////////////////////////////////////////// + // print stats + if ( fPrintStats ) + { + sprintf( Command, "print_stats" ); + if ( Cmd_CommandExecute( pAbc, Command ) ) + { + fprintf( stdout, "Cannot execute command \"%s\".\n", Command ); + return; + } + } + +clk = clock(); + ////////////////////////////////////////////////////////////////////////// + // synthesize + if ( fUseResyn ) + { + sprintf( Command, "balance; rewrite -l; rewrite -lz; balance; rewrite -lz; balance" ); + if ( Cmd_CommandExecute( pAbc, Command ) ) + { + fprintf( stdout, "Cannot execute command \"%s\".\n", Command ); + return; + } + } +clkResyn = clock() - clk; + + ////////////////////////////////////////////////////////////////////////// + // print stats + if ( fPrintStats ) + { + sprintf( Command, "print_stats" ); + if ( Cmd_CommandExecute( pAbc, Command ) ) + { + fprintf( stdout, "Cannot execute command \"%s\".\n", Command ); + return; + } + } + printf( "Balancing = %6.2f sec ", (float)(clkBalan)/(float)(CLOCKS_PER_SEC) ); + printf( "Rewriting = %6.2f sec ", (float)(clkResyn)/(float)(CLOCKS_PER_SEC) ); + printf( "\n" ); + + // read the target network from the current network + mng->pTarget = Abc_NtkDup( Abc_FrameReadNtk(pAbc) ); +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/csat/csat_apis.h b/src/sat/csat/csat_apis.h index 3e04c7df..a6179710 100644 --- a/src/sat/csat/csat_apis.h +++ b/src/sat/csat/csat_apis.h @@ -171,6 +171,8 @@ extern void ABC_Dump_Bench_File(ABC_Manager mng); extern void ABC_QuitManager( ABC_Manager mng ); extern void ABC_TargetResFree( ABC_Target_ResultT * p ); +extern void ABC_PerformRewriting( ABC_Manager mng ); + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/fraig/fraigMan.c b/src/sat/fraig/fraigMan.c index 673fcad7..ff6faa33 100644 --- a/src/sat/fraig/fraigMan.c +++ b/src/sat/fraig/fraigMan.c @@ -185,7 +185,7 @@ void Fraig_ManFree( Fraig_Man_t * p ) // Fraig_TablePrintStatsF( p ); // Fraig_TablePrintStatsF0( p ); } - + for ( i = 0; i < p->vNodes->nSize; i++ ) if ( p->vNodes->pArray[i]->vFanins ) { diff --git a/src/sat/fraig/fraigSat.c b/src/sat/fraig/fraigSat.c index a9e09f61..d4358772 100644 --- a/src/sat/fraig/fraigSat.c +++ b/src/sat/fraig/fraigSat.c @@ -156,6 +156,132 @@ int Fraig_ManCheckMiter( Fraig_Man_t * p ) /**Function************************************************************* + Synopsis [Returns 1 if pOld is in the TFI of pNew.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_MarkTfi_rec( Fraig_Man_t * pMan, Fraig_Node_t * pNode ) +{ + // skip the visited node + if ( pNode->TravId == pMan->nTravIds ) + return 0; + pNode->TravId = pMan->nTravIds; + // skip the PI node + if ( pNode->NumPi >= 0 ) + return 1; + // check the children + return Fraig_MarkTfi_rec( pMan, Fraig_Regular(pNode->p1) ) + + Fraig_MarkTfi_rec( pMan, Fraig_Regular(pNode->p2) ); +} + +/**Function************************************************************* + + Synopsis [Returns 1 if pOld is in the TFI of pNew.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_MarkTfi2_rec( Fraig_Man_t * pMan, Fraig_Node_t * pNode ) +{ + // skip the visited node + if ( pNode->TravId == pMan->nTravIds ) + return 0; + // skip the boundary node + if ( pNode->TravId == pMan->nTravIds-1 ) + { + pNode->TravId = pMan->nTravIds; + return 1; + } + pNode->TravId = pMan->nTravIds; + // skip the PI node + if ( pNode->NumPi >= 0 ) + return 1; + // check the children + return Fraig_MarkTfi2_rec( pMan, Fraig_Regular(pNode->p1) ) + + Fraig_MarkTfi2_rec( pMan, Fraig_Regular(pNode->p2) ); +} + +/**Function************************************************************* + + Synopsis [Returns 1 if pOld is in the TFI of pNew.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fraig_MarkTfi3_rec( Fraig_Man_t * pMan, Fraig_Node_t * pNode ) +{ + // skip the visited node + if ( pNode->TravId == pMan->nTravIds ) + return 1; + // skip the boundary node + if ( pNode->TravId == pMan->nTravIds-1 ) + { + pNode->TravId = pMan->nTravIds; + return 1; + } + pNode->TravId = pMan->nTravIds; + // skip the PI node + if ( pNode->NumPi >= 0 ) + return 0; + // check the children + return Fraig_MarkTfi3_rec( pMan, Fraig_Regular(pNode->p1) ) * + Fraig_MarkTfi3_rec( pMan, Fraig_Regular(pNode->p2) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fraig_VarsStudy( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * pNew ) +{ + int NumPis, NumCut, fContain; + + // mark the TFI of pNew + p->nTravIds++; + NumPis = Fraig_MarkTfi_rec( p, pNew ); + printf( "(%d)(%d,%d):", NumPis, pOld->Level, pNew->Level ); + + // check if the old is in the TFI + if ( pOld->TravId == p->nTravIds ) + { + printf( "* " ); + return; + } + + // count the boundary of nodes in pOld + p->nTravIds++; + NumCut = Fraig_MarkTfi2_rec( p, pOld ); + printf( "%d", NumCut ); + + // check if the new is contained in the old's support + p->nTravIds++; + fContain = Fraig_MarkTfi3_rec( p, pNew ); + printf( "%c ", fContain? '+':'-' ); +} + + +/**Function************************************************************* + Synopsis [Checks whether two nodes are functinally equivalent.] Description [The flag (fComp) tells whether the nodes to be checked @@ -202,6 +328,7 @@ int Fraig_NodeIsEquivalent( Fraig_Man_t * p, Fraig_Node_t * pOld, Fraig_Node_t * // get the logic cone clk = clock(); +// Fraig_VarsStudy( p, pOld, pNew ); Fraig_OrderVariables( p, pOld, pNew ); // Fraig_PrepareCones( p, pOld, pNew ); p->timeTrav += clock() - clk; @@ -223,18 +350,20 @@ if ( fVerbose ) Msat_SolverPrepare( p->pSat, p->vVarsInt ); //p->time3 += clock() - clk; + // solve under assumptions // A = 1; B = 0 OR A = 1; B = 1 Msat_IntVecClear( p->vProj ); Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pOld->Num, 0) ); Msat_IntVecPush( p->vProj, MSAT_VAR2LIT(pNew->Num, !fComp) ); + +//Msat_SolverWriteDimacs( p->pSat, "temp_fraig.cnf" ); + // run the solver clk = clock(); RetValue1 = Msat_SolverSolve( p->pSat, p->vProj, nBTLimit, nTimeLimit ); p->timeSat += clock() - clk; -//Msat_SolverWriteDimacs( p->pSat, "temp_fraig.cnf" ); - if ( RetValue1 == MSAT_FALSE ) { //p->time1 += clock() - clk; diff --git a/src/sat/msat/msatClause.c b/src/sat/msat/msatClause.c index 62b9ecad..2ba8cd32 100644 --- a/src/sat/msat/msatClause.c +++ b/src/sat/msat/msatClause.c @@ -194,7 +194,7 @@ bool Msat_ClauseCreate( Msat_Solver_t * p, Msat_IntVec_t * vLits, bool fLearned, { Msat_SolverVarBumpActivity( p, pLits[i] ); // Msat_SolverVarBumpActivity( p, pLits[i] ); - p->pFreq[ MSAT_LIT2VAR(pLits[i]) ]++; +// p->pFreq[ MSAT_LIT2VAR(pLits[i]) ]++; } } diff --git a/src/sat/msat/msatSolverCore.c b/src/sat/msat/msatSolverCore.c index 5f13694b..091a0c55 100644 --- a/src/sat/msat/msatSolverCore.c +++ b/src/sat/msat/msatSolverCore.c @@ -140,8 +140,8 @@ bool Msat_SolverSolve( Msat_Solver_t * p, Msat_IntVec_t * vAssumps, int nBackTra int64 nConflictsOld = p->Stats.nConflicts; int64 nDecisionsOld = p->Stats.nDecisions; - p->pFreq = ALLOC( int, p->nVarsAlloc ); - memset( p->pFreq, 0, sizeof(int) * p->nVarsAlloc ); +// p->pFreq = ALLOC( int, p->nVarsAlloc ); +// memset( p->pFreq, 0, sizeof(int) * p->nVarsAlloc ); if ( vAssumps ) { |