From 4d30a1e4f1edecff86d5066ce4653a370e59e5e1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 30 Jan 2008 08:01:00 -0800 Subject: Version abc80130 --- src/base/abci/abcStrash.c | 441 +++++++++++++--------------------------------- 1 file changed, 124 insertions(+), 317 deletions(-) (limited to 'src/base/abci/abcStrash.c') diff --git a/src/base/abci/abcStrash.c b/src/base/abci/abcStrash.c index c77f8dea..de87a1e9 100644 --- a/src/base/abci/abcStrash.c +++ b/src/base/abci/abcStrash.c @@ -1,6 +1,6 @@ /**CFile**************************************************************** - FileName [abcStrash.c] + FileName [aigStrash.c] SystemName [ABC: Logic synthesis and verification system.] @@ -14,7 +14,7 @@ Date [Ver. 1.0. Started - June 20, 2005.] - Revision [$Id: abcStrash.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + Revision [$Id: aigStrash.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ @@ -26,170 +26,52 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int fAllNodes, int fRecord ); +// static functions +static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkAig, bool fAllNodes ); +static Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ); +static Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ); + +extern char * Mio_GateReadSop( void * pGate ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Reapplies structural hashing to the AIG.] + Synopsis [Creates the strashed AIG network.] - Description [Because of the structural hashing, this procedure should not - change the number of nodes. It is useful to detect the bugs in the original AIG.] + Description [Converts the logic network or the AIG into a + structurally hashed AIG.] SideEffects [] SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkRestrash( Abc_Ntk_t * pNtk, bool fCleanup ) +Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup ) { - extern int timeRetime; Abc_Ntk_t * pNtkAig; - Abc_Obj_t * pObj; - int i, nNodes;//, RetValue; - assert( Abc_NtkIsStrash(pNtk) ); -//timeRetime = clock(); - // print warning about choice nodes - if ( Abc_NtkGetChoiceNum( pNtk ) ) - printf( "Warning: The choice nodes in the original AIG are removed by strashing.\n" ); - // start the new network (constants and CIs of the old network will point to the their counterparts in the new network) - pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); - // restrash the nodes (assuming a topological order of the old network) - Abc_NtkForEachNode( pNtk, pObj, i ) - pObj->pCopy = Abc_AigAnd( pNtkAig->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); - // finalize the network - Abc_NtkFinalize( pNtk, pNtkAig ); - // print warning about self-feed latches -// if ( Abc_NtkCountSelfFeedLatches(pNtkAig) ) -// printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) ); - // perform cleanup if requested - if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) - printf( "Abc_NtkRestrash(): AIG cleanup removed %d nodes (this is a bug).\n", nNodes ); - // duplicate EXDC - if ( pNtk->pExdc ) - pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc ); - // make sure everything is okay - if ( !Abc_NtkCheck( pNtkAig ) ) - { - printf( "Abc_NtkStrash: The network check has failed.\n" ); - Abc_NtkDelete( pNtkAig ); - return NULL; - } -//timeRetime = clock() - timeRetime; -// if ( RetValue = Abc_NtkRemoveSelfFeedLatches(pNtkAig) ) -// printf( "Modified %d self-feeding latches. The result may not verify.\n", RetValue ); - return pNtkAig; - -} - -/**Function************************************************************* - - Synopsis [Reapplies structural hashing to the AIG.] - - Description [Because of the structural hashing, this procedure should not - change the number of nodes. It is useful to detect the bugs in the original AIG.] - - SideEffects [] - - SeeAlso [] + int nNodes; -***********************************************************************/ -Abc_Ntk_t * Abc_NtkRestrashZero( Abc_Ntk_t * pNtk, bool fCleanup ) -{ - extern int timeRetime; - Abc_Ntk_t * pNtkAig; - Abc_Obj_t * pObj; - int i, nNodes;//, RetValue; - assert( Abc_NtkIsStrash(pNtk) ); -//timeRetime = clock(); + assert( !Abc_NtkIsNetlist(pNtk) ); + if ( Abc_NtkIsBddLogic(pNtk) ) + Abc_NtkBddToSop(pNtk); // print warning about choice nodes if ( Abc_NtkGetChoiceNum( pNtk ) ) - printf( "Warning: The choice nodes in the original AIG are removed by strashing.\n" ); - // start the new network (constants and CIs of the old network will point to the their counterparts in the new network) - pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); - // complement the 1-values registers - Abc_NtkForEachLatch( pNtk, pObj, i ) - if ( Abc_LatchIsInit1(pObj) ) - Abc_ObjFanout0(pObj)->pCopy = Abc_ObjNot(Abc_ObjFanout0(pObj)->pCopy); - // restrash the nodes (assuming a topological order of the old network) - Abc_NtkForEachNode( pNtk, pObj, i ) - pObj->pCopy = Abc_AigAnd( pNtkAig->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); - // finalize the network - Abc_NtkFinalize( pNtk, pNtkAig ); - // complement the 1-valued registers - Abc_NtkForEachLatch( pNtkAig, pObj, i ) - if ( Abc_LatchIsInit1(pObj) ) - Abc_ObjXorFaninC( Abc_ObjFanin0(pObj), 0 ); - // set all constant-0 values - Abc_NtkForEachLatch( pNtkAig, pObj, i ) - Abc_LatchSetInit0( pObj ); - - // print warning about self-feed latches -// if ( Abc_NtkCountSelfFeedLatches(pNtkAig) ) -// printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) ); - // perform cleanup if requested - if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) - printf( "Abc_NtkRestrash(): AIG cleanup removed %d nodes (this is a bug).\n", nNodes ); - // duplicate EXDC - if ( pNtk->pExdc ) - pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc ); - // make sure everything is okay - if ( !Abc_NtkCheck( pNtkAig ) ) - { - printf( "Abc_NtkStrash: The network check has failed.\n" ); - Abc_NtkDelete( pNtkAig ); - return NULL; - } -//timeRetime = clock() - timeRetime; -// if ( RetValue = Abc_NtkRemoveSelfFeedLatches(pNtkAig) ) -// printf( "Modified %d self-feeding latches. The result may not verify.\n", RetValue ); - return pNtkAig; - -} - -/**Function************************************************************* - - Synopsis [Transforms logic network into structurally hashed AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, int fAllNodes, int fCleanup, int fRecord ) -{ - Abc_Ntk_t * pNtkAig; - int nNodes; - assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) ); - // consider the special case when the network is already structurally hashed - if ( Abc_NtkIsStrash(pNtk) ) - return Abc_NtkRestrash( pNtk, fCleanup ); - // convert the node representation in the logic network to the AIG form - if ( !Abc_NtkToAig(pNtk) ) - { - printf( "Converting to AIGs has failed.\n" ); - return NULL; - } + printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" ); // perform strashing -// Abc_NtkCleanCopy( pNtk ); - pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG ); - Abc_NtkStrashPerform( pNtk, pNtkAig, fAllNodes, fRecord ); + pNtkAig = Abc_NtkStartFrom( pNtk, ABC_TYPE_STRASH, ABC_FUNC_AIG ); + Abc_NtkStrashPerform( pNtk, pNtkAig, fAllNodes ); Abc_NtkFinalize( pNtk, pNtkAig ); // print warning about self-feed latches -// if ( Abc_NtkCountSelfFeedLatches(pNtkAig) ) -// printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) ); - // perform cleanup if requested - nNodes = fCleanup? Abc_AigCleanup(pNtkAig->pManFunc) : 0; -// if ( nNodes ) -// printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes ); + if ( Abc_NtkCountSelfFeedLatches(pNtkAig) ) + printf( "The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) ); + if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) ) + printf( "Cleanup has removed %d nodes.\n", nNodes ); // duplicate EXDC if ( pNtk->pExdc ) - pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc ); + pNtkAig->pExdc = Abc_NtkStrash( pNtk->pExdc, 0, 1 ); // make sure everything is okay if ( !Abc_NtkCheck( pNtkAig ) ) { @@ -205,85 +87,34 @@ Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, int fAllNodes, int fCleanup, int fR Synopsis [Appends the second network to the first.] Description [Modifies the first network by adding the logic of the second. - Performs structural hashing while appending the networks. Does not change - the second network. Returns 0 if the appending failed, 1 otherise.] + Performs structural hashing while appending the networks. Does not add + the COs of the second. Does not change the second network. Returns 0 + if the appending failed, 1 otherise.] SideEffects [] SeeAlso [] ***********************************************************************/ -int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos ) +int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ) { Abc_Obj_t * pObj; - char * pName; - int i, nNewCis; + int i; // the first network should be an AIG assert( Abc_NtkIsStrash(pNtk1) ); assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) ); - if ( Abc_NtkIsLogic(pNtk2) && !Abc_NtkToAig(pNtk2) ) - { - printf( "Converting to AIGs has failed.\n" ); - return 0; - } + if ( Abc_NtkIsBddLogic(pNtk2) ) + Abc_NtkBddToSop(pNtk2); // check that the networks have the same PIs // reorder PIs of pNtk2 according to pNtk1 - if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1, 1 ) ) - printf( "Abc_NtkAppend(): The union of the network PIs is computed (warning).\n" ); + if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1 ) ) + return 0; // perform strashing - nNewCis = 0; Abc_NtkCleanCopy( pNtk2 ); - if ( Abc_NtkIsStrash(pNtk2) ) - Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtk1); Abc_NtkForEachCi( pNtk2, pObj, i ) - { - pName = Abc_ObjName(pObj); - pObj->pCopy = Abc_NtkFindCi(pNtk1, Abc_ObjName(pObj)); - if ( pObj->pCopy == NULL ) - { - pObj->pCopy = Abc_NtkDupObj(pNtk1, pObj, 1); - nNewCis++; - } - } - if ( nNewCis ) - printf( "Warning: Procedure Abc_NtkAppend() added %d new CIs.\n", nNewCis ); + pObj->pCopy = Abc_NtkCi(pNtk1, i); // add pNtk2 to pNtk1 while strashing - if ( Abc_NtkIsLogic(pNtk2) ) - Abc_NtkStrashPerform( pNtk2, pNtk1, 1, 0 ); - else - Abc_NtkForEachNode( pNtk2, pObj, i ) - pObj->pCopy = Abc_AigAnd( pNtk1->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) ); - // add the COs of the second network - if ( fAddPos ) - { - Abc_NtkForEachPo( pNtk2, pObj, i ) - { - Abc_NtkDupObj( pNtk1, pObj, 0 ); - Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) ); - Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj->pCopy), NULL ); - } - } - else - { - Abc_Obj_t * pObjOld, * pDriverOld, * pDriverNew; - int fCompl, iNodeId; - // OR the choices - Abc_NtkForEachCo( pNtk2, pObj, i ) - { - iNodeId = Nm_ManFindIdByNameTwoTypes( pNtk1->pManName, Abc_ObjName(pObj), ABC_OBJ_PO, ABC_OBJ_BI ); - assert( iNodeId >= 0 ); - pObjOld = Abc_NtkObj( pNtk1, iNodeId ); - // derive the new driver - pDriverOld = Abc_ObjChild0( pObjOld ); - pDriverNew = Abc_ObjChild0Copy( pObj ); - pDriverNew = Abc_AigOr( pNtk1->pManFunc, pDriverOld, pDriverNew ); - if ( Abc_ObjRegular(pDriverOld) == Abc_ObjRegular(pDriverNew) ) - continue; - // replace the old driver by the new driver - fCompl = Abc_ObjRegular(pDriverOld)->fPhase ^ Abc_ObjRegular(pDriverNew)->fPhase; - Abc_ObjPatchFanin( pObjOld, Abc_ObjRegular(pDriverOld), Abc_ObjNotCond(Abc_ObjRegular(pDriverNew), fCompl) ); - } - } + Abc_NtkStrashPerform( pNtk2, pNtk1, 1 ); // make sure that everything is okay if ( !Abc_NtkCheck( pNtk1 ) ) { @@ -293,6 +124,7 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos ) return 1; } + /**Function************************************************************* Synopsis [Prepares the network for strashing.] @@ -304,31 +136,38 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos ) SeeAlso [] ***********************************************************************/ -void Abc_NtkStrashPerform( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew, int fAllNodes, int fRecord ) +void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, bool fAllNodes ) { ProgressBar * pProgress; + Abc_Aig_t * pMan = pNtkNew->pManFunc; Vec_Ptr_t * vNodes; - Abc_Obj_t * pNodeOld; - int i, clk = clock(); - assert( Abc_NtkIsLogic(pNtkOld) ); - assert( Abc_NtkIsStrash(pNtkNew) ); -// vNodes = Abc_NtkDfs( pNtkOld, fAllNodes ); - vNodes = Abc_NtkDfsIter( pNtkOld, fAllNodes ); -//printf( "Nodes = %d. ", Vec_PtrSize(vNodes) ); -//PRT( "Time", clock() - clk ); + Abc_Obj_t * pNode, * pNodeNew, * pObj; + int i; + + // perform strashing + vNodes = Abc_NtkDfs( pNtk, fAllNodes ); pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize ); - Vec_PtrForEachEntry( vNodes, pNodeOld, i ) + Vec_PtrForEachEntry( vNodes, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); - pNodeOld->pCopy = Abc_NodeStrash( pNtkNew, pNodeOld, fRecord ); + // get the node + assert( Abc_ObjIsNode(pNode) ); + // strash the node + pNodeNew = Abc_NodeStrash( pMan, pNode ); + // get the old object + pObj = Abc_ObjFanout0Ntk( pNode ); + // make sure the node is not yet strashed + assert( pObj->pCopy == NULL ); + // mark the old object with the new AIG node + pObj->pCopy = pNodeNew; } - Extra_ProgressBarStop( pProgress ); Vec_PtrFree( vNodes ); + Extra_ProgressBarStop( pProgress ); } /**Function************************************************************* - Synopsis [Transfers the AIG from one manager into another.] + Synopsis [Strashes one logic node.] Description [] @@ -337,76 +176,40 @@ void Abc_NtkStrashPerform( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew, int fAllNod SeeAlso [] ***********************************************************************/ -void Abc_NodeStrash_rec( Abc_Aig_t * pMan, Hop_Obj_t * pObj ) +Abc_Obj_t * Abc_NodeStrash( Abc_Aig_t * pMan, Abc_Obj_t * pNode ) { - assert( !Hop_IsComplement(pObj) ); - if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) ) - return; - Abc_NodeStrash_rec( pMan, Hop_ObjFanin0(pObj) ); - Abc_NodeStrash_rec( pMan, Hop_ObjFanin1(pObj) ); - pObj->pData = Abc_AigAnd( pMan, (Abc_Obj_t *)Hop_ObjChild0Copy(pObj), (Abc_Obj_t *)Hop_ObjChild1Copy(pObj) ); - assert( !Hop_ObjIsMarkA(pObj) ); // loop detection - Hop_ObjSetMarkA( pObj ); -} - -/**Function************************************************************* + int fUseFactor = 1; + char * pSop; - Synopsis [Strashes one logic node.] + assert( Abc_ObjIsNode(pNode) ); - Description [Assume the network is in the AIG form] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, int fRecord ) -{ - Hop_Man_t * pMan; - Hop_Obj_t * pRoot; - Abc_Obj_t * pFanin; - int i; - assert( Abc_ObjIsNode(pNodeOld) ); - assert( Abc_NtkHasAig(pNodeOld->pNtk) && !Abc_NtkIsStrash(pNodeOld->pNtk) ); - // get the local AIG manager and the local root node - pMan = pNodeOld->pNtk->pManFunc; - pRoot = pNodeOld->pData; - // check the constant case - if ( Abc_NodeIsConst(pNodeOld) || Hop_Regular(pRoot) == Hop_ManConst1(pMan) ) - return Abc_ObjNotCond( Abc_AigConst1(pNtkNew), Hop_IsComplement(pRoot) ); - // perform special case-strashing using the record of AIG subgraphs - if ( fRecord && Abc_NtkRecIsRunning() && Abc_ObjFaninNum(pNodeOld) > 2 && Abc_ObjFaninNum(pNodeOld) <= Abc_NtkRecVarNum() ) + // consider the case when the graph is an AIG + if ( Abc_NtkIsStrash(pNode->pNtk) ) { - extern Vec_Int_t * Abc_NtkRecMemory(); - extern int Abc_NtkRecStrashNode( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, unsigned * pTruth, int nVars ); - int nVars = Abc_NtkRecVarNum(); - Vec_Int_t * vMemory = Abc_NtkRecMemory(); - unsigned * pTruth = Abc_ConvertAigToTruth( pMan, Hop_Regular(pRoot), nVars, vMemory, 0 ); - assert( Extra_TruthSupportSize(pTruth, nVars) == Abc_ObjFaninNum(pNodeOld) ); // should be swept - if ( Hop_IsComplement(pRoot) ) - Extra_TruthNot( pTruth, pTruth, nVars ); - if ( Abc_NtkRecStrashNode( pNtkNew, pNodeOld, pTruth, nVars ) ) - return pNodeOld->pCopy; + if ( Abc_NodeIsConst(pNode) ) + return Abc_AigConst1(pMan); + return Abc_AigAnd( pMan, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); } - // set elementary variables - Abc_ObjForEachFanin( pNodeOld, pFanin, i ) - Hop_IthVar(pMan, i)->pData = pFanin->pCopy; - // strash the AIG of this node - Abc_NodeStrash_rec( pNtkNew->pManFunc, Hop_Regular(pRoot) ); - Hop_ConeUnmark_rec( Hop_Regular(pRoot) ); - // return the final node - return Abc_ObjNotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) ); -} - - - + // get the SOP of the node + if ( Abc_NtkHasMapping(pNode->pNtk) ) + pSop = Mio_GateReadSop(pNode->pData); + else + pSop = pNode->pData; + // consider the constant node + if ( Abc_NodeIsConst(pNode) ) + return Abc_ObjNotCond( Abc_AigConst1(pMan), Abc_SopIsConst0(pSop) ); + // decide when to use factoring + if ( fUseFactor && Abc_ObjFaninNum(pNode) > 2 && Abc_SopGetCubeNum(pSop) > 1 ) + return Abc_NodeStrashFactor( pMan, pNode, pSop ); + return Abc_NodeStrashSop( pMan, pNode, pSop ); +} /**Function************************************************************* - Synopsis [Copies the topmost levels of the network.] + Synopsis [Strashes one logic node using its SOP.] Description [] @@ -415,21 +218,41 @@ Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, int fReco SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Abc_NtkTopmost_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int LevelCut ) +Abc_Obj_t * Abc_NodeStrashSop( Abc_Aig_t * pMan, Abc_Obj_t * pNode, char * pSop ) { - assert( !Abc_ObjIsComplement(pNode) ); - if ( pNode->pCopy ) - return pNode->pCopy; - if ( pNode->Level <= (unsigned)LevelCut ) - return pNode->pCopy = Abc_NtkCreatePi( pNtkNew ); - Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(pNode), LevelCut ); - Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin1(pNode), LevelCut ); - return pNode->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) ); + Abc_Obj_t * pFanin, * pAnd, * pSum; + Abc_Obj_t * pConst1 = Abc_AigConst1(pMan); + char * pCube; + int i, nFanins; + + // get the number of node's fanins + nFanins = Abc_ObjFaninNum( pNode ); + assert( nFanins == Abc_SopGetVarNum(pSop) ); + // go through the cubes of the node's SOP + pSum = Abc_ObjNot(pConst1); + Abc_SopForEachCube( pSop, nFanins, pCube ) + { + // create the AND of literals + pAnd = pConst1; + Abc_ObjForEachFanin( pNode, pFanin, i ) // pFanin can be a net + { + if ( pCube[i] == '1' ) + pAnd = Abc_AigAnd( pMan, pAnd, pFanin->pCopy ); + else if ( pCube[i] == '0' ) + pAnd = Abc_AigAnd( pMan, pAnd, Abc_ObjNot(pFanin->pCopy) ); + } + // add to the sum of cubes + pSum = Abc_AigOr( pMan, pSum, pAnd ); + } + // decide whether to complement the result + if ( Abc_SopIsComplement(pSop) ) + pSum = Abc_ObjNot(pSum); + return pSum; } /**Function************************************************************* - Synopsis [Copies the topmost levels of the network.] + Synopsis [Strashes one logic node using its SOP.] Description [] @@ -438,39 +261,23 @@ Abc_Obj_t * Abc_NtkTopmost_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int Leve SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels ) +Abc_Obj_t * Abc_NodeStrashFactor( Abc_Aig_t * pMan, Abc_Obj_t * pRoot, char * pSop ) { - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObjNew, * pPoNew; - int LevelCut; - assert( Abc_NtkIsStrash(pNtk) ); - assert( Abc_NtkCoNum(pNtk) == 1 ); - // get the cutoff level - LevelCut = ABC_MAX( 0, Abc_AigLevel(pNtk) - nLevels ); - // start the network - pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); - pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); - Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); - // create PIs below the cut and nodes above the cut - Abc_NtkCleanCopy( pNtk ); - pObjNew = Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(Abc_NtkPo(pNtk, 0)), LevelCut ); - pObjNew = Abc_ObjNotCond( pObjNew, Abc_ObjFaninC0(Abc_NtkPo(pNtk, 0)) ); - // add the PO node and name - pPoNew = Abc_NtkCreatePo(pNtkNew); - Abc_ObjAddFanin( pPoNew, pObjNew ); - Abc_NtkAddDummyPiNames( pNtkNew ); - Abc_ObjAssignName( pPoNew, Abc_ObjName(Abc_NtkPo(pNtk, 0)), NULL ); - // make sure everything is okay - if ( !Abc_NtkCheck( pNtkNew ) ) - { - printf( "Abc_NtkTopmost: The network check has failed.\n" ); - Abc_NtkDelete( pNtkNew ); - return NULL; - } - return pNtkNew; + Dec_Graph_t * pFForm; + Dec_Node_t * pNode; + Abc_Obj_t * pAnd; + int i; + // perform factoring + pFForm = Dec_Factor( pSop ); + // collect the fanins + Dec_GraphForEachLeaf( pFForm, pNode, i ) + pNode->pFunc = Abc_ObjFanin(pRoot,i)->pCopy; + // perform strashing + pAnd = Dec_GraphToNetwork( pMan, pFForm ); + Dec_GraphFree( pFForm ); + return pAnd; } - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3