/**Function************************************************************* Synopsis [Implementation of retiming.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOnly, int fOneStep, int fVerbose ) { int nLatches = Abc_NtkLatchNum(pNtk); int nLevels = Abc_NtkLevel(pNtk); int RetValue = 0, clkTotal = clock(); int nNodesOld, nLatchesOld; assert( Mode > 0 && Mode < 7 ); assert( !fForwardOnly || !fBackwardOnly ); // cleanup the network nNodesOld = Abc_NtkNodeNum(pNtk); nLatchesOld = Abc_NtkLatchNum(pNtk); Abc_NtkCleanupSeq(pNtk, 0, 0, 0); if ( nNodesOld > Abc_NtkNodeNum(pNtk) || nLatchesOld > Abc_NtkLatchNum(pNtk) ) printf( "Cleanup before retiming removed %d dangling nodes and %d dangling latches.\n", nNodesOld - Abc_NtkNodeNum(pNtk), nLatchesOld - Abc_NtkLatchNum(pNtk) ); // perform retiming switch ( Mode ) { case 1: // forward RetValue = Abc_NtkRetimeIncremental( pNtk, 1, 0, 0, fVerbose ); break; case 2: // backward RetValue = Abc_NtkRetimeIncremental( pNtk, 0, 0, 0, fVerbose ); break; case 3: // min-area RetValue = Abc_NtkRetimeMinArea( pNtk, fForwardOnly, fBackwardOnly, fVerbose ); break; case 4: // min-delay if ( !fBackwardOnly ) RetValue += Abc_NtkRetimeIncremental( pNtk, 1, 1, fOneStep, fVerbose ); if ( !fForwardOnly ) RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, fOneStep, fVerbose ); break; case 5: // min-area + min-delay RetValue = Abc_NtkRetimeMinArea( pNtk, fForwardOnly, fBackwardOnly, fVerbose ); if ( !fBackwardOnly ) RetValue += Abc_NtkRetimeIncremental( pNtk, 1, 1, 0, fVerbose ); if ( !fForwardOnly ) RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, 0, fVerbose ); break; case 6: // Pan's algorithm RetValue = Abc_NtkRetimeLValue( pNtk, 500, fVerbose ); break; default: printf( "Unknown retiming option.\n" ); break; } if ( fVerbose ) { printf( "Reduction in area = %3d. Reduction in delay = %3d. ", nLatches - Abc_NtkLatchNum(pNtk), nLevels - Abc_NtkLevel(pNtk) ); PRT( "Total runtime", clock() - clkTotal ); } timeRetime = clock() - clkTotal; return RetValue; }
/**Function************************************************************* Synopsis [Performs retiming in one direction.] Description [Currently does not retime over black boxes.] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkRetimeIncremental( Abc_Ntk_t * pNtk, int nDelayLim, int fForward, int fMinDelay, int fOneStep, int fVerbose ) { Abc_Ntk_t * pNtkCopy = NULL; Vec_Ptr_t * vBoxes; st__table * tLatches; int nLatches = Abc_NtkLatchNum(pNtk); int nIdMaxStart = Abc_NtkObjNumMax(pNtk); int RetValue; int nIterLimit = -1; // Suppress "might be used uninitialized" if ( Abc_NtkNodeNum(pNtk) == 0 ) return 0; // reorder CI/CO/latch inputs Abc_NtkOrderCisCos( pNtk ); if ( fMinDelay ) { nIterLimit = fOneStep? 1 : 2 * Abc_NtkLevel(pNtk); pNtkCopy = Abc_NtkDup( pNtk ); tLatches = Abc_NtkRetimePrepareLatches( pNtkCopy ); st__free_table( tLatches ); } // collect latches and remove CIs/COs tLatches = Abc_NtkRetimePrepareLatches( pNtk ); // share the latches Abc_NtkRetimeShareLatches( pNtk, 0 ); // save boxes vBoxes = pNtk->vBoxes; pNtk->vBoxes = NULL; // perform the retiming if ( fMinDelay ) Abc_NtkRetimeMinDelay( pNtk, pNtkCopy, nDelayLim, nIterLimit, fForward, fVerbose ); else Abc_NtkRetimeOneWay( pNtk, fForward, fVerbose ); if ( fMinDelay ) Abc_NtkDelete( pNtkCopy ); // share the latches Abc_NtkRetimeShareLatches( pNtk, 0 ); // restore boxes pNtk->vBoxes = vBoxes; // finalize the latches RetValue = Abc_NtkRetimeFinalizeLatches( pNtk, tLatches, nIdMaxStart ); st__free_table( tLatches ); if ( RetValue == 0 ) return 0; // fix the COs // Abc_NtkLogicMakeSimpleCos( pNtk, 0 ); // check for correctness if ( !Abc_NtkCheck( pNtk ) ) fprintf( stdout, "Abc_NtkRetimeForward(): Network check has failed.\n" ); // return the number of latches saved return nLatches - Abc_NtkLatchNum(pNtk); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkBmc( Abc_Ntk_t * pNtk, int nFrames, int fInit, int fVerbose ) { Ivy_FraigParams_t Params, * pParams = &Params; Ivy_Man_t * pMan, * pFrames, * pFraig; Vec_Ptr_t * vMapping; // convert to IVY manager pMan = Abc_NtkIvyBefore( pNtk, 0, 0 ); // generate timeframes pFrames = Ivy_ManFrames( pMan, Abc_NtkLatchNum(pNtk), nFrames, fInit, &vMapping ); // fraig the timeframes Ivy_FraigParamsDefault( pParams ); pParams->nBTLimitNode = ABC_INFINITY; pParams->fVerbose = 0; pParams->fProve = 0; pFraig = Ivy_FraigPerform( pFrames, pParams ); printf( "Frames have %6d nodes. ", Ivy_ManNodeNum(pFrames) ); printf( "Fraig has %6d nodes.\n", Ivy_ManNodeNum(pFraig) ); // report the classes // if ( fVerbose ) // Abc_NtkBmcReport( pMan, pFrames, pFraig, vMapping, nFrames ); // free stuff Vec_PtrFree( vMapping ); Ivy_ManStop( pFraig ); Ivy_ManStop( pFrames ); Ivy_ManStop( pMan ); }
/**Function************************************************************* Synopsis [Computes the transition relation of the network.] Description [Assumes that the global BDDs are computed.] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose ) { DdNode * bRel, * bTemp, * bProd, * bVar, * bInputs; Abc_Obj_t * pNode; int fReorder = 1; int i; // extand the BDD manager to represent NS variables assert( dd->size == Abc_NtkCiNum(pNtk) ); Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + Abc_NtkLatchNum(pNtk) - 1 ); // enable reordering if ( fReorder ) Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT ); else Cudd_AutodynDisable( dd ); // compute the transition relation bRel = b1; Cudd_Ref( bRel ); Abc_NtkForEachLatch( pNtk, pNode, i ) { bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i ); // bProd = Cudd_bddXnor( dd, bVar, pNtk->vFuncsGlob->pArray[i] ); Cudd_Ref( bProd ); bProd = Cudd_bddXnor( dd, bVar, Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) ); Cudd_Ref( bProd ); bRel = Cudd_bddAnd( dd, bTemp = bRel, bProd ); Cudd_Ref( bRel ); Cudd_RecursiveDeref( dd, bTemp ); Cudd_RecursiveDeref( dd, bProd ); }
/**Function************************************************************* Synopsis [Writes the logic network in the equation format.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_WriteEqn( Abc_Ntk_t * pNtk, char * pFileName ) { FILE * pFile; assert( Abc_NtkIsAigNetlist(pNtk) ); if ( Abc_NtkLatchNum(pNtk) > 0 ) printf( "Warning: only combinational portion is being written.\n" ); // check that the names are fine for the EQN format if ( !Io_NtkWriteEqnCheck(pNtk) ) return; // start the output stream pFile = fopen( pFileName, "w" ); if ( pFile == NULL ) { fprintf( stdout, "Io_WriteEqn(): Cannot open the output file \"%s\".\n", pFileName ); return; } fprintf( pFile, "# Equations for \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() ); // write the equations for the network Io_NtkWriteEqnOne( pFile, pNtk ); fprintf( pFile, "\n" ); fclose( pFile ); }
/**Function************************************************************* Synopsis [Interface with the FPGA mapping package.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkFpga( Abc_Ntk_t * pNtk, float DelayTarget, int fRecovery, int fSwitching, int fLatchPaths, int fVerbose ) { int fShowSwitching = 1; Abc_Ntk_t * pNtkNew; Fpga_Man_t * pMan; Vec_Int_t * vSwitching; float * pSwitching = NULL; assert( Abc_NtkIsStrash(pNtk) ); // print a warning about choice nodes if ( Abc_NtkGetChoiceNum( pNtk ) ) printf( "Performing FPGA mapping with choices.\n" ); // compute switching activity fShowSwitching |= fSwitching; if ( fShowSwitching ) { extern Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns ); vSwitching = Sim_NtkComputeSwitching( pNtk, 4096 ); pSwitching = (float *)vSwitching->pArray; } // perform FPGA mapping pMan = Abc_NtkToFpga( pNtk, fRecovery, pSwitching, fLatchPaths, fVerbose ); if ( pSwitching ) Vec_IntFree( vSwitching ); if ( pMan == NULL ) return NULL; Fpga_ManSetSwitching( pMan, fSwitching ); Fpga_ManSetLatchPaths( pMan, fLatchPaths ); Fpga_ManSetLatchNum( pMan, Abc_NtkLatchNum(pNtk) ); Fpga_ManSetDelayTarget( pMan, DelayTarget ); if ( !Fpga_Mapping( pMan ) ) { Fpga_ManFree( pMan ); return NULL; } // transform the result of mapping into a BDD network pNtkNew = Abc_NtkFromFpga( pMan, pNtk ); if ( pNtkNew == NULL ) return NULL; Fpga_ManFree( pMan ); // make the network minimum base Abc_NtkMinimumBase( pNtkNew ); if ( pNtk->pExdc ) pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); // make sure that everything is okay if ( !Abc_NtkCheck( pNtkNew ) ) { printf( "Abc_NtkFpga: The network check has failed.\n" ); Abc_NtkDelete( pNtkNew ); return NULL; } return pNtkNew; }
/**Function************************************************************* Synopsis [Prints statistics about latches.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkPrintLatch( FILE * pFile, Abc_Ntk_t * pNtk ) { Abc_Obj_t * pLatch, * pFanin; int i, Counter0, Counter1, Counter2; int InitNums[4], Init; assert( !Abc_NtkIsNetlist(pNtk) ); if ( Abc_NtkLatchNum(pNtk) == 0 ) { fprintf( pFile, "The network is combinational.\n" ); return; } for ( i = 0; i < 4; i++ ) InitNums[i] = 0; Counter0 = Counter1 = Counter2 = 0; Abc_NtkForEachLatch( pNtk, pLatch, i ) { Init = Abc_LatchInit( pLatch ); assert( Init < 4 ); InitNums[Init]++; pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch)); if ( Abc_NtkIsLogic(pNtk) ) { if ( !Abc_NodeIsConst(pFanin) ) continue; } else if ( Abc_NtkIsStrash(pNtk) ) { if ( !Abc_AigNodeIsConst(pFanin) ) continue; } else assert( 0 ); // the latch input is a constant node Counter0++; if ( Abc_LatchIsInitDc(pLatch) ) { Counter1++; continue; } // count the number of cases when the constant is equal to the initial value if ( Abc_NtkIsStrash(pNtk) ) { if ( Abc_LatchIsInit1(pLatch) == !Abc_ObjFaninC0(pLatch) ) Counter2++; } else { if ( Abc_LatchIsInit1(pLatch) == Abc_NodeIsConst1(pLatch) ) Counter2++; } }
/**Function************************************************************* Synopsis [This procedure also finalizes construction of the ABC network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void ABC_Network_Finalize( ABC_Manager mng ) { Abc_Ntk_t * pNtk = mng->pNtk; Abc_Obj_t * pObj; int i; Abc_NtkForEachPi( pNtk, pObj, i ) Abc_ObjAssignName( pObj, ABC_GetNodeName(mng, pObj), NULL ); Abc_NtkForEachPo( pNtk, pObj, i ) Abc_ObjAssignName( pObj, ABC_GetNodeName(mng, pObj), NULL ); assert( Abc_NtkLatchNum(pNtk) == 0 ); }
/**Function************************************************************* Synopsis [Starts a new network using existing network as a model.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func ) { Abc_Ntk_t * pNtkNew; Abc_Obj_t * pObj; int fCopyNames, i; if ( pNtk == NULL ) return NULL; // decide whether to copy the names fCopyNames = ( Type != ABC_NTK_NETLIST ); // start the network pNtkNew = Abc_NtkAlloc( Type, Func, 1 ); // duplicate the name and the spec pNtkNew->pName = Extra_UtilStrsav(pNtk->pName); pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec); // clean the node copy fields Abc_NtkCleanCopy( pNtk ); // map the constant nodes if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) ) Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew); // clone CIs/CIs/boxes Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); Abc_NtkForEachPo( pNtk, pObj, i ) Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); Abc_NtkForEachAssert( pNtk, pObj, i ) Abc_NtkDupObj( pNtkNew, pObj, fCopyNames ); Abc_NtkForEachBox( pNtk, pObj, i ) Abc_NtkDupBox( pNtkNew, pObj, fCopyNames ); // transfer the names // Abc_NtkTrasferNames( pNtk, pNtkNew ); Abc_ManTimeDup( pNtk, pNtkNew ); // check that the CI/CO/latches are copied correctly assert( Abc_NtkCiNum(pNtk) == Abc_NtkCiNum(pNtkNew) ); assert( Abc_NtkCoNum(pNtk) == Abc_NtkCoNum(pNtkNew) ); assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) ); return pNtkNew; }
/**Function************************************************************* Synopsis [Prepares the IVY package.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Ivy_Man_t * Abc_NtkIvyBefore( Abc_Ntk_t * pNtk, int fSeq, int fUseDc ) { Ivy_Man_t * pMan; int fCleanup = 1; //timeRetime = clock(); assert( !Abc_NtkIsNetlist(pNtk) ); if ( Abc_NtkIsBddLogic(pNtk) ) { if ( !Abc_NtkBddToSop(pNtk, 0) ) { printf( "Abc_NtkIvyBefore(): Converting to SOPs has failed.\n" ); return NULL; } } if ( fSeq && Abc_NtkCountSelfFeedLatches(pNtk) ) { printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtk) ); // return NULL; } // print warning about choice nodes if ( Abc_NtkGetChoiceNum( pNtk ) ) printf( "Warning: The choice nodes in the initial AIG are removed by strashing.\n" ); // convert to the AIG manager pMan = Abc_NtkToIvy( pNtk ); if ( !Ivy_ManCheck( pMan ) ) { printf( "AIG check has failed.\n" ); Ivy_ManStop( pMan ); return NULL; } // Ivy_ManPrintStats( pMan ); if ( fSeq ) { int nLatches = Abc_NtkLatchNum(pNtk); Vec_Int_t * vInit = Abc_NtkCollectLatchValuesIvy( pNtk, fUseDc ); Ivy_ManMakeSeq( pMan, nLatches, vInit->pArray ); Vec_IntFree( vInit ); // Ivy_ManPrintStats( pMan ); } //timeRetime = clock() - timeRetime; return pMan; }
/**Function************************************************************* Synopsis [Prints PIs/POs and LIs/LOs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkPrintIo( FILE * pFile, Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj; int i; fprintf( pFile, "Primary inputs (%d): ", Abc_NtkPiNum(pNtk) ); Abc_NtkForEachPi( pNtk, pObj, i ) fprintf( pFile, " %s", Abc_ObjName(pObj) ); // fprintf( pFile, " %s(%d)", Abc_ObjName(pObj), Abc_ObjFanoutNum(pObj) ); fprintf( pFile, "\n" ); fprintf( pFile, "Primary outputs (%d):", Abc_NtkPoNum(pNtk) ); Abc_NtkForEachPo( pNtk, pObj, i ) fprintf( pFile, " %s", Abc_ObjName(pObj) ); fprintf( pFile, "\n" ); fprintf( pFile, "Latches (%d): ", Abc_NtkLatchNum(pNtk) ); Abc_NtkForEachLatch( pNtk, pObj, i ) fprintf( pFile, " %s(%s=%s)", Abc_ObjName(pObj), Abc_ObjName(Abc_ObjFanout0(pObj)), Abc_ObjName(Abc_ObjFanin0(pObj)) ); fprintf( pFile, "\n" ); }
/**Function************************************************************* Synopsis [Prepares the network for retiming.] Description [Hash latches into their number in the original network.] SideEffects [] SeeAlso [] ***********************************************************************/ st__table * Abc_NtkRetimePrepareLatches( Abc_Ntk_t * pNtk ) { st__table * tLatches; Abc_Obj_t * pLatch, * pLatchIn, * pLatchOut, * pFanin; int i, nOffSet = Abc_NtkBoxNum(pNtk) - Abc_NtkLatchNum(pNtk); // collect latches and remove CIs/COs tLatches = st__init_table( st__ptrcmp, st__ptrhash ); Abc_NtkForEachLatch( pNtk, pLatch, i ) { // map latch into its true number st__insert( tLatches, (char *)(ABC_PTRUINT_T)pLatch, (char *)(ABC_PTRUINT_T)(i-nOffSet) ); // disconnect LI pLatchIn = Abc_ObjFanin0(pLatch); pFanin = Abc_ObjFanin0(pLatchIn); Abc_ObjTransferFanout( pLatchIn, pFanin ); Abc_ObjDeleteFanin( pLatchIn, pFanin ); // disconnect LO pLatchOut = Abc_ObjFanout0(pLatch); pFanin = Abc_ObjFanin0(pLatchOut); if ( Abc_ObjFanoutNum(pLatchOut) > 0 ) Abc_ObjTransferFanout( pLatchOut, pFanin ); Abc_ObjDeleteFanin( pLatchOut, pFanin ); }
Mini_Aig_t * Abc_NtkToMiniAig( Abc_Ntk_t * pNtk ) { Mini_Aig_t * p; Abc_Obj_t * pObj; int i; assert( Abc_NtkIsStrash(pNtk) ); // create the manager p = Mini_AigStart(); // create mapping from MiniAIG into ABC objects Abc_NtkCleanCopy( pNtk ); Abc_AigConst1(pNtk)->iTemp = Mini_AigLitConst1(); // create primary inputs Abc_NtkForEachCi( pNtk, pObj, i ) pObj->iTemp = Mini_AigCreatePi(p); // create internal nodes Abc_NtkForEachNode( pNtk, pObj, i ) pObj->iTemp = Mini_AigAnd( p, Abc_NodeFanin0Copy2(pObj), Abc_NodeFanin1Copy2(pObj) ); // create primary outputs Abc_NtkForEachCo( pNtk, pObj, i ) pObj->iTemp = Mini_AigCreatePo( p, Abc_NodeFanin0Copy2(pObj) ); // set registers Mini_AigSetRegNum( p, Abc_NtkLatchNum(pNtk) ); return p; }
/**Function************************************************************* Synopsis [Print the vital stats of the network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) { int Num; // if ( Abc_NtkIsStrash(pNtk) ) // Abc_AigCountNext( pNtk->pManFunc ); fprintf( pFile, "%-13s:", pNtk->pName ); if ( Abc_NtkAssertNum(pNtk) ) fprintf( pFile, " i/o/a = %4d/%4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk), Abc_NtkAssertNum(pNtk) ); else fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) ); fprintf( pFile, " lat = %4d", Abc_NtkLatchNum(pNtk) ); if ( Abc_NtkIsNetlist(pNtk) ) { fprintf( pFile, " net = %5d", Abc_NtkNetNum(pNtk) ); fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) ); fprintf( pFile, " wbox = %3d", Abc_NtkWhiteboxNum(pNtk) ); fprintf( pFile, " bbox = %3d", Abc_NtkBlackboxNum(pNtk) ); } else if ( Abc_NtkIsStrash(pNtk) ) { fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) ); if ( Num = Abc_NtkGetChoiceNum(pNtk) ) fprintf( pFile, " (choice = %d)", Num ); if ( Num = Abc_NtkGetExorNum(pNtk) ) fprintf( pFile, " (exor = %d)", Num ); // if ( Num2 = Abc_NtkGetMuxNum(pNtk) ) // fprintf( pFile, " (mux = %d)", Num2-Num ); // if ( Num2 ) // fprintf( pFile, " (other = %d)", Abc_NtkNodeNum(pNtk)-3*Num2 ); } else { fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) ); fprintf( pFile, " net = %5d", Abc_NtkGetTotalFanins(pNtk) ); } if ( Abc_NtkIsStrash(pNtk) || Abc_NtkIsNetlist(pNtk) ) { } else if ( Abc_NtkHasSop(pNtk) ) { fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) ); // fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) ); if ( fFactored ) fprintf( pFile, " lit(fac) = %5d", Abc_NtkGetLitFactNum(pNtk) ); } else if ( Abc_NtkHasAig(pNtk) ) fprintf( pFile, " aig = %5d", Abc_NtkGetAigNodeNum(pNtk) ); else if ( Abc_NtkHasBdd(pNtk) ) fprintf( pFile, " bdd = %5d", Abc_NtkGetBddNodeNum(pNtk) ); else if ( Abc_NtkHasMapping(pNtk) ) { fprintf( pFile, " area = %5.2f", Abc_NtkGetMappedArea(pNtk) ); fprintf( pFile, " delay = %5.2f", Abc_NtkDelayTrace(pNtk) ); } else if ( !Abc_NtkHasBlackbox(pNtk) ) { assert( 0 ); } if ( Abc_NtkIsStrash(pNtk) ) fprintf( pFile, " lev = %3d", Abc_AigLevel(pNtk) ); else fprintf( pFile, " lev = %3d", Abc_NtkLevel(pNtk) ); fprintf( pFile, "\n" ); // Abc_NtkCrossCut( pNtk ); // print the statistic into a file /* { FILE * pTable; pTable = fopen( "iscas/seqmap__stats.txt", "a+" ); fprintf( pTable, "%s ", pNtk->pName ); fprintf( pTable, "%d ", Abc_NtkPiNum(pNtk) ); fprintf( pTable, "%d ", Abc_NtkPoNum(pNtk) ); fprintf( pTable, "%d ", Abc_NtkLatchNum(pNtk) ); fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) ); fprintf( pTable, "%d ", Abc_NtkLevel(pNtk) ); fprintf( pTable, "\n" ); fclose( pTable ); } */ /* // print the statistic into a file { FILE * pTable; pTable = fopen( "stats.txt", "a+" ); fprintf( pTable, "%s ", pNtk->pSpec ); fprintf( pTable, "%.0f ", Abc_NtkGetMappedArea(pNtk) ); fprintf( pTable, "%.2f ", Abc_NtkDelayTrace(pNtk) ); fprintf( pTable, "\n" ); fclose( pTable ); } */ /* // print the statistic into a file { FILE * pTable; pTable = fopen( "x/stats_new.txt", "a+" ); fprintf( pTable, "%s ", pNtk->pName ); // fprintf( pTable, "%d ", Abc_NtkPiNum(pNtk) ); // fprintf( pTable, "%d ", Abc_NtkPoNum(pNtk) ); // fprintf( pTable, "%d ", Abc_NtkLevel(pNtk) ); // fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) ); // fprintf( pTable, "%d ", Abc_NtkGetTotalFanins(pNtk) ); // fprintf( pTable, "%d ", Abc_NtkLatchNum(pNtk) ); // fprintf( pTable, "%.2f ", (float)(s_MappingMem)/(float)(1<<20) ); fprintf( pTable, "%.2f", (float)(s_MappingTime)/(float)(CLOCKS_PER_SEC) ); // fprintf( pTable, "%.2f", (float)(s_ResynTime)/(float)(CLOCKS_PER_SEC) ); fprintf( pTable, "\n" ); fclose( pTable ); s_ResynTime = 0; } */ /* // print the statistic into a file { static int Counter = 0; extern int timeRetime; FILE * pTable; Counter++; pTable = fopen( "a/ret__stats.txt", "a+" ); fprintf( pTable, "%s ", pNtk->pName ); fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) ); fprintf( pTable, "%d ", Abc_NtkLatchNum(pNtk) ); fprintf( pTable, "%d ", Abc_NtkLevel(pNtk) ); fprintf( pTable, "%.2f ", (float)(timeRetime)/(float)(CLOCKS_PER_SEC) ); if ( Counter % 4 == 0 ) fprintf( pTable, "\n" ); fclose( pTable ); } */ /* // print the statistic into a file { static int Counter = 0; extern int timeRetime; FILE * pTable; Counter++; pTable = fopen( "d/stats.txt", "a+" ); fprintf( pTable, "%s ", pNtk->pName ); // fprintf( pTable, "%d ", Abc_NtkPiNum(pNtk) ); // fprintf( pTable, "%d ", Abc_NtkPoNum(pNtk) ); // fprintf( pTable, "%d ", Abc_NtkLatchNum(pNtk) ); fprintf( pTable, "%d ", Abc_NtkNodeNum(pNtk) ); fprintf( pTable, "%.2f ", (float)(timeRetime)/(float)(CLOCKS_PER_SEC) ); fprintf( pTable, "\n" ); fclose( pTable ); } */ /* s_TotalNodes += Abc_NtkNodeNum(pNtk); printf( "Total nodes = %6d %6.2f Mb Changes = %6d.\n", s_TotalNodes, s_TotalNodes * 20.0 / (1<<20), s_TotalChanges ); */ }
/**Function************************************************************* Synopsis [Writes the graph structure of network for DOT.] Description [Useful for graph visualization using tools such as GraphViz: http://www.graphviz.org/] SideEffects [] SeeAlso [] ***********************************************************************/ void Io_WriteDotNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesShow, char * pFileName, int fGateNames, int fUseReverse ) { FILE * pFile; Abc_Obj_t * pNode, * pFanin; char * pSopString; int LevelMin, LevelMax, fHasCos, Level, i, k, fHasBdds, fCompl; int Limit = 300; assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsLogic(pNtk) ); if ( vNodes->nSize < 1 ) { printf( "The set has no nodes. DOT file is not written.\n" ); return; } if ( vNodes->nSize > Limit ) { printf( "The set has more than %d nodes. DOT file is not written.\n", Limit ); return; } // start the stream if ( (pFile = fopen( pFileName, "w" )) == NULL ) { fprintf( stdout, "Cannot open the intermediate file \"%s\".\n", pFileName ); return; } // transform logic functions from BDD to SOP if ( fHasBdds = Abc_NtkIsBddLogic(pNtk) ) { if ( !Abc_NtkBddToSop(pNtk, 0) ) { printf( "Io_WriteDotNtk(): Converting to SOPs has failed.\n" ); return; } } // mark the nodes from the set Vec_PtrForEachEntry( vNodes, pNode, i ) pNode->fMarkC = 1; if ( vNodesShow ) Vec_PtrForEachEntry( vNodesShow, pNode, i ) pNode->fMarkB = 1; // get the levels of nodes LevelMax = Abc_NtkLevel( pNtk ); if ( fUseReverse ) { LevelMin = Abc_NtkLevelReverse( pNtk ); assert( LevelMax == LevelMin ); Vec_PtrForEachEntry( vNodes, pNode, i ) if ( Abc_ObjIsNode(pNode) ) pNode->Level = LevelMax - pNode->Level + 1; } // find the largest and the smallest levels LevelMin = 10000; LevelMax = -1; fHasCos = 0; Vec_PtrForEachEntry( vNodes, pNode, i ) { if ( Abc_ObjIsCo(pNode) ) { fHasCos = 1; continue; } if ( LevelMin > (int)pNode->Level ) LevelMin = pNode->Level; if ( LevelMax < (int)pNode->Level ) LevelMax = pNode->Level; } // set the level of the CO nodes if ( fHasCos ) { LevelMax++; Vec_PtrForEachEntry( vNodes, pNode, i ) { if ( Abc_ObjIsCo(pNode) ) pNode->Level = LevelMax; } } // write the DOT header fprintf( pFile, "# %s\n", "Network structure generated by ABC" ); fprintf( pFile, "\n" ); fprintf( pFile, "digraph network {\n" ); fprintf( pFile, "size = \"7.5,10\";\n" ); // fprintf( pFile, "size = \"10,8.5\";\n" ); // fprintf( pFile, "size = \"14,11\";\n" ); // fprintf( pFile, "page = \"8,11\";\n" ); // fprintf( pFile, "ranksep = 0.5;\n" ); // fprintf( pFile, "nodesep = 0.5;\n" ); fprintf( pFile, "center = true;\n" ); // fprintf( pFile, "orientation = landscape;\n" ); // fprintf( pFile, "edge [fontsize = 10];\n" ); // fprintf( pFile, "edge [dir = none];\n" ); fprintf( pFile, "edge [dir = back];\n" ); fprintf( pFile, "\n" ); // labels on the left of the picture fprintf( pFile, "{\n" ); fprintf( pFile, " node [shape = plaintext];\n" ); fprintf( pFile, " edge [style = invis];\n" ); fprintf( pFile, " LevelTitle1 [label=\"\"];\n" ); fprintf( pFile, " LevelTitle2 [label=\"\"];\n" ); // generate node names with labels for ( Level = LevelMax; Level >= LevelMin; Level-- ) { // the visible node name fprintf( pFile, " Level%d", Level ); fprintf( pFile, " [label = " ); // label name fprintf( pFile, "\"" ); fprintf( pFile, "\"" ); fprintf( pFile, "];\n" ); } // genetate the sequence of visible/invisible nodes to mark levels fprintf( pFile, " LevelTitle1 -> LevelTitle2 ->" ); for ( Level = LevelMax; Level >= LevelMin; Level-- ) { // the visible node name fprintf( pFile, " Level%d", Level ); // the connector if ( Level != LevelMin ) fprintf( pFile, " ->" ); else fprintf( pFile, ";" ); } fprintf( pFile, "\n" ); fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); // generate title box on top fprintf( pFile, "{\n" ); fprintf( pFile, " rank = same;\n" ); fprintf( pFile, " LevelTitle1;\n" ); fprintf( pFile, " title1 [shape=plaintext,\n" ); fprintf( pFile, " fontsize=20,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); fprintf( pFile, "%s", "Network structure visualized by ABC" ); fprintf( pFile, "\\n" ); fprintf( pFile, "Benchmark \\\"%s\\\". ", pNtk->pName ); fprintf( pFile, "Time was %s. ", Extra_TimeStamp() ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); // generate statistics box fprintf( pFile, "{\n" ); fprintf( pFile, " rank = same;\n" ); fprintf( pFile, " LevelTitle2;\n" ); fprintf( pFile, " title2 [shape=plaintext,\n" ); fprintf( pFile, " fontsize=18,\n" ); fprintf( pFile, " fontname = \"Times-Roman\",\n" ); fprintf( pFile, " label=\"" ); if ( Abc_NtkObjNum(pNtk) == Vec_PtrSize(vNodes) ) fprintf( pFile, "The network contains %d logic nodes and %d latches.", Abc_NtkNodeNum(pNtk), Abc_NtkLatchNum(pNtk) ); else fprintf( pFile, "The set contains %d logic nodes and spans %d levels.", Abc_NtkCountLogicNodes(vNodes), LevelMax - LevelMin + 1 ); fprintf( pFile, "\\n" ); fprintf( pFile, "\"\n" ); fprintf( pFile, " ];\n" ); fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); // generate the POs if ( fHasCos ) { fprintf( pFile, "{\n" ); fprintf( pFile, " rank = same;\n" ); // the labeling node of this level fprintf( pFile, " Level%d;\n", LevelMax ); // generate the PO nodes Vec_PtrForEachEntry( vNodes, pNode, i ) { if ( !Abc_ObjIsCo(pNode) ) continue; fprintf( pFile, " Node%d [label = \"%s%s\"", pNode->Id, (Abc_ObjIsBi(pNode)? Abc_ObjName(Abc_ObjFanout0(pNode)):Abc_ObjName(pNode)), (Abc_ObjIsBi(pNode)? "_in":"") ); fprintf( pFile, ", shape = %s", (Abc_ObjIsBi(pNode)? "box":"invtriangle") ); if ( pNode->fMarkB ) fprintf( pFile, ", style = filled" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); } // generate nodes of each rank for ( Level = LevelMax - fHasCos; Level >= LevelMin && Level > 0; Level-- ) { fprintf( pFile, "{\n" ); fprintf( pFile, " rank = same;\n" ); // the labeling node of this level fprintf( pFile, " Level%d;\n", Level ); Vec_PtrForEachEntry( vNodes, pNode, i ) { if ( (int)pNode->Level != Level ) continue; if ( Abc_ObjFaninNum(pNode) == 0 ) continue; // fprintf( pFile, " Node%d [label = \"%d\"", pNode->Id, pNode->Id ); if ( Abc_NtkIsStrash(pNtk) ) pSopString = ""; else if ( Abc_NtkHasMapping(pNtk) && fGateNames ) pSopString = Mio_GateReadName(pNode->pData); else if ( Abc_NtkHasMapping(pNtk) ) pSopString = Abc_NtkPrintSop(Mio_GateReadSop(pNode->pData)); else pSopString = Abc_NtkPrintSop(pNode->pData); fprintf( pFile, " Node%d [label = \"%d\\n%s\"", pNode->Id, pNode->Id, pSopString ); fprintf( pFile, ", shape = ellipse" ); if ( pNode->fMarkB ) fprintf( pFile, ", style = filled" ); fprintf( pFile, "];\n" ); } fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); } // generate the PI nodes if any if ( LevelMin == 0 ) { fprintf( pFile, "{\n" ); fprintf( pFile, " rank = same;\n" ); // the labeling node of this level fprintf( pFile, " Level%d;\n", LevelMin ); // generate the PO nodes Vec_PtrForEachEntry( vNodes, pNode, i ) { if ( !Abc_ObjIsCi(pNode) ) { // check if the costant node is present if ( Abc_ObjFaninNum(pNode) == 0 && Abc_ObjFanoutNum(pNode) > 0 ) { fprintf( pFile, " Node%d [label = \"Const%d\"", pNode->Id, Abc_NtkIsStrash(pNode->pNtk) || Abc_NodeIsConst1(pNode) ); fprintf( pFile, ", shape = ellipse" ); if ( pNode->fMarkB ) fprintf( pFile, ", style = filled" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } continue; } fprintf( pFile, " Node%d [label = \"%s\"", pNode->Id, (Abc_ObjIsBo(pNode)? Abc_ObjName(Abc_ObjFanin0(pNode)):Abc_ObjName(pNode)) ); fprintf( pFile, ", shape = %s", (Abc_ObjIsBo(pNode)? "box":"triangle") ); if ( pNode->fMarkB ) fprintf( pFile, ", style = filled" ); fprintf( pFile, ", color = coral, fillcolor = coral" ); fprintf( pFile, "];\n" ); } fprintf( pFile, "}" ); fprintf( pFile, "\n" ); fprintf( pFile, "\n" ); }
/**Function************************************************************* Synopsis [Performs minimum-register retiming.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_FlowRetime_MinReg( Abc_Ntk_t * pNtk, int fVerbose, int fComputeInitState, int fGuaranteeInitState, int fBlockConst, int fForwardOnly, int fBackwardOnly, int nMaxIters, int maxDelay, int fFastButConservative ) { int i; Abc_Obj_t *pObj, *pNext; InitConstraint_t *pData; // create manager pManMR = ALLOC( MinRegMan_t, 1 ); pManMR->pNtk = pNtk; pManMR->fVerbose = fVerbose; pManMR->fComputeInitState = fComputeInitState; pManMR->fGuaranteeInitState = fGuaranteeInitState; pManMR->fBlockConst = fBlockConst; pManMR->fForwardOnly = fForwardOnly; pManMR->fBackwardOnly = fBackwardOnly; pManMR->nMaxIters = nMaxIters; pManMR->maxDelay = maxDelay; pManMR->fComputeInitState = fComputeInitState; pManMR->fConservTimingOnly = fFastButConservative; pManMR->vNodes = Vec_PtrAlloc(100); pManMR->vInitConstraints = Vec_PtrAlloc(2); pManMR->pInitNtk = NULL; pManMR->pInitToOrig = NULL; pManMR->sizeInitToOrig = 0; vprintf("Flow-based minimum-register retiming...\n"); if (!Abc_NtkHasOnlyLatchBoxes(pNtk)) { printf("\tERROR: Can not retime with black/white boxes\n"); return pNtk; } if (maxDelay) { vprintf("\tmax delay constraint = %d\n", maxDelay); if (maxDelay < (i = Abc_NtkLevel(pNtk))) { printf("ERROR: max delay constraint (%d) must be > current max delay (%d)\n", maxDelay, i); return pNtk; } } // print info about type of network vprintf("\tnetlist type = "); if (Abc_NtkIsNetlist( pNtk )) { vprintf("netlist/"); } else if (Abc_NtkIsLogic( pNtk )) { vprintf("logic/"); } else if (Abc_NtkIsStrash( pNtk )) { vprintf("strash/"); } else { vprintf("***unknown***/"); } if (Abc_NtkHasSop( pNtk )) { vprintf("sop\n"); } else if (Abc_NtkHasBdd( pNtk )) { vprintf("bdd\n"); } else if (Abc_NtkHasAig( pNtk )) { vprintf("aig\n"); } else if (Abc_NtkHasMapping( pNtk )) { vprintf("mapped\n"); } else { vprintf("***unknown***\n"); } vprintf("\tinitial reg count = %d\n", Abc_NtkLatchNum(pNtk)); vprintf("\tinitial levels = %d\n", Abc_NtkLevel(pNtk)); // remove bubbles from latch boxes if (pManMR->fVerbose) Abc_FlowRetime_PrintInitStateInfo(pNtk); vprintf("\tpushing bubbles out of latch boxes\n"); Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_FlowRetime_RemoveLatchBubbles(pObj); if (pManMR->fVerbose) Abc_FlowRetime_PrintInitStateInfo(pNtk); // check for box inputs/outputs Abc_NtkForEachLatch( pNtk, pObj, i ) { assert(Abc_ObjFaninNum(pObj) == 1); assert(Abc_ObjFanoutNum(pObj) == 1); assert(!Abc_ObjFaninC0(pObj)); pNext = Abc_ObjFanin0(pObj); assert(Abc_ObjIsBi(pNext)); assert(Abc_ObjFaninNum(pNext) <= 1); if(Abc_ObjFaninNum(pNext) == 0) // every Bi should have a fanin Abc_FlowRetime_AddDummyFanin( pNext ); pNext = Abc_ObjFanout0(pObj); assert(Abc_ObjIsBo(pNext)); assert(Abc_ObjFaninNum(pNext) == 1); assert(!Abc_ObjFaninC0(pNext)); }
assert(Abc_ObjFanoutNum(pObj) == 1); assert(!Abc_ObjFaninC0(pObj)); pNext = Abc_ObjFanin0(pObj); assert(Abc_ObjIsBi(pNext)); assert(Abc_ObjFaninNum(pNext) <= 1); if(Abc_ObjFaninNum(pNext) == 0) // every Bi should have a fanin Abc_FlowRetime_AddDummyFanin( pNext ); pNext = Abc_ObjFanout0(pObj); assert(Abc_ObjIsBo(pNext)); assert(Abc_ObjFaninNum(pNext) == 1); assert(!Abc_ObjFaninC0(pNext)); } pManMR->nLatches = Abc_NtkLatchNum( pNtk ); pManMR->nNodes = Abc_NtkObjNumMax( pNtk )+1; // build histogram pManMR->vSinkDistHist = Vec_IntStart( pManMR->nNodes*2+10 ); // initialize timing if (maxDelay) Abc_FlowRetime_InitTiming( pNtk ); // create lag and Flow_Data structure pManMR->vLags = Vec_IntStart(pManMR->nNodes); memset(pManMR->vLags->pArray, 0, sizeof(int)*pManMR->nNodes); pManMR->pDataArray = ALLOC( Flow_Data_t, pManMR->nNodes ); Abc_FlowRetime_ClearFlows( 1 );
} // count the number of cases when the constant is equal to the initial value if ( Abc_NtkIsStrash(pNtk) ) { if ( Abc_LatchIsInit1(pLatch) == !Abc_ObjFaninC0(pLatch) ) Counter2++; } else { if ( Abc_LatchIsInit1(pLatch) == Abc_NodeIsConst1(pLatch) ) Counter2++; } } fprintf( pFile, "%-15s: ", pNtk->pName ); fprintf( pFile, "Latch = %6d. No = %4d. Zero = %4d. One = %4d. DC = %4d.\n", Abc_NtkLatchNum(pNtk), InitNums[0], InitNums[1], InitNums[2], InitNums[3] ); fprintf( pFile, "Const fanin = %3d. DC init = %3d. Matching init = %3d. ", Counter0, Counter1, Counter2 ); fprintf( pFile, "Self-feed latches = %2d.\n", Abc_NtkCountSelfFeedLatches(pNtk) ); } /**Function************************************************************* Synopsis [Prints the distribution of fanins/fanouts in the network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/
/**Function************************************************************* Synopsis [Load the network into manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, float * pSwitching, int fVerbose ) { Map_Man_t * pMan; Map_Node_t * pNodeMap; Vec_Ptr_t * vNodes; Abc_Obj_t * pNode, * pFanin, * pPrev; int i; assert( Abc_NtkIsStrash(pNtk) ); // start the mapping manager and set its parameters pMan = Map_ManCreate( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) - pNtk->nBarBufs, Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) - pNtk->nBarBufs, fVerbose ); if ( pMan == NULL ) return NULL; Map_ManSetAreaRecovery( pMan, fRecovery ); Map_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) ); Map_ManSetDelayTarget( pMan, (float)DelayTarget ); Map_ManSetInputArrivals( pMan, Abc_NtkMapCopyCiArrival(pNtk, Abc_NtkGetCiArrivalTimes(pNtk)) ); Map_ManSetOutputRequireds( pMan, Abc_NtkMapCopyCoRequired(pNtk, Abc_NtkGetCoRequiredTimes(pNtk)) ); // create PIs and remember them in the old nodes Abc_NtkCleanCopy( pNtk ); Abc_AigConst1(pNtk)->pCopy = (Abc_Obj_t *)Map_ManReadConst1(pMan); Abc_NtkForEachCi( pNtk, pNode, i ) { if ( i == Abc_NtkCiNum(pNtk) - pNtk->nBarBufs ) break; pNodeMap = Map_ManReadInputs(pMan)[i]; pNode->pCopy = (Abc_Obj_t *)pNodeMap; if ( pSwitching ) Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] ); } // load the AIG into the mapper vNodes = Abc_AigDfsMap( pNtk ); Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i ) { if ( Abc_ObjIsLatch(pNode) ) { pFanin = Abc_ObjFanin0(pNode); pNodeMap = Map_NodeBuf( pMan, Map_NotCond( Abc_ObjFanin0(pFanin)->pCopy, (int)Abc_ObjFaninC0(pFanin) ) ); Abc_ObjFanout0(pNode)->pCopy = (Abc_Obj_t *)pNodeMap; continue; } assert( Abc_ObjIsNode(pNode) ); // add the node to the mapper pNodeMap = Map_NodeAnd( pMan, Map_NotCond( Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) ), Map_NotCond( Abc_ObjFanin1(pNode)->pCopy, (int)Abc_ObjFaninC1(pNode) ) ); assert( pNode->pCopy == NULL ); // remember the node pNode->pCopy = (Abc_Obj_t *)pNodeMap; if ( pSwitching ) Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] ); // set up the choice node if ( Abc_AigNodeIsChoice( pNode ) ) for ( pPrev = pNode, pFanin = (Abc_Obj_t *)pNode->pData; pFanin; pPrev = pFanin, pFanin = (Abc_Obj_t *)pFanin->pData ) { Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy ); Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy ); } } assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs ); Vec_PtrFree( vNodes ); // set the primary outputs in the required phase Abc_NtkForEachCo( pNtk, pNode, i ) { if ( i == Abc_NtkCoNum(pNtk) - pNtk->nBarBufs ) break; Map_ManReadOutputs(pMan)[i] = Map_NotCond( (Map_Node_t *)Abc_ObjFanin0(pNode)->pCopy, (int)Abc_ObjFaninC0(pNode) ); } return pMan; }
/**Function************************************************************* Synopsis [Attempts to solve the miter using an internal SAT sat_solver.] Description [Returns -1 if timed out; 0 if SAT; 1 if UNSAT.] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects ) { sat_solver * pSat; lbool status; int RetValue; clock_t clk; if ( pNumConfs ) *pNumConfs = 0; if ( pNumInspects ) *pNumInspects = 0; assert( Abc_NtkLatchNum(pNtk) == 0 ); // if ( Abc_NtkPoNum(pNtk) > 1 ) // fprintf( stdout, "Warning: The miter has %d outputs. SAT will try to prove all of them.\n", Abc_NtkPoNum(pNtk) ); // load clauses into the sat_solver clk = clock(); pSat = (sat_solver *)Abc_NtkMiterSatCreate( pNtk, 0 ); if ( pSat == NULL ) return 1; //printf( "%d \n", pSat->clauses.size ); //sat_solver_delete( pSat ); //return 1; // printf( "Created SAT problem with %d variable and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) ); // ABC_PRT( "Time", clock() - clk ); // simplify the problem clk = clock(); status = sat_solver_simplify(pSat); // printf( "Simplified the problem to %d variables and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) ); // ABC_PRT( "Time", clock() - clk ); if ( status == 0 ) { sat_solver_delete( pSat ); // printf( "The problem is UNSATISFIABLE after simplification.\n" ); return 1; } // solve the miter clk = clock(); if ( fVerbose ) pSat->verbosity = 1; status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)nInsLimit, (ABC_INT64_T)0, (ABC_INT64_T)0 ); if ( status == l_Undef ) { // printf( "The problem timed out.\n" ); RetValue = -1; } else if ( status == l_True ) { // printf( "The problem is SATISFIABLE.\n" ); RetValue = 0; } else if ( status == l_False ) { // printf( "The problem is UNSATISFIABLE.\n" ); RetValue = 1; } else assert( 0 ); // ABC_PRT( "SAT sat_solver time", clock() - clk ); // printf( "The number of conflicts = %d.\n", (int)pSat->sat_solver_stats.conflicts ); // if the problem is SAT, get the counterexample if ( status == l_True ) { // Vec_Int_t * vCiIds = Abc_NtkGetCiIds( pNtk ); Vec_Int_t * vCiIds = Abc_NtkGetCiSatVarNums( pNtk ); pNtk->pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize ); Vec_IntFree( vCiIds ); } // free the sat_solver if ( fVerbose ) Sat_SolverPrintStats( stdout, pSat ); if ( pNumConfs ) *pNumConfs = (int)pSat->stats.conflicts; if ( pNumInspects ) *pNumInspects = (int)pSat->stats.inspects; sat_solver_store_write( pSat, "trace.cnf" ); sat_solver_store_free( pSat ); sat_solver_delete( pSat ); return RetValue; }
/**Function************************************************************* Synopsis [Checks the integrity of the network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj, * pNet, * pNode; int i; // check network types if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) ) { fprintf( stdout, "NetworkCheck: Unknown network type.\n" ); return 0; } if ( !Abc_NtkHasSop(pNtk) && !Abc_NtkHasBdd(pNtk) && !Abc_NtkHasAig(pNtk) && !Abc_NtkHasMapping(pNtk) && !Abc_NtkHasBlifMv(pNtk) && !Abc_NtkHasBlackbox(pNtk) ) { fprintf( stdout, "NetworkCheck: Unknown functionality type.\n" ); return 0; } if ( Abc_NtkHasMapping(pNtk) ) { if ( pNtk->pManFunc != Abc_FrameReadLibGen() ) { fprintf( stdout, "NetworkCheck: The library of the mapped network is not the global library.\n" ); return 0; } } if ( Abc_NtkHasOnlyLatchBoxes(pNtk) ) { // check CI/CO numbers if ( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) != Abc_NtkCiNum(pNtk) ) { fprintf( stdout, "NetworkCheck: Number of CIs does not match number of PIs and latches.\n" ); fprintf( stdout, "One possible reason is that latches are added twice:\n" ); fprintf( stdout, "in procedure Abc_NtkCreateObj() and in the user's code.\n" ); return 0; } if ( Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) != Abc_NtkCoNum(pNtk) ) { fprintf( stdout, "NetworkCheck: Number of COs does not match number of POs, asserts, and latches.\n" ); fprintf( stdout, "One possible reason is that latches are added twice:\n" ); fprintf( stdout, "in procedure Abc_NtkCreateObj() and in the user's code.\n" ); return 0; } } // check the names if ( !Abc_NtkCheckNames( pNtk ) ) return 0; // check PIs and POs Abc_NtkCleanCopy( pNtk ); if ( !Abc_NtkCheckPis( pNtk ) ) return 0; if ( !Abc_NtkCheckPos( pNtk ) ) return 0; if ( Abc_NtkHasBlackbox(pNtk) ) return 1; // check the connectivity of objects Abc_NtkForEachObj( pNtk, pObj, i ) if ( !Abc_NtkCheckObj( pNtk, pObj ) ) return 0; // if it is a netlist change nets and latches if ( Abc_NtkIsNetlist(pNtk) ) { if ( Abc_NtkNetNum(pNtk) == 0 ) fprintf( stdout, "NetworkCheck: Warning! Netlist has no nets.\n" ); // check the nets Abc_NtkForEachNet( pNtk, pNet, i ) if ( !Abc_NtkCheckNet( pNtk, pNet ) ) return 0; } else { if ( Abc_NtkNetNum(pNtk) != 0 )