diff options
Diffstat (limited to 'src/aig/ntl/ntlExtract.c')
-rw-r--r-- | src/aig/ntl/ntlExtract.c | 877 |
1 files changed, 0 insertions, 877 deletions
diff --git a/src/aig/ntl/ntlExtract.c b/src/aig/ntl/ntlExtract.c deleted file mode 100644 index a6268b2c..00000000 --- a/src/aig/ntl/ntlExtract.c +++ /dev/null @@ -1,877 +0,0 @@ -/**CFile**************************************************************** - - FileName [ntlExtract.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Netlist representation.] - - Synopsis [Netlist SOP to AIG conversion.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: ntlExtract.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "ntl.h" -#include "dec.h" -#include "kit.h" - -ABC_NAMESPACE_IMPL_START - - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Obj_t * Ntl_ConvertSopToAigInternal( Aig_Man_t * pMan, Ntl_Obj_t * pNode, char * pSop ) -{ - Ntl_Net_t * pNet; - Aig_Obj_t * pAnd, * pSum; - int i, Value, nFanins; - char * pCube; - // get the number of variables - nFanins = Kit_PlaGetVarNum(pSop); - // go through the cubes of the node's SOP - pSum = Aig_ManConst0(pMan); - Kit_PlaForEachCube( pSop, nFanins, pCube ) - { - // create the AND of literals - pAnd = Aig_ManConst1(pMan); - Kit_PlaCubeForEachVar( pCube, Value, i ) - { - pNet = Ntl_ObjFanin( pNode, i ); - if ( Value == '1' ) - pAnd = Aig_And( pMan, pAnd, (Aig_Obj_t *)pNet->pCopy ); - else if ( Value == '0' ) - pAnd = Aig_And( pMan, pAnd, Aig_Not((Aig_Obj_t *)pNet->pCopy) ); - } - // add to the sum of cubes - pSum = Aig_Or( pMan, pSum, pAnd ); - } - // decide whether to complement the result - if ( Kit_PlaIsComplement(pSop) ) - pSum = Aig_Not(pSum); - return pSum; -} - -/**Function************************************************************* - - Synopsis [Transforms the decomposition graph into the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Obj_t * Ntl_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph ) -{ - Dec_Node_t * pNode = NULL; // Suppress "might be used uninitialized" - Aig_Obj_t * pAnd0, * pAnd1; - int i; - // check for constant function - if ( Dec_GraphIsConst(pGraph) ) - return Aig_NotCond( Aig_ManConst1(pMan), Dec_GraphIsComplement(pGraph) ); - // check for a literal - if ( Dec_GraphIsVar(pGraph) ) - return Aig_NotCond( (Aig_Obj_t *)Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); - // build the AIG nodes corresponding to the AND gates of the graph - Dec_GraphForEachNode( pGraph, pNode, i ) - { - pAnd0 = Aig_NotCond( (Aig_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - pAnd1 = Aig_NotCond( (Aig_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); - pNode->pFunc = Aig_And( pMan, pAnd0, pAnd1 ); - } - // complement the result if necessary - return Aig_NotCond( (Aig_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) ); -} - -/**Function************************************************************* - - Synopsis [Converts the network from AIG to BDD representation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Obj_t * Ntl_ManBuildNodeAig( Ntl_Man_t * p, Ntl_Obj_t * pNode ) -{ - int fUseFactor = 1; - // consider the constant node - if ( Kit_PlaGetVarNum(pNode->pSop) == 0 ) - return Aig_NotCond( Aig_ManConst1(p->pAig), Kit_PlaIsConst0(pNode->pSop) ); - // decide when to use factoring - if ( fUseFactor && Kit_PlaGetVarNum(pNode->pSop) > 2 && Kit_PlaGetCubeNum(pNode->pSop) > 1 ) - { - Dec_Graph_t * pFForm; - Dec_Node_t * pFFNode; - Aig_Obj_t * pFunc; - int i; - // perform factoring - pFForm = Dec_Factor( pNode->pSop ); - // collect the fanins - Dec_GraphForEachLeaf( pFForm, pFFNode, i ) - pFFNode->pFunc = Ntl_ObjFanin(pNode, i)->pCopy; - // perform strashing - pFunc = Ntl_GraphToNetworkAig( p->pAig, pFForm ); - Dec_GraphFree( pFForm ); - return pFunc; - } - return Ntl_ConvertSopToAigInternal( p->pAig, pNode, pNode->pSop ); -} - -/**Function************************************************************* - - Synopsis [Collects the nodes in a topological order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntl_ManExtract_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ) -{ - Ntl_Obj_t * pObj; - Ntl_Net_t * pNetFanin; - int i; - // skip visited - if ( pNet->nVisits == 2 ) - return 1; - // if the node is on the path, this is a combinational loop - if ( pNet->nVisits == 1 ) - return 0; - // mark the node as the one on the path - pNet->nVisits = 1; - // derive the box - pObj = pNet->pDriver; - assert( Ntl_ObjIsNode(pObj) || Ntl_ObjIsBox(pObj) ); - // visit the input nets of the box - Ntl_ObjForEachFanin( pObj, pNetFanin, i ) - if ( !Ntl_ManExtract_rec( p, pNetFanin ) ) - return 0; - // add box inputs/outputs to COs/CIs - if ( Ntl_ObjIsBox(pObj) ) - { - int LevelCur, LevelMax = -TIM_ETERNITY; - assert( Ntl_BoxIsComb(pObj) ); - assert( Ntl_ModelLatchNum(pObj->pImplem) == 0 ); - assert( pObj->pImplem->vDelays != NULL ); - Vec_IntPush( p->vBox1Cios, Aig_ManPoNum(p->pAig) ); - Ntl_ObjForEachFanin( pObj, pNetFanin, i ) - { - LevelCur = Aig_ObjLevel( Aig_Regular((Aig_Obj_t *)pNetFanin->pCopy) ); - LevelMax = ABC_MAX( LevelMax, LevelCur ); - Vec_PtrPush( p->vCos, pNetFanin ); - Aig_ObjCreatePo( p->pAig, (Aig_Obj_t *)pNetFanin->pCopy ); - } - Ntl_ObjForEachFanout( pObj, pNetFanin, i ) - { - Vec_PtrPush( p->vCis, pNetFanin ); - pNetFanin->pCopy = Aig_ObjCreatePi( p->pAig ); - Aig_ObjSetLevel( (Aig_Obj_t *)pNetFanin->pCopy, LevelMax + 1 ); - } - } - Vec_PtrPush( p->vVisNodes, pObj ); - if ( Ntl_ObjIsNode(pObj) ) - pNet->pCopy = Ntl_ManBuildNodeAig( p, pObj ); - pNet->nVisits = 2; - return 1; -} - -/**Function************************************************************* - - Synopsis [Performs DFS.] - - Description [Checks for combinational loops. Collects PI/PO nets. - Collects nodes in the topological order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p ) -{ - Aig_Man_t * pAig; - Ntl_Mod_t * pRoot; - Ntl_Obj_t * pObj; - Ntl_Net_t * pNet; - int i, k, nUselessObjects; - Ntl_ManCleanup( p ); - Vec_PtrClear( p->vCis ); - Vec_PtrClear( p->vCos ); - Vec_PtrClear( p->vVisNodes ); - Vec_IntClear( p->vBox1Cios ); - // start the AIG manager - assert( p->pAig == NULL ); - p->pAig = Aig_ManStart( 10000 ); - p->pAig->pName = Aig_UtilStrsav( p->pName ); - p->pAig->pSpec = Aig_UtilStrsav( p->pSpec ); - // get the root model - pRoot = Ntl_ManRootModel( p ); - assert( Ntl_ModelLatchNum(pRoot) == 0 ); - // clear net visited flags - Ntl_ModelClearNets( pRoot ); - // collect mapping leafs - Ntl_ModelForEachMapLeaf( pRoot, pObj, i ) - { - assert( !Ntl_ObjIsBox(pObj) || Ntl_BoxIsBlack(pObj) || Ntl_ModelLatchNum(pObj->pImplem) > 0 ); - Ntl_ObjForEachFanout( pObj, pNet, k ) - { - Vec_PtrPush( p->vCis, pNet ); - pNet->pCopy = Aig_ObjCreatePi( p->pAig ); - if ( pNet->nVisits ) - { - printf( "Ntl_ManExtract(): Seq leaf is duplicated or defined as a primary input.\n" ); - return 0; - } - pNet->nVisits = 2; - } - } - p->iLastCi = Aig_ManPiNum(p->pAig); - // collect mapping roots - Ntl_ModelForEachMapRoot( pRoot, pObj, i ) - { - Ntl_ObjForEachFanin( pObj, pNet, k ) - { - if ( !Ntl_ManExtract_rec( p, pNet ) ) - { - printf( "Ntl_ManExtract(): Error: Combinational loop is detected.\n" ); - return 0; - } - Vec_PtrPush( p->vCos, pNet ); - Aig_ObjCreatePo( p->pAig, (Aig_Obj_t *)pNet->pCopy ); - } - } - // visit dangling boxes - Ntl_ModelForEachBox( pRoot, pObj, i ) - { - pNet = Ntl_ObjFanout0(pObj); - if ( !Ntl_ManExtract_rec( p, pNet ) ) - { - printf( "Ntl_ManExtract(): Error: Combinational loop is detected.\n" ); - return 0; - } - } - // report the number of dangling objects - nUselessObjects = Ntl_ModelNodeNum(pRoot) + Ntl_ModelLut1Num(pRoot) + Ntl_ModelBoxNum(pRoot) - Vec_PtrSize(p->vVisNodes); -// if ( nUselessObjects ) -// printf( "The number of dangling objects = %d.\n", nUselessObjects ); - // cleanup the AIG - Aig_ManCleanup( p->pAig ); - // extract the timing manager - assert( p->pManTime == NULL ); - p->pManTime = Ntl_ManCreateTiming( p ); - // discretize timing info - p->pAig->pManTime = Tim_ManDup( p->pManTime, 1 ); - pAig = p->pAig; p->pAig = NULL; - return pAig; -} - - - - -/**Function************************************************************* - - Synopsis [Collects the nodes in a topological order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntl_ManCollapseBoxComb_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox ) -{ - extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ); - Ntl_Mod_t * pModel = pBox->pImplem; - Ntl_Obj_t * pObj; - Ntl_Net_t * pNet, * pNetBox; - int i; - assert( Ntl_ObjFaninNum(pBox) == Ntl_ModelPiNum(pModel) ); - assert( Ntl_ObjFanoutNum(pBox) == Ntl_ModelPoNum(pModel) ); - // clear net visited flags - Ntl_ModelClearNets( pModel ); - // transfer from the box to the PIs of the model - Ntl_ModelForEachPi( pModel, pObj, i ) - { - pNet = Ntl_ObjFanout0(pObj); - pNetBox = Ntl_ObjFanin( pBox, i ); - pNet->pCopy = pNetBox->pCopy; - pNet->nVisits = 2; - } - // compute AIG for the internal nodes - Ntl_ModelForEachPo( pModel, pObj, i ) - { - pNet = Ntl_ObjFanin0(pObj); - if ( !Ntl_ManCollapse_rec( p, pNet ) ) - return 0; - pNetBox = Ntl_ObjFanout( pBox, i ); - pNetBox->pCopy = pNet->pCopy; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Collects the nodes in a topological order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntl_ManCollapseBoxSeq1_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox ) -{ - extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ); - Ntl_Mod_t * pModel = pBox->pImplem; - Ntl_Obj_t * pObj; - Ntl_Net_t * pNet, * pNetBox; - int i; - assert( Ntl_ModelLatchNum(pModel) > 0 ); - assert( Ntl_ObjFaninNum(pBox) == Ntl_ModelPiNum(pModel) ); - assert( Ntl_ObjFanoutNum(pBox) == Ntl_ModelPoNum(pModel) ); - // clear net visited flags - Ntl_ModelClearNets( pModel ); - // initialize the registers - Ntl_ModelForEachLatch( pModel, pObj, i ) - { - pNet = Ntl_ObjFanout0(pObj); - pNet->pCopy = Aig_ObjCreatePi( p->pAig ); - if ( Ntl_ObjIsInit1( pObj ) ) - pNet->pCopy = Aig_Not((Aig_Obj_t *)pNet->pCopy); - pNet->nVisits = 2; - // remember the class of this register - Vec_IntPush( p->vRegClasses, p->pNal ? pBox->iTemp : pObj->LatchId.regClass ); - Vec_IntPush( p->vRstClasses, p->pNal ? pBox->Reset : -1 ); - } - // compute AIG for the internal nodes - Ntl_ModelForEachPo( pModel, pObj, i ) - { - pNet = Ntl_ObjFanin0(pObj); - if ( !Ntl_ManCollapse_rec( p, pNet ) ) - return 0; - pNetBox = Ntl_ObjFanout( pBox, i ); - pNetBox->pCopy = pNet->pCopy; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Collects the nodes in a topological order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntl_ManCollapseBoxSeq2_rec( Ntl_Man_t * p, Ntl_Obj_t * pBox, int iFirstPi ) -{ - extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ); - Ntl_Mod_t * pModel = pBox->pImplem; - Ntl_Obj_t * pObj; - Ntl_Net_t * pNet, * pNetBox; - int i; - assert( Ntl_ModelLatchNum(pModel) > 0 ); - assert( Ntl_ObjFaninNum(pBox) == Ntl_ModelPiNum(pModel) ); - assert( Ntl_ObjFanoutNum(pBox) == Ntl_ModelPoNum(pModel) ); - // clear net visited flags - Ntl_ModelClearNets( pModel ); - // transfer from the box to the PIs of the model - Ntl_ModelForEachPi( pModel, pObj, i ) - { - pNet = Ntl_ObjFanout0(pObj); - pNetBox = Ntl_ObjFanin( pBox, i ); - pNet->pCopy = pNetBox->pCopy; - pNet->nVisits = 2; - } - // initialize the registers - Ntl_ModelForEachLatch( pModel, pObj, i ) - { - pNet = Ntl_ObjFanout0(pObj); - pNet->pCopy = Aig_ManPi( p->pAig, iFirstPi++ ); - if ( Ntl_ObjIsInit1( pObj ) ) - pNet->pCopy = Aig_Not((Aig_Obj_t *)pNet->pCopy); - pNet->nVisits = 2; - } - // compute AIGs for the registers - Ntl_ModelForEachLatch( pModel, pObj, i ) - { - pNet = Ntl_ObjFanin0(pObj); - if ( !Ntl_ManCollapse_rec( p, pNet ) ) - return 0; - if ( Ntl_ObjIsInit1( pObj ) ) - Aig_ObjCreatePo( p->pAig, Aig_Not((Aig_Obj_t *)pNet->pCopy) ); - else - Aig_ObjCreatePo( p->pAig, (Aig_Obj_t *)pNet->pCopy ); - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Collects the nodes in a topological order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ) -{ - Ntl_Obj_t * pObj; - Ntl_Net_t * pNetFanin; - int i; - // skip visited - if ( pNet->nVisits == 2 ) - return 1; - // if the node is on the path, this is a combinational loop - if ( pNet->nVisits == 1 ) - return 0; - // mark the node as the one on the path - pNet->nVisits = 1; - // derive the box - pObj = pNet->pDriver; - assert( Ntl_ObjIsNode(pObj) || Ntl_ObjIsBox(pObj) ); - // visit the input nets of the box - Ntl_ObjForEachFanin( pObj, pNetFanin, i ) - if ( !Ntl_ManCollapse_rec( p, pNetFanin ) ) - return 0; - // add box inputs/outputs to COs/CIs - if ( Ntl_ObjIsBox(pObj) ) - { - assert( Ntl_BoxIsWhite(pObj) && Ntl_BoxIsComb(pObj) ); - if ( !Ntl_ManCollapseBoxComb_rec( p, pObj ) ) - return 0; - } - if ( Ntl_ObjIsNode(pObj) ) - pNet->pCopy = Ntl_ManBuildNodeAig( p, pObj ); - pNet->nVisits = 2; - return 1; -} - -/**Function************************************************************* - - Synopsis [Performs DFS.] - - Description [Checks for combinational loops. Collects PI/PO nets. - Collects nodes in the topological order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p, int fSeq ) -{ - Aig_Man_t * pAig; - Ntl_Mod_t * pRoot; - Ntl_Obj_t * pBox; - Ntl_Net_t * pNet; - int i, k, nTruePis, nTruePos, iBox = 0; - assert( Vec_PtrSize(p->vCis) != 0 ); - assert( Vec_PtrSize(p->vCos) != 0 ); - Vec_IntClear( p->vBox1Cios ); - Vec_IntClear( p->vRegClasses ); - Vec_IntClear( p->vRstClasses ); - // clear net visited flags - pRoot = Ntl_ManRootModel(p); - assert( Ntl_ModelLatchNum(pRoot) == 0 ); - Ntl_ModelClearNets( pRoot ); - // create the manager - p->pAig = Aig_ManStart( 10000 ); - p->pAig->pName = Aig_UtilStrsav( p->pName ); - p->pAig->pSpec = Aig_UtilStrsav( p->pSpec ); - // set the inputs - Ntl_ManForEachCiNet( p, pNet, i ) - { - pNet->pCopy = Aig_ObjCreatePi( p->pAig ); - if ( pNet->nVisits ) - { - printf( "Ntl_ManCollapse(): Primary input appears twice in the list.\n" ); - return 0; - } - pNet->nVisits = 2; - } - nTruePis = Aig_ManPiNum(p->pAig); - // create inputs of seq boxes - if ( fSeq ) { - Ntl_ModelForEachBox( pRoot, pBox, i ) - { - if ( !(Ntl_BoxIsSeq(pBox) && Ntl_BoxIsWhite(pBox)) ) - continue; - Vec_IntPush( p->vBox1Cios, Aig_ManPiNum(p->pAig) ); - Ntl_ManCollapseBoxSeq1_rec( p, pBox ); - Ntl_ObjForEachFanout( pBox, pNet, k ) - pNet->nVisits = 2; - } - } - // derive the outputs - Ntl_ManForEachCoNet( p, pNet, i ) - { - if ( !Ntl_ManCollapse_rec( p, pNet ) ) - { - printf( "Ntl_ManCollapse(): Error: Combinational loop is detected.\n" ); - return 0; - } - Aig_ObjCreatePo( p->pAig, (Aig_Obj_t *)pNet->pCopy ); - } - nTruePos = Aig_ManPoNum(p->pAig); - // create outputs of seq boxes - if ( fSeq ) { - Ntl_ModelForEachBox( pRoot, pBox, i ) - { - if ( !(Ntl_BoxIsSeq(pBox) && Ntl_BoxIsWhite(pBox)) ) - continue; - Ntl_ObjForEachFanin( pBox, pNet, k ) - if ( !Ntl_ManCollapse_rec( p, pNet ) ) - { - printf( "Ntl_ManCollapse(): Error: Combinational loop is detected.\n" ); - return 0; - } - Ntl_ManCollapseBoxSeq2_rec( p, pBox, Vec_IntEntry(p->vBox1Cios, iBox++) ); - } - } - // make sure registers are added correctly - if ( Aig_ManPiNum(p->pAig) - nTruePis != Aig_ManPoNum(p->pAig) - nTruePos ) - { - printf( "Ntl_ManCollapse(): Error: Registers are created incorrectly.\n" ); - return 0; - } - // cleanup the AIG - Aig_ManSetRegNum( p->pAig, Aig_ManPiNum(p->pAig) - nTruePis ); - Aig_ManCleanup( p->pAig ); - pAig = p->pAig; p->pAig = NULL; - return pAig; -} - - -/**Function************************************************************* - - Synopsis [Collapses the netlist combinationally.] - - Description [Checks for combinational loops. Collects PI/PO nets. - Collects nodes in the topological order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Ntl_ManCollapseComb( Ntl_Man_t * p ) -{ - Ntl_Mod_t * pRoot; - Ntl_Obj_t * pObj; - Ntl_Net_t * pNet; - int i, k; - Vec_PtrClear( p->vCis ); - Vec_PtrClear( p->vCos ); - // prepare the model - pRoot = Ntl_ManRootModel(p); - // collect the leaves for this traversal - Ntl_ModelForEachCombLeaf( pRoot, pObj, i ) - Ntl_ObjForEachFanout( pObj, pNet, k ) - Vec_PtrPush( p->vCis, pNet ); - // collect the roots for this traversal - Ntl_ModelForEachCombRoot( pRoot, pObj, i ) - Ntl_ObjForEachFanin( pObj, pNet, k ) - Vec_PtrPush( p->vCos, pNet ); - // perform the traversal - return Ntl_ManCollapse( p, 0 ); -} - -/**Function************************************************************* - - Synopsis [Collapses the netlist combinationally.] - - Description [Checks for combinational loops. Collects PI/PO nets. - Collects nodes in the topological order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Aig_Man_t * Ntl_ManCollapseSeq( Ntl_Man_t * p, int nMinDomSize, int fVerbose ) -{ - Aig_Man_t * pAig; - Ntl_Mod_t * pRoot; - Ntl_Obj_t * pObj; - Ntl_Net_t * pNet; - int i, k; - Vec_PtrClear( p->vCis ); - Vec_PtrClear( p->vCos ); - // prepare the model - pRoot = Ntl_ManRootModel(p); - // collect the leaves for this traversal - Ntl_ModelForEachSeqLeaf( pRoot, pObj, i ) - Ntl_ObjForEachFanout( pObj, pNet, k ) - Vec_PtrPush( p->vCis, pNet ); - // collect the roots for this traversal - Ntl_ModelForEachSeqRoot( pRoot, pObj, i ) - Ntl_ObjForEachFanin( pObj, pNet, k ) - Vec_PtrPush( p->vCos, pNet ); - // perform the traversal - pAig = Ntl_ManCollapse( p, 1 ); - // check if there are register classes - pAig->vClockDoms = Ntl_ManTransformRegClasses( p, nMinDomSize, fVerbose ); - if ( pAig->vClockDoms ) - { - if ( Vec_VecSize(pAig->vClockDoms) == 0 ) - { - printf( "Register classes are below the limit (%d). Seq synthesis is not performed.\n", nMinDomSize ); - Aig_ManStop( pAig ); - pAig = NULL; - } - else if ( fVerbose ) - printf( "Performing seq synthesis for %d register classes.\n", Vec_VecSize(pAig->vClockDoms) ); - if ( fVerbose ) - printf( "\n" ); - } - return pAig; -} - - - -/**Function************************************************************* - - Synopsis [Increments reference counter of the net.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Ntl_NetIncrementRefs( Ntl_Net_t * pNet ) -{ - int nRefs = (int)(long)pNet->pCopy; - pNet->pCopy = (void *)(long)(nRefs + 1); -} - -/**Function************************************************************* - - Synopsis [Extracts logic newtork out of the netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Obj_t * Ntl_ManExtractNwk_rec( Ntl_Man_t * p, Ntl_Net_t * pNet, Nwk_Man_t * pNtk, Vec_Int_t * vCover, Vec_Int_t * vMemory ) -{ - extern Hop_Obj_t * Kit_CoverToHop( Hop_Man_t * pMan, Vec_Int_t * vCover, int nVars, Vec_Int_t * vMemory ); - Ntl_Net_t * pFaninNet; - Nwk_Obj_t * pNode; - int i; - if ( pNet->fMark ) - return (Nwk_Obj_t *)pNet->pCopy2; - pNet->fMark = 1; - pNode = Nwk_ManCreateNode( pNtk, Ntl_ObjFaninNum(pNet->pDriver), (int)(long)pNet->pCopy ); - Ntl_ObjForEachFanin( pNet->pDriver, pFaninNet, i ) - { - Ntl_ManExtractNwk_rec( p, pFaninNet, pNtk, vCover, vMemory ); - Nwk_ObjAddFanin( pNode, (Nwk_Obj_t *)pFaninNet->pCopy2 ); - } - if ( Ntl_ObjFaninNum(pNet->pDriver) == 0 || Kit_PlaGetVarNum(pNet->pDriver->pSop) == 0 ) - pNode->pFunc = Hop_NotCond( Hop_ManConst1(pNtk->pManHop), Kit_PlaIsConst0(pNet->pDriver->pSop) ); - else - { - Kit_PlaToIsop( pNet->pDriver->pSop, vCover ); - pNode->pFunc = Kit_CoverToHop( pNtk->pManHop, vCover, Ntl_ObjFaninNum(pNet->pDriver), vMemory ); - if ( Kit_PlaIsComplement(pNet->pDriver->pSop) ) - pNode->pFunc = Hop_Not(pNode->pFunc); - } - return (Nwk_Obj_t *)(pNet->pCopy2 = pNode); -} - -/**Function************************************************************* - - Synopsis [Extracts logic network out of the netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Man_t * Ntl_ManExtractNwk( Ntl_Man_t * p, Aig_Man_t * pAig, Tim_Man_t * pManTime ) -{ - Nwk_Man_t * pNtk; - Nwk_Obj_t * pNode; - Ntl_Mod_t * pRoot; - Ntl_Net_t * pNet, * pNetSimple; - Ntl_Obj_t * pObj; - Aig_Obj_t * pAnd; - Vec_Int_t * vCover, * vMemory; - int i, k; - pRoot = Ntl_ManRootModel( p ); - if ( Ntl_ModelGetFaninMax(pRoot) > 6 ) - { - printf( "The network contains logic nodes with more than 6 inputs.\n" ); - return NULL; - } - vCover = Vec_IntAlloc( 100 ); - vMemory = Vec_IntAlloc( 1 << 16 ); - // count the number of fanouts of each net - Ntl_ModelClearNets( pRoot ); - Ntl_ModelForEachObj( pRoot, pObj, i ) - Ntl_ObjForEachFanin( pObj, pNet, k ) - Ntl_NetIncrementRefs( pNet ); - // remember netlist objects int the AIG nodes - if ( pManTime != NULL ) // logic netlist - { - assert( Ntl_ModelPiNum(pRoot) == Aig_ManPiNum(pAig) ); - assert( Ntl_ModelPoNum(pRoot) == Aig_ManPoNum(pAig) ); - Aig_ManForEachPi( pAig, pAnd, i ) - pAnd->pData = Ntl_ObjFanout0( Ntl_ModelPi(pRoot, i) ); - Aig_ManForEachPo( pAig, pAnd, i ) - pAnd->pData = Ntl_ObjFanin0(Ntl_ModelPo(pRoot, i) ); - } - else // real netlist - { - assert( p->vCis && p->vCos ); - Aig_ManForEachPi( pAig, pAnd, i ) - pAnd->pData = Vec_PtrEntry( p->vCis, i ); - Aig_ManForEachPo( pAig, pAnd, i ) - pAnd->pData = Vec_PtrEntry( p->vCos, i ); - } - // construct the network - pNtk = Nwk_ManAlloc(); - pNtk->pName = Aig_UtilStrsav( pAig->pName ); - pNtk->pSpec = Aig_UtilStrsav( pAig->pSpec ); - Aig_ManForEachObj( pAig, pAnd, i ) - { - if ( Aig_ObjIsPi(pAnd) ) - { - pNet = (Ntl_Net_t *)pAnd->pData; - pNet->fMark = 1; - pNet->pCopy2 = Nwk_ManCreateCi( pNtk, (int)(long)pNet->pCopy ); - } - else if ( Aig_ObjIsPo(pAnd) ) - { - pNet = (Ntl_Net_t *)pAnd->pData; - pNode = Nwk_ManCreateCo( pNtk ); - if ( (pNetSimple = Ntl_ModelFindSimpleNet( pNet )) ) - { - pNetSimple->pCopy2 = Ntl_ManExtractNwk_rec( p, pNetSimple, pNtk, vCover, vMemory ); - Nwk_ObjAddFanin( pNode, (Nwk_Obj_t *)pNetSimple->pCopy2 ); - pNode->fInvert = Kit_PlaIsInv( pNet->pDriver->pSop ); - } - else - { - pNet->pCopy2 = Ntl_ManExtractNwk_rec( p, pNet, pNtk, vCover, vMemory ); - Nwk_ObjAddFanin( pNode, (Nwk_Obj_t *)pNet->pCopy2 ); - pNode->fInvert = (Nwk_ObjFanin0(pNode)->pFunc == Hop_ManConst0(pNtk->pManHop)); // fixed on June 7, 2009 - } - } - } - Ntl_ModelClearNets( pRoot ); - Vec_IntFree( vCover ); - Vec_IntFree( vMemory ); - // create timing manager from the current design - if ( pManTime ) - pNtk->pManTime = Tim_ManDup( pManTime, 0 ); - else - pNtk->pManTime = Tim_ManDup( p->pManTime, 0 ); - Nwk_ManRemoveDupFanins( pNtk, 0 ); - assert( Nwk_ManCheck( pNtk ) ); - return pNtk; -} - -/**Function************************************************************* - - Synopsis [Extracts logic newtork out of the netlist.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Nwk_Man_t * Ntl_ManReadNwk( char * pFileName, Aig_Man_t * pAig, Tim_Man_t * pManTime ) -{ - Nwk_Man_t * pNtk; - Ntl_Man_t * pNtl; - Ntl_Mod_t * pRoot; - pNtl = Ntl_ManReadBlif( pFileName, 1 ); - if ( pNtl == NULL ) - { - printf( "Ntl_ManReadNwk(): Reading BLIF has failed.\n" ); - return NULL; - } - pRoot = Ntl_ManRootModel( pNtl ); - if ( Ntl_ModelLatchNum(pRoot) != 0 ) - { - printf( "Ntl_ManReadNwk(): The input network has %d registers.\n", Ntl_ModelLatchNum(pRoot) ); - return NULL; - } - if ( Ntl_ModelBoxNum(pRoot) != 0 ) - { - printf( "Ntl_ManReadNwk(): The input network has %d boxes.\n", Ntl_ModelBoxNum(pRoot) ); - return NULL; - } - if ( Ntl_ModelPiNum(pRoot) != Aig_ManPiNum(pAig) ) - { - printf( "Ntl_ManReadNwk(): The number of primary inputs does not match (%d and %d).\n", - Ntl_ModelPiNum(pRoot), Aig_ManPiNum(pAig) ); - return NULL; - } - if ( Ntl_ModelPoNum(pRoot) != Aig_ManPoNum(pAig) ) - { - printf( "Ntl_ManReadNwk(): The number of primary outputs does not match (%d and %d).\n", - Ntl_ModelPoNum(pRoot), Aig_ManPoNum(pAig) ); - return NULL; - } - pNtk = Ntl_ManExtractNwk( pNtl, pAig, pManTime ); - Ntl_ManFree( pNtl ); - return pNtk; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - -ABC_NAMESPACE_IMPL_END - |