/**CFile**************************************************************** FileName [fraigTrans.c] PackageName [MVSIS 1.3: Multi-valued logic synthesis system.] Synopsis [Adds the additive and distributive choices to the AIG.] Author [MVSIS Group] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - February 1, 2003.] Revision [$Id: fraigTrans.c,v 1.1 2005/02/28 05:34:34 alanmi Exp $] ***********************************************************************/ #include "fraigInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Adds choice nodes based on associativity.] Description [Make nLimit big AND gates and add all decompositions to the Fraig.] SideEffects [] SeeAlso [] ***********************************************************************/ void Fraig_ManAddChoices( Fraig_Man_t * pMan, int fVerbose, int nLimit ) { // ProgressBar * pProgress; char Buffer[100]; abctime clkTotal = Abc_Clock(); int i, nNodesBefore, nNodesAfter, nInputs, nMaxNodes; int /*nMaxLevel,*/ nDistributive; Fraig_Node_t *pNode, *pRepr; Fraig_Node_t *pX, *pA, *pB, *pC, /* *pD,*/ *pN, /* *pQ, *pR,*/ *pT; int fShortCut = 0; nDistributive = 0; // Fraig_ManSetApprox( pMan, 1 ); // NO functional reduction if (fShortCut) Fraig_ManSetFuncRed( pMan, 0 ); // First we mark critical functions i.e. compute those // nodes which lie on the critical path. Note that this // doesn't update the required times on any choice nodes // which are not the representatives /* nMaxLevel = Fraig_GetMaxLevel( pMan ); for ( i = 0; i < pMan->nOutputs; i++ ) { Fraig_SetNodeRequired( pMan, pMan->pOutputs[i], nMaxLevel ); } */ nNodesBefore = Fraig_ManReadNodeNum( pMan ); nInputs = Fraig_ManReadInputNum( pMan ); nMaxNodes = nInputs + nLimit * ( nNodesBefore - nInputs ); printf ("Limit = %d, Before = %d\n", nMaxNodes, nNodesBefore ); if (0) { char buffer[128]; sprintf (buffer, "test" ); // Fraig_MappingShow( pMan, buffer ); } // pProgress = Extra_ProgressBarStart( stdout, nMaxNodes ); Fraig_ManCheckConsistency( pMan ); for ( i = nInputs+1; (i < Fraig_ManReadNodeNum( pMan )) && (nMaxNodes > Fraig_ManReadNodeNum( pMan )); ++i ) { // if ( i == nNodesBefore ) // break; pNode = Fraig_ManReadIthNode( pMan, i ); assert ( pNode ); pRepr = pNode->pRepr ? pNode->pRepr : pNode; //printf ("Slack: %d\n", Fraig_NodeReadSlack( pRepr )); // All the new associative choices we add will have huge slack // since we do not redo timing, and timing doesnt handle choices // well anyway. However every newly added node is a choice of an // existing critical node, so they are considered critical. // if ( (Fraig_NodeReadSlack( pRepr ) > 3) && (i < nNodesBefore) ) // continue; // if ( pNode->pRepr ) // continue; // Try ((ab)c), x = ab -> (a(bc)) and (b(ac)) pX = Fraig_NodeReadOne(pNode); pC = Fraig_NodeReadTwo(pNode); if (Fraig_NodeIsAnd(pX) && !Fraig_IsComplement(pX)) { pA = Fraig_NodeReadOne(Fraig_Regular(pX)); pB = Fraig_NodeReadTwo(Fraig_Regular(pX)); // pA = Fraig_NodeGetRepr( pA ); // pB = Fraig_NodeGetRepr( pB ); // pC = Fraig_NodeGetRepr( pC ); if (fShortCut) { pT = Fraig_NodeAnd(pMan, pB, pC); if ( !pT->pRepr ) { pN = Fraig_NodeAnd(pMan, pA, pT); // Fraig_NodeAddChoice( pMan, pNode, pN ); } } else pN = Fraig_NodeAnd(pMan, pA, Fraig_NodeAnd(pMan, pB, pC)); // assert ( Fraig_NodesEqual(pN, pNode) ); if (fShortCut) { pT = Fraig_NodeAnd(pMan, pA, pC); if ( !pT->pRepr ) { pN = Fraig_NodeAnd(pMan, pB, pT); // Fraig_NodeAddChoice( pMan, pNode, pN ); } } else pN = Fraig_NodeAnd(pMan, pB, Fraig_NodeAnd(pMan, pA, pC)); // assert ( Fraig_NodesEqual(pN, pNode) ); } // Try (a(bc)), x = bc -> ((ab)c) and ((ac)b) pA = Fraig_NodeReadOne(pNode); pX = Fraig_NodeReadTwo(pNode); if (Fraig_NodeIsAnd(pX) && !Fraig_IsComplement(pX)) { pB = Fraig_NodeReadOne(Fraig_Regular(pX)); pC = Fraig_NodeReadTwo(Fraig_Regular(pX)); // pA = Fraig_NodeGetRepr( pA ); // pB = Fraig_NodeGetRepr( pB ); // pC = Fraig_NodeGetRepr( pC ); if (fShortCut) { pT = Fraig_NodeAnd(pMan, pA, pB); if ( !pT->pRepr ) { pN = Fraig_NodeAnd(pMan, pC, pT); // Fraig_NodeAddChoice( pMan, pNode, pN ); } } else pN = Fraig_NodeAnd(pMan, Fraig_NodeAnd(pMan, pA, pB), pC); // assert ( Fraig_NodesEqual(pN, pNode) ); if (fShortCut) { pT = Fraig_NodeAnd(pMan, pA, pC); if ( !pT->pRepr ) { pN = Fraig_NodeAnd(pMan, pB, pT); // Fraig_NodeAddChoice( pMan, pNode, pN ); } } else pN = Fraig_NodeAnd(pMan, Fraig_NodeAnd(pMan, pA, pC), pB); // assert ( Fraig_NodesEqual(pN, pNode) ); } /* // Try distributive transform pQ = Fraig_NodeReadOne(pNode); pR = Fraig_NodeReadTwo(pNode); if ( (Fraig_IsComplement(pQ) && Fraig_NodeIsAnd(pQ)) && (Fraig_IsComplement(pR) && Fraig_NodeIsAnd(pR)) ) { pA = Fraig_NodeReadOne(Fraig_Regular(pQ)); pB = Fraig_NodeReadTwo(Fraig_Regular(pQ)); pC = Fraig_NodeReadOne(Fraig_Regular(pR)); pD = Fraig_NodeReadTwo(Fraig_Regular(pR)); // Now detect the !(xy + xz) pattern, store // x in pA, y in pB and z in pC and set pD = 0 to indicate // pattern was found assert (pD != 0); if (pA == pC) { pC = pD; pD = 0; } if (pA == pD) { pD = 0; } if (pB == pC) { pB = pA; pA = pC; pC = pD; pD = 0; } if (pB == pD) { pB = pA; pA = pD; pD = 0; } if (pD == 0) { nDistributive++; pN = Fraig_Not(Fraig_NodeAnd(pMan, pA, Fraig_NodeOr(pMan, pB, pC))); if (fShortCut) Fraig_NodeAddChoice( pMan, pNode, pN ); // assert ( Fraig_NodesEqual(pN, pNode) ); } } */ if ( i % 1000 == 0 ) { sprintf( Buffer, "Adding choice %6d...", i - nNodesBefore ); // Extra_ProgressBarUpdate( pProgress, i, Buffer ); } } // Extra_ProgressBarStop( pProgress ); Fraig_ManCheckConsistency( pMan ); nNodesAfter = Fraig_ManReadNodeNum( pMan ); printf ( "Nodes before = %6d. Nodes with associative choices = %6d. Increase = %4.2f %%.\n", nNodesBefore, nNodesAfter, ((float)(nNodesAfter - nNodesBefore)) * 100.0/(nNodesBefore - nInputs) ); printf ( "Distributive = %d\n", nDistributive ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END