/**Function************************************************************* Synopsis [Prints out the statistics of the manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Dar_ManRefPrintStats( Ref_Man_t * p ) { int Gain = p->nNodesInit - Aig_ManNodeNum(p->pAig); printf( "NodesBeg = %8d. NodesEnd = %8d. Gain = %6d. (%6.2f %%).\n", p->nNodesInit, Aig_ManNodeNum(p->pAig), Gain, 100.0*Gain/p->nNodesInit ); printf( "Tried = %6d. Below = %5d. Extended = %5d. Used = %5d. Levels = %4d.\n", p->nNodesTried, p->nNodesBelow, p->nNodesExten, p->nCutsUsed, Aig_ManLevels(p->pAig) ); ABC_PRT( "Cuts ", p->timeCuts ); ABC_PRT( "Eval ", p->timeEval ); ABC_PRT( "Other ", p->timeOther ); ABC_PRT( "TOTAL ", p->timeTotal ); }
/**Function************************************************************* Synopsis [Prints the manager statisticis.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Sim_ManPrintStats( Sim_Man_t * p ) { // printf( "Inputs = %5d. Outputs = %5d. Sim words = %5d.\n", // Abc_NtkCiNum(p->pNtk), Abc_NtkCoNum(p->pNtk), p->nSimWords ); printf( "Total func supps = %8d.\n", Sim_UtilCountSuppSizes(p, 0) ); printf( "Total struct supps = %8d.\n", Sim_UtilCountSuppSizes(p, 1) ); printf( "Sat runs SAT = %8d.\n", p->nSatRunsSat ); printf( "Sat runs UNSAT = %8d.\n", p->nSatRunsUnsat ); ABC_PRT( "Simulation ", p->timeSim ); ABC_PRT( "Traversal ", p->timeTrav ); ABC_PRT( "Fraiging ", p->timeFraig ); ABC_PRT( "SAT ", p->timeSat ); ABC_PRT( "TOTAL ", p->timeTotal ); }
/**Function************************************************************* Synopsis [Computes initial values of the new latches.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Abc_NtkRetimeInitialValues( Abc_Ntk_t * pNtkCone, Vec_Int_t * vValues, int fVerbose ) { Vec_Int_t * vSolution; Abc_Ntk_t * pNtkMiter, * pNtkLogic; int RetValue; abctime clk; if ( pNtkCone == NULL ) return Vec_IntDup( vValues ); // convert the target network to AIG pNtkLogic = Abc_NtkDup( pNtkCone ); Abc_NtkToAig( pNtkLogic ); // get the miter pNtkMiter = Abc_NtkCreateTarget( pNtkLogic, pNtkLogic->vCos, vValues ); if ( fVerbose ) printf( "The miter for initial state computation has %d AIG nodes. ", Abc_NtkNodeNum(pNtkMiter) ); // solve the miter clk = Abc_Clock(); RetValue = Abc_NtkMiterSat( pNtkMiter, (ABC_INT64_T)500000, (ABC_INT64_T)50000000, 0, NULL, NULL ); if ( fVerbose ) { ABC_PRT( "SAT solving time", Abc_Clock() - clk ); } // analyze the result if ( RetValue == 1 ) printf( "Abc_NtkRetimeInitialValues(): The problem is unsatisfiable. DC latch values are used.\n" ); else if ( RetValue == -1 ) printf( "Abc_NtkRetimeInitialValues(): The SAT problem timed out. DC latch values are used.\n" ); else if ( !Abc_NtkRetimeVerifyModel( pNtkCone, vValues, pNtkMiter->pModel ) ) printf( "Abc_NtkRetimeInitialValues(): The computed counter-example is incorrect.\n" ); // set the values of the latches vSolution = RetValue? NULL : Vec_IntAllocArray( pNtkMiter->pModel, Abc_NtkPiNum(pNtkLogic) ); pNtkMiter->pModel = NULL; Abc_NtkDelete( pNtkMiter ); Abc_NtkDelete( pNtkLogic ); return vSolution; }
/**Function************************************************************* Synopsis [Reproduces script "compress2".] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fConstruct, int nConfMax, int nLevelMax, int fVerbose ) { Aig_Man_t * pMan, * pTemp; Vec_Ptr_t * vAigs; int i; abctime clk; clk = Abc_Clock(); // vAigs = Dar_ManChoiceSynthesisExt(); vAigs = Dar_ManChoiceSynthesis( pAig, fBalance, fUpdateLevel, 0, fVerbose ); // swap the first and last network // this should lead to the primary choice being "better" because of synthesis // (it is also important when constructing choices) if ( !fConstruct ) { pMan = (Aig_Man_t *)Vec_PtrPop( vAigs ); Vec_PtrPush( vAigs, Vec_PtrEntry(vAigs,0) ); Vec_PtrWriteEntry( vAigs, 0, pMan ); } if ( fVerbose ) { ABC_PRT( "Synthesis time", Abc_Clock() - clk ); } clk = Abc_Clock(); if ( fConstruct ) pMan = Aig_ManChoiceConstructive( vAigs, fVerbose ); else pMan = Aig_ManChoicePartitioned( vAigs, 300, nConfMax, nLevelMax, fVerbose ); Vec_PtrForEachEntry( Aig_Man_t *, vAigs, pTemp, i ) Aig_ManStop( pTemp ); Vec_PtrFree( vAigs ); if ( fVerbose ) { ABC_PRT( "Choicing time ", Abc_Clock() - clk ); } return pMan; // return NULL; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fra_ManPartitionTest( Aig_Man_t * p, int nComLim ) { // Bar_Progress_t * pProgress; Vec_Vec_t * vSupps, * vSuppsIn; Vec_Ptr_t * vSuppsNew; Vec_Int_t * vSupNew, * vSup, * vSup2, * vTemp;//, * vSupIn; Vec_Int_t * vOverNew, * vQuantNew; Aig_Obj_t * pObj; int i, k, nCommon, CountOver, CountQuant; int nTotalSupp, nTotalSupp2, Entry, Largest;//, iVar; double Ratio, R; clock_t clk; nTotalSupp = 0; nTotalSupp2 = 0; Ratio = 0.0; // compute supports clk = clock(); vSupps = (Vec_Vec_t *)Aig_ManSupports( p ); ABC_PRT( "Supports", clock() - clk ); // remove last entry Aig_ManForEachCo( p, pObj, i ) { vSup = Vec_VecEntryInt( vSupps, i ); Vec_IntPop( vSup ); // remember support // pObj->pNext = (Aig_Obj_t *)vSup; }
/**Fnction************************************************************* Synopsis [Constructs AIG in ABC from the manager.] Description [The ABC network is started, as well as the array vCopy, which will map the new ID of each object in the BBLIF manager into the ponter ot the corresponding AIG object in the ABC. For each internal node in a topological oder the AIG representation is created by factoring the SOP representation of the BBLIF object. Finally, the CO objects are created, and the dummy names are assigned because ABC requires each CI/CO to have a name.] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Bbl_ManToAig( Bbl_Man_t * p ) { extern int Bbl_ManFncSize( Bbl_Man_t * p ); extern int Bbl_ObjFncHandle( Bbl_Obj_t * p ); extern Abc_Obj_t * Dec_GraphToAig( Abc_Ntk_t * pNtk, Dec_Graph_t * pFForm, Vec_Ptr_t * vFaninAigs ); int fVerbose = 0; Abc_Ntk_t * pNtk; Abc_Obj_t * pObjNew; Bbl_Obj_t * pObj, * pFanin; Vec_Ptr_t * vCopy, * vNodes, * vFaninAigs; Dec_Graph_t ** pFForms; int i; clock_t clk; clk = clock(); // map SOP handles into factored forms pFForms = ABC_CALLOC( Dec_Graph_t *, Bbl_ManFncSize(p) ); Bbl_ManForEachObj( p, pObj ) if ( pFForms[Bbl_ObjFncHandle(pObj)] == NULL ) pFForms[Bbl_ObjFncHandle(pObj)] = Dec_Factor( Bbl_ObjSop(p, pObj) ); if ( fVerbose ) ABC_PRT( "Fct", clock() - clk ); // start the network pNtk = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); pNtk->pName = Extra_UtilStrsav( Bbl_ManName(p) ); vCopy = Vec_PtrStart( 1000 ); // create CIs Bbl_ManForEachObj( p, pObj ) { if ( !Bbl_ObjIsInput(pObj) ) continue; Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), Abc_NtkCreatePi(pNtk) ); } clk = clock(); // create internal nodes vNodes = Bbl_ManDfs( p ); vFaninAigs = Vec_PtrAlloc( 100 ); Vec_PtrForEachEntry( Bbl_Obj_t *, vNodes, pObj, i ) { // collect fanin AIGs Vec_PtrClear( vFaninAigs ); Bbl_ObjForEachFanin( pObj, pFanin ) Vec_PtrPush( vFaninAigs, Vec_PtrEntry( vCopy, Bbl_ObjId(pFanin) ) ); // create the new node pObjNew = Dec_GraphToAig( pNtk, pFForms[Bbl_ObjFncHandle(pObj)], vFaninAigs ); Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), pObjNew ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Cnf_Dat_t * Cnf_Derive_old( Aig_Man_t * pAig ) { /* // iteratively improve area flow for ( i = 0; i < nIters; i++ ) { clk = Abc_Clock(); Cnf_ManScanMapping( p, 0 ); Cnf_ManMapForCnf( p ); ABC_PRT( "iter ", Abc_Clock() - clk ); } */ // write the file vMapped = Aig_ManScanMapping( p, 1 ); Vec_PtrFree( vMapped ); clk = Abc_Clock(); Cnf_ManTransferCuts( p ); Cnf_ManPostprocess( p ); Cnf_ManScanMapping( p, 0 ); /* Cnf_ManPostprocess( p ); Cnf_ManScanMapping( p, 0 ); Cnf_ManPostprocess( p ); Cnf_ManScanMapping( p, 0 ); */ ABC_PRT( "Ext ", Abc_Clock() - clk ); /* vMapped = Cnf_ManScanMapping( p, 1 ); pCnf = Cnf_ManWriteCnf( p, vMapped ); Vec_PtrFree( vMapped ); // clean up Cnf_ManFreeCuts( p ); Dar_ManCutsFree( pAig ); return pCnf; */ Aig_MmFixedStop( pMemCuts, 0 ); return NULL; }
/**Function************************************************************* Synopsis [Prints the manager statisticis.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Sym_ManPrintStats( Sym_Man_t * p ) { // printf( "Inputs = %5d. Outputs = %5d. Sim words = %5d.\n", // Abc_NtkCiNum(p->pNtk), Abc_NtkCoNum(p->pNtk), p->nSimWords ); printf( "Total symm = %8d.\n", p->nPairsSymm ); printf( "Structural symm = %8d.\n", p->nPairsSymmStr ); printf( "Total non-sym = %8d.\n", p->nPairsNonSymm ); printf( "Total var pairs = %8d.\n", p->nPairsTotal ); printf( "Sat runs SAT = %8d.\n", p->nSatRunsSat ); printf( "Sat runs UNSAT = %8d.\n", p->nSatRunsUnsat ); ABC_PRT( "Structural ", p->timeStruct ); ABC_PRT( "Simulation ", p->timeSim ); ABC_PRT( "Matrix ", p->timeMatr ); ABC_PRT( "Counting ", p->timeCount ); ABC_PRT( "Fraiging ", p->timeFraig ); ABC_PRT( "SAT ", p->timeSat ); ABC_PRT( "TOTAL ", p->timeTotal ); }
/**Function************************************************************* Synopsis [Performs technology mapping for the given object graph.] Description [The object graph is stored in the mapping manager. First, all the AND-nodes, which fanout into the POs, are collected in the DFS fashion. Next, three steps are performed: the k-feasible cuts are computed for each node, the truth tables are computed for each cut, and the delay-optimal matches are assigned for each node.] SideEffects [] SeeAlso [] ***********************************************************************/ int Fpga_Mapping( Fpga_Man_t * p ) { int clk, clkTotal = clock(); // collect the nodes reachable from POs in the DFS order (including the choices) p->vAnds = Fpga_MappingDfs( p, 1 ); Fpga_ManReportChoices( p ); // recomputes levels Fpga_MappingSetChoiceLevels( p ); // compute the cuts of nodes in the DFS order clk = clock(); Fpga_MappingCuts( p ); p->timeCuts = clock() - clk; // match the truth tables to the supergates clk = clock(); if ( !Fpga_MappingMatches( p, 1 ) ) return 0; p->timeMatch = clock() - clk; // perform area recovery clk = clock(); if ( !Fpga_MappingPostProcess( p ) ) return 0; p->timeRecover = clock() - clk; //ABC_PRT( "Total mapping time", clock() - clkTotal ); s_MappingTime = clock() - clkTotal; s_MappingMem = Fpga_CutCountAll(p) * (sizeof(Fpga_Cut_t) - sizeof(int) * (FPGA_MAX_LEAVES - p->nVarsMax)); // print the AI-graph used for mapping //Fpga_ManShow( p, "test" ); // if ( p->fVerbose ) // Fpga_MappingPrintOutputArrivals( p ); if ( p->fVerbose ) { ABC_PRT( "Total time", clock() - clkTotal ); } return 1; }
/**Function************************************************************* Synopsis [Precomputes the library of AND2 gates.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Super2_Precompute( int nInputs, int nLevels, int fVerbose ) { Super2_Man_t * pMan; Super2_Lib_t * pLibCur, * pLibNext; int Level; int clk; assert( nInputs < 6 ); // start the manager pMan = Super2_ManStart(); // get the starting supergates pLibCur = Super2_LibFirst( pMan, nInputs ); // perform the computation of supergates printf( "Computing supergates for %d inputs and %d levels:\n", nInputs, nLevels ); for ( Level = 1; Level <= nLevels; Level++ ) { clk = clock(); pLibNext = Super2_LibCompute( pMan, pLibCur ); pLibNext->nLevels = Level; Super2_LibStop( pLibCur ); pLibCur = pLibNext; printf( "Level %d: Tried = %7d. Computed = %7d. ", Level, pMan->nTried, pLibCur->nGates ); ABC_PRT( "Runtime", clock() - clk ); fflush( stdout ); } printf( "Writing the output file...\n" ); fflush( stdout ); // write them into a file Super2_LibWrite( pLibCur ); Super2_LibStop( pLibCur ); // stop the manager Super2_ManStop( pMan ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ManInterTest( Aig_Man_t * pMan, int fVerbose ) { sat_solver2 * pSat; // Aig_Man_t * pInter; word * pInter; Vec_Int_t * vVars; Cnf_Dat_t * pCnf; Aig_Obj_t * pObj; int Lit, Cid, Var, status, i; clock_t clk = clock(); assert( Aig_ManRegNum(pMan) == 0 ); assert( Aig_ManCoNum(pMan) == 1 ); // derive CNFs pCnf = Cnf_Derive( pMan, 1 ); // start the solver pSat = sat_solver2_new(); sat_solver2_setnvars( pSat, 2*pCnf->nVars+1 ); // set A-variables (all used except PI/PO) Aig_ManForEachObj( pMan, pObj, i ) { if ( pCnf->pVarNums[pObj->Id] < 0 ) continue; if ( !Aig_ObjIsCi(pObj) && !Aig_ObjIsCo(pObj) ) var_set_partA( pSat, pCnf->pVarNums[pObj->Id], 1 ); } // add clauses of A for ( i = 0; i < pCnf->nClauses; i++ ) { Cid = sat_solver2_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1], 0 ); clause2_set_partA( pSat, Cid, 1 ); } // add clauses of B Cnf_DataLift( pCnf, pCnf->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) sat_solver2_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1], 0 ); Cnf_DataLift( pCnf, -pCnf->nVars ); // add PI equality clauses vVars = Vec_IntAlloc( Aig_ManCoNum(pMan)+1 ); Aig_ManForEachCi( pMan, pObj, i ) { if ( Aig_ObjRefs(pObj) == 0 ) continue; Var = pCnf->pVarNums[pObj->Id]; Aig_ManInterAddBuffer( pSat, Var, pCnf->nVars + Var, 0, 0 ); Vec_IntPush( vVars, Var ); } // add an XOR clause in the end Var = pCnf->pVarNums[Aig_ManCo(pMan,0)->Id]; Aig_ManInterAddXor( pSat, Var, pCnf->nVars + Var, 2*pCnf->nVars, 0, 0 ); Vec_IntPush( vVars, Var ); // solve the problem Lit = toLitCond( 2*pCnf->nVars, 0 ); status = sat_solver2_solve( pSat, &Lit, &Lit + 1, 0, 0, 0, 0 ); assert( status == l_False ); Sat_Solver2PrintStats( stdout, pSat ); // derive interpolant // pInter = Sat_ProofInterpolant( pSat, vVars ); // Aig_ManPrintStats( pInter ); // Aig_ManDumpBlif( pInter, "int.blif", NULL, NULL ); //pInter = Sat_ProofInterpolantTruth( pSat, vVars ); pInter = NULL; // Extra_PrintHex( stdout, pInter, Vec_IntSize(vVars) ); printf( "\n" ); // clean up // Aig_ManStop( pInter ); ABC_FREE( pInter ); Vec_IntFree( vVars ); Cnf_DataFree( pCnf ); sat_solver2_delete( pSat ); ABC_PRT( "Total interpolation time", clock() - clk ); }
/**Function************************************************************* Synopsis [Run the SAT solver on the unrolled instance.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose ) { int nConfLimit = 1000000; Abc_Cex_t * pCtrex = NULL; Aig_Man_t * pFrames; sat_solver * pSat; Cnf_Dat_t * pCnf; int status; clock_t clk = clock(); Vec_Int_t * vCiIds; // create timeframes assert( Saig_ManPoNum(pAig) == 1 ); pFrames = Inter_ManFramesBmc( pAig, nFrames ); // derive CNF pCnf = Cnf_Derive( pFrames, 0 ); Cnf_DataTranformPolarity( pCnf, 0 ); vCiIds = Cnf_DataCollectPiSatNums( pCnf, pFrames ); Aig_ManStop( pFrames ); // convert into SAT solver pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Cnf_DataFree( pCnf ); if ( pSat == NULL ) { printf( "Counter-example generation in command \"int\" has failed.\n" ); printf( "Use command \"bmc2\" to produce a valid counter-example.\n" ); Vec_IntFree( vCiIds ); return NULL; } // simplify the problem status = sat_solver_simplify(pSat); if ( status == 0 ) { Vec_IntFree( vCiIds ); sat_solver_delete( pSat ); return NULL; } // solve the miter status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); // if the problem is SAT, get the counterexample if ( status == l_True ) { int i, * pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize ); pCtrex = Abc_CexAlloc( Saig_ManRegNum(pAig), Saig_ManPiNum(pAig), nFrames ); pCtrex->iFrame = nFrames - 1; pCtrex->iPo = 0; for ( i = 0; i < Vec_IntSize(vCiIds); i++ ) if ( pModel[i] ) Abc_InfoSetBit( pCtrex->pData, Saig_ManRegNum(pAig) + i ); ABC_FREE( pModel ); } // free the sat_solver sat_solver_delete( pSat ); Vec_IntFree( vCiIds ); // verify counter-example status = Saig_ManVerifyCex( pAig, pCtrex ); if ( status == 0 ) printf( "Inter_ManGetCounterExample(): Counter-example verification has FAILED.\n" ); // report the results if ( fVerbose ) { ABC_PRT( "Total ctrex generation time", clock() - clk ); } return pCtrex; }
/**Function************************************************************* Synopsis [Interface with the mapping package.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, double AreaMulti, double DelayMulti, float LogFan, float Slew, float Gain, int nGatesMin, int fRecovery, int fSwitching, int fSkipFanout, int fVerbose ) { static int fUseMulti = 0; int fShowSwitching = 1; Abc_Ntk_t * pNtkNew; Map_Man_t * pMan; Vec_Int_t * vSwitching = NULL; float * pSwitching = NULL; abctime clk, clkTotal = Abc_Clock(); Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen(); assert( Abc_NtkIsStrash(pNtk) ); // derive library from SCL // if the library is created here, it will be deleted when pSuperLib is deleted in Map_SuperLibFree() if ( Abc_FrameReadLibScl() && Abc_SclHasDelayInfo( Abc_FrameReadLibScl() ) ) { pLib = Abc_SclDeriveGenlib( Abc_FrameReadLibScl(), Slew, Gain, nGatesMin, fVerbose ); if ( Abc_FrameReadLibGen() ) Mio_LibraryTransferDelays( (Mio_Library_t *)Abc_FrameReadLibGen(), pLib ); // remove supergate library Map_SuperLibFree( (Map_SuperLib_t *)Abc_FrameReadLibSuper() ); Abc_FrameSetLibSuper( NULL ); } // quit if there is no library if ( pLib == NULL ) { printf( "The current library is not available.\n" ); return 0; } if ( AreaMulti != 0.0 ) fUseMulti = 1, printf( "The cell areas are multiplied by the factor: <num_fanins> ^ (%.2f).\n", AreaMulti ); if ( DelayMulti != 0.0 ) fUseMulti = 1, printf( "The cell delays are multiplied by the factor: <num_fanins> ^ (%.2f).\n", DelayMulti ); // penalize large gates by increasing their area if ( AreaMulti != 0.0 ) Mio_LibraryMultiArea( pLib, AreaMulti ); if ( DelayMulti != 0.0 ) Mio_LibraryMultiDelay( pLib, DelayMulti ); // derive the supergate library if ( fUseMulti || Abc_FrameReadLibSuper() == NULL ) { if ( fVerbose ) printf( "Converting \"%s\" into supergate library \"%s\".\n", Mio_LibraryReadName(pLib), Extra_FileNameGenericAppend(Mio_LibraryReadName(pLib), ".super") ); // compute supergate library to be used for mapping Map_SuperLibDeriveFromGenlib( pLib, fVerbose ); } // return the library to normal if ( AreaMulti != 0.0 ) Mio_LibraryMultiArea( (Mio_Library_t *)Abc_FrameReadLibGen(), -AreaMulti ); if ( DelayMulti != 0.0 ) Mio_LibraryMultiDelay( (Mio_Library_t *)Abc_FrameReadLibGen(), -DelayMulti ); // print a warning about choice nodes if ( fVerbose && Abc_NtkGetChoiceNum( pNtk ) ) printf( "Performing 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 the mapping pMan = Abc_NtkToMap( pNtk, DelayTarget, fRecovery, pSwitching, fVerbose ); if ( pSwitching ) Vec_IntFree( vSwitching ); if ( pMan == NULL ) return NULL; clk = Abc_Clock(); Map_ManSetSwitching( pMan, fSwitching ); Map_ManSetSkipFanout( pMan, fSkipFanout ); if ( LogFan != 0 ) Map_ManCreateNodeDelays( pMan, LogFan ); if ( !Map_Mapping( pMan ) ) { Map_ManFree( pMan ); return NULL; } // Map_ManPrintStatsToFile( pNtk->pSpec, Map_ManReadAreaFinal(pMan), Map_ManReadRequiredGlo(pMan), Abc_Clock()-clk ); // reconstruct the network after mapping pNtkNew = Abc_NtkFromMap( pMan, pNtk ); Map_ManFree( pMan ); if ( pNtkNew == NULL ) return NULL; if ( pNtk->pExdc ) pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc ); if ( fVerbose ) { ABC_PRT( "Total runtime", Abc_Clock() - clkTotal ); } // make sure that everything is okay if ( !Abc_NtkCheck( pNtkNew ) ) { printf( "Abc_NtkMap: The network check has failed.\n" ); Abc_NtkDelete( pNtkNew ); return NULL; } return pNtkNew; }
/**Function************************************************************* Synopsis [Interplates while the number of conflicts is not exceeded.] Description [Returns 1 if proven. 0 if failed. -1 if undecided.] SideEffects [Does not check the property in 0-th frame.] SeeAlso [] ***********************************************************************/ int Inter_ManPerformInterpolation( Aig_Man_t * pAig, Inter_ManParams_t * pPars, int * piFrame ) { extern int Inter_ManCheckInductiveContainment( Aig_Man_t * pTrans, Aig_Man_t * pInter, int nSteps, int fBackward ); Inter_Man_t * p; Inter_Check_t * pCheck = NULL; Aig_Man_t * pAigTemp; int s, i, RetValue, Status; abctime clk, clk2, clkTotal = Abc_Clock(), timeTemp = 0; abctime nTimeNewOut = pPars->nSecLimit ? pPars->nSecLimit * CLOCKS_PER_SEC + Abc_Clock() : 0; // enable ORing of the interpolants, if containment check is performed inductively with K > 1 if ( pPars->nFramesK > 1 ) pPars->fTransLoop = 1; // sanity checks assert( Saig_ManRegNum(pAig) > 0 ); assert( Saig_ManPiNum(pAig) > 0 ); assert( Saig_ManPoNum(pAig)-Saig_ManConstrNum(pAig) == 1 ); if ( pPars->fVerbose && Saig_ManConstrNum(pAig) ) printf( "Performing interpolation with %d constraints...\n", Saig_ManConstrNum(pAig) ); if ( Inter_ManCheckInitialState(pAig) ) { *piFrame = -1; printf( "Property trivially fails in the initial state.\n" ); return 0; } /* if ( Inter_ManCheckAllStates(pAig) ) { printf( "Property trivially holds in all states.\n" ); return 1; } */ // create interpolation manager // can perform SAT sweeping and/or rewriting of this AIG... p = Inter_ManCreate( pAig, pPars ); if ( pPars->fTransLoop ) p->pAigTrans = Inter_ManStartOneOutput( pAig, 0 ); else p->pAigTrans = Inter_ManStartDuplicated( pAig ); // derive CNF for the transformed AIG clk = Abc_Clock(); p->pCnfAig = Cnf_Derive( p->pAigTrans, Aig_ManRegNum(p->pAigTrans) ); p->timeCnf += Abc_Clock() - clk; if ( pPars->fVerbose ) { printf( "AIG: PI/PO/Reg = %d/%d/%d. And = %d. Lev = %d. CNF: Var/Cla = %d/%d.\n", Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig), Aig_ManAndNum(pAig), Aig_ManLevelNum(pAig), p->pCnfAig->nVars, p->pCnfAig->nClauses ); } // derive interpolant *piFrame = -1; p->nFrames = 1; for ( s = 0; ; s++ ) { Cnf_Dat_t * pCnfInter2; clk2 = Abc_Clock(); // initial state if ( pPars->fUseBackward ) p->pInter = Inter_ManStartOneOutput( pAig, 1 ); else p->pInter = Inter_ManStartInitState( Aig_ManRegNum(pAig) ); assert( Aig_ManCoNum(p->pInter) == 1 ); clk = Abc_Clock(); p->pCnfInter = Cnf_Derive( p->pInter, 0 ); p->timeCnf += Abc_Clock() - clk; // timeframes p->pFrames = Inter_ManFramesInter( pAig, p->nFrames, pPars->fUseBackward, pPars->fUseTwoFrames ); clk = Abc_Clock(); if ( pPars->fRewrite ) { p->pFrames = Dar_ManRwsat( pAigTemp = p->pFrames, 1, 0 ); Aig_ManStop( pAigTemp ); // p->pFrames = Fra_FraigEquivence( pAigTemp = p->pFrames, 100, 0 ); // Aig_ManStop( pAigTemp ); } p->timeRwr += Abc_Clock() - clk; // can also do SAT sweeping on the timeframes... clk = Abc_Clock(); if ( pPars->fUseBackward ) p->pCnfFrames = Cnf_Derive( p->pFrames, Aig_ManCoNum(p->pFrames) ); else // p->pCnfFrames = Cnf_Derive( p->pFrames, 0 ); p->pCnfFrames = Cnf_DeriveSimple( p->pFrames, 0 ); p->timeCnf += Abc_Clock() - clk; // report statistics if ( pPars->fVerbose ) { printf( "Step = %2d. Frames = 1 + %d. And = %5d. Lev = %5d. ", s+1, p->nFrames, Aig_ManNodeNum(p->pFrames), Aig_ManLevelNum(p->pFrames) ); ABC_PRT( "Time", Abc_Clock() - clk2 ); } ////////////////////////////////////////// // start containment checking if ( !(pPars->fTransLoop || pPars->fUseBackward || pPars->nFramesK > 1) ) { pCheck = Inter_CheckStart( p->pAigTrans, pPars->nFramesK ); // try new containment check for the initial state clk = Abc_Clock(); pCnfInter2 = Cnf_Derive( p->pInter, 1 ); p->timeCnf += Abc_Clock() - clk; clk = Abc_Clock(); RetValue = Inter_CheckPerform( pCheck, pCnfInter2, nTimeNewOut ); p->timeEqu += Abc_Clock() - clk; // assert( RetValue == 0 ); Cnf_DataFree( pCnfInter2 ); if ( p->vInters ) Vec_PtrPush( p->vInters, Aig_ManDupSimple(p->pInter) ); } ////////////////////////////////////////// // iterate the interpolation procedure for ( i = 0; ; i++ ) { if ( pPars->nFramesMax && p->nFrames + i >= pPars->nFramesMax ) { if ( pPars->fVerbose ) printf( "Reached limit (%d) on the number of timeframes.\n", pPars->nFramesMax ); p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 0 ); Inter_CheckStop( pCheck ); return -1; } // perform interpolation clk = Abc_Clock(); #ifdef ABC_USE_LIBRARIES if ( pPars->fUseMiniSat ) { assert( !pPars->fUseBackward ); RetValue = Inter_ManPerformOneStepM114p( p, pPars->fUsePudlak, pPars->fUseOther ); } else #endif RetValue = Inter_ManPerformOneStep( p, pPars->fUseBias, pPars->fUseBackward, nTimeNewOut ); if ( pPars->fVerbose ) { printf( " I = %2d. Bmc =%3d. IntAnd =%6d. IntLev =%5d. Conf =%6d. ", i+1, i + 1 + p->nFrames, Aig_ManNodeNum(p->pInter), Aig_ManLevelNum(p->pInter), p->nConfCur ); ABC_PRT( "Time", Abc_Clock() - clk ); } // remember the number of timeframes completed pPars->iFrameMax = i - 1 + p->nFrames; if ( RetValue == 0 ) // found a (spurious?) counter-example { if ( i == 0 ) // real counterexample { if ( pPars->fVerbose ) printf( "Found a real counterexample in frame %d.\n", p->nFrames ); p->timeTotal = Abc_Clock() - clkTotal; *piFrame = p->nFrames; // pAig->pSeqModel = (Abc_Cex_t *)Inter_ManGetCounterExample( pAig, p->nFrames+1, pPars->fVerbose ); { int RetValue; Saig_ParBmc_t ParsBmc, * pParsBmc = &ParsBmc; Saig_ParBmcSetDefaultParams( pParsBmc ); pParsBmc->nConfLimit = 100000000; pParsBmc->nStart = p->nFrames; pParsBmc->fVerbose = pPars->fVerbose; RetValue = Saig_ManBmcScalable( pAig, pParsBmc ); if ( RetValue == 1 ) printf( "Error: The problem should be SAT but it is UNSAT.\n" ); else if ( RetValue == -1 ) printf( "Error: The problem timed out.\n" ); } Inter_ManStop( p, 0 ); Inter_CheckStop( pCheck ); return 0; } // likely spurious counter-example p->nFrames += i; Inter_ManClean( p ); break; } else if ( RetValue == -1 ) { if ( pPars->nSecLimit && Abc_Clock() > nTimeNewOut ) // timed out { if ( pPars->fVerbose ) printf( "Reached timeout (%d seconds).\n", pPars->nSecLimit ); } else { assert( p->nConfCur >= p->nConfLimit ); if ( pPars->fVerbose ) printf( "Reached limit (%d) on the number of conflicts.\n", p->nConfLimit ); } p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 0 ); Inter_CheckStop( pCheck ); return -1; } assert( RetValue == 1 ); // found new interpolant // compress the interpolant clk = Abc_Clock(); if ( p->pInterNew ) { // save the timeout value p->pInterNew->Time2Quit = nTimeNewOut; // Ioa_WriteAiger( p->pInterNew, "interpol.aig", 0, 0 ); p->pInterNew = Dar_ManRwsat( pAigTemp = p->pInterNew, 1, 0 ); // p->pInterNew = Dar_ManRwsat( pAigTemp = p->pInterNew, 0, 0 ); Aig_ManStop( pAigTemp ); if ( p->pInterNew == NULL ) { printf( "Reached timeout (%d seconds) during rewriting.\n", pPars->nSecLimit ); p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 1 ); Inter_CheckStop( pCheck ); return -1; } } p->timeRwr += Abc_Clock() - clk; // check if interpolant is trivial if ( p->pInterNew == NULL || Aig_ObjChild0(Aig_ManCo(p->pInterNew,0)) == Aig_ManConst0(p->pInterNew) ) { // printf( "interpolant is constant 0\n" ); if ( pPars->fVerbose ) printf( "The problem is trivially true for all states.\n" ); p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 1 ); Inter_CheckStop( pCheck ); return 1; } // check containment of interpolants clk = Abc_Clock(); if ( pPars->fCheckKstep ) // k-step unique-state induction { if ( Aig_ManCiNum(p->pInterNew) == Aig_ManCiNum(p->pInter) ) { if ( pPars->fTransLoop || pPars->fUseBackward || pPars->nFramesK > 1 ) { clk2 = Abc_Clock(); Status = Inter_ManCheckInductiveContainment( p->pAigTrans, p->pInterNew, Abc_MinInt(i + 1, pPars->nFramesK), pPars->fUseBackward ); timeTemp = Abc_Clock() - clk2; } else { // new containment check clk2 = Abc_Clock(); pCnfInter2 = Cnf_Derive( p->pInterNew, 1 ); p->timeCnf += Abc_Clock() - clk2; timeTemp = Abc_Clock() - clk2; Status = Inter_CheckPerform( pCheck, pCnfInter2, nTimeNewOut ); Cnf_DataFree( pCnfInter2 ); if ( p->vInters ) Vec_PtrPush( p->vInters, Aig_ManDupSimple(p->pInterNew) ); } } else Status = 0; } else // combinational containment { if ( Aig_ManCiNum(p->pInterNew) == Aig_ManCiNum(p->pInter) ) Status = Inter_ManCheckContainment( p->pInterNew, p->pInter ); else Status = 0; } p->timeEqu += Abc_Clock() - clk - timeTemp; if ( Status ) // contained { if ( pPars->fVerbose ) printf( "Proved containment of interpolants.\n" ); p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 1 ); Inter_CheckStop( pCheck ); return 1; } if ( pPars->nSecLimit && Abc_Clock() > nTimeNewOut ) { printf( "Reached timeout (%d seconds).\n", pPars->nSecLimit ); p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 1 ); Inter_CheckStop( pCheck ); return -1; } // save interpolant and convert it into CNF if ( pPars->fTransLoop ) { Aig_ManStop( p->pInter ); p->pInter = p->pInterNew; } else { if ( pPars->fUseBackward ) { p->pInter = Aig_ManCreateMiter( pAigTemp = p->pInter, p->pInterNew, 2 ); Aig_ManStop( pAigTemp ); Aig_ManStop( p->pInterNew ); // compress the interpolant clk = Abc_Clock(); p->pInter = Dar_ManRwsat( pAigTemp = p->pInter, 1, 0 ); Aig_ManStop( pAigTemp ); p->timeRwr += Abc_Clock() - clk; } else // forward with the new containment checking (using only the frontier) { Aig_ManStop( p->pInter ); p->pInter = p->pInterNew; } } p->pInterNew = NULL; Cnf_DataFree( p->pCnfInter ); clk = Abc_Clock(); p->pCnfInter = Cnf_Derive( p->pInter, 0 ); p->timeCnf += Abc_Clock() - clk; } // start containment checking Inter_CheckStop( pCheck ); } assert( 0 ); return RetValue; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Reads in the supergate library and prepares it for use.] Description [The supergates library comes in a .super file. This file contains descriptions of supergates along with some relevant information. This procedure reads the supergate file, canonicizes the supergates, and constructs an additional lookup table, which can be used to map truth tables of the cuts into the pair (phase, supergate). The phase indicates how the current truth table should be phase assigned to match the canonical form of the supergate. The resulting phase is the bitwise EXOR of the phase needed to canonicize the supergate and the phase needed to transform the truth table into its canonical form.] SideEffects [] SeeAlso [] ***********************************************************************/ Map_SuperLib_t * Map_SuperLibCreate( char * pFileName, char * pExcludeFile, int fAlgorithm, int fVerbose ) { Map_SuperLib_t * p; clock_t clk; // start the supergate library p = ABC_ALLOC( Map_SuperLib_t, 1 ); memset( p, 0, sizeof(Map_SuperLib_t) ); p->pName = pFileName; p->fVerbose = fVerbose; p->mmSupers = Extra_MmFixedStart( sizeof(Map_Super_t) ); p->mmEntries = Extra_MmFixedStart( sizeof(Map_HashEntry_t) ); p->mmForms = Extra_MmFlexStart(); Map_MappingSetupTruthTables( p->uTruths ); // start the hash table p->tTableC = Map_SuperTableCreate( p ); p->tTable = Map_SuperTableCreate( p ); // read the supergate library from file clk = clock(); if ( fAlgorithm ) { if ( !Map_LibraryReadTree( p, pFileName, pExcludeFile ) ) { Map_SuperLibFree( p ); return NULL; } } else { if ( pExcludeFile != 0 ) { Map_SuperLibFree( p ); printf ("Error: Exclude file support not present for old format. Stop.\n"); return NULL; } if ( !Map_LibraryRead( p, pFileName ) ) { Map_SuperLibFree( p ); return NULL; } } assert( p->nVarsMax > 0 ); // report the stats if ( fVerbose ) { printf( "Loaded %d unique %d-input supergates from \"%s\". ", p->nSupersReal, p->nVarsMax, pFileName ); ABC_PRT( "Time", clock() - clk ); } // assign the interver parameters p->pGateInv = Mio_LibraryReadInv( p->pGenlib ); p->tDelayInv.Rise = Mio_LibraryReadDelayInvRise( p->pGenlib ); p->tDelayInv.Fall = Mio_LibraryReadDelayInvFall( p->pGenlib ); p->tDelayInv.Worst = MAP_MAX( p->tDelayInv.Rise, p->tDelayInv.Fall ); p->AreaInv = Mio_LibraryReadAreaInv( p->pGenlib ); p->AreaBuf = Mio_LibraryReadAreaBuf( p->pGenlib ); // assign the interver supergate p->pSuperInv = (Map_Super_t *)Extra_MmFixedEntryFetch( p->mmSupers ); memset( p->pSuperInv, 0, sizeof(Map_Super_t) ); p->pSuperInv->Num = -1; p->pSuperInv->nGates = 1; p->pSuperInv->nFanins = 1; p->pSuperInv->nFanLimit = 10; p->pSuperInv->pFanins[0] = p->ppSupers[0]; p->pSuperInv->pRoot = p->pGateInv; p->pSuperInv->Area = p->AreaInv; p->pSuperInv->tDelayMax = p->tDelayInv; p->pSuperInv->tDelaysR[0].Rise = MAP_NO_VAR; p->pSuperInv->tDelaysR[0].Fall = p->tDelayInv.Rise; p->pSuperInv->tDelaysF[0].Rise = p->tDelayInv.Fall; p->pSuperInv->tDelaysF[0].Fall = MAP_NO_VAR; return p; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_FraigSec( Aig_Man_t * p, Fra_Sec_t * pParSec, Aig_Man_t ** ppResult ) { Ssw_Pars_t Pars2, * pPars2 = &Pars2; Fra_Ssw_t Pars, * pPars = &Pars; Fra_Sml_t * pSml; Aig_Man_t * pNew, * pTemp; int nFrames, RetValue, nIter; abctime clk, clkTotal = Abc_Clock(); int TimeOut = 0; int fLatchCorr = 0; float TimeLeft = 0.0; pParSec->nSMnumber = -1; // try the miter before solving pNew = Aig_ManDupSimple( p ); RetValue = Fra_FraigMiterStatus( pNew ); if ( RetValue >= 0 ) goto finish; // prepare parameters memset( pPars, 0, sizeof(Fra_Ssw_t) ); pPars->fLatchCorr = fLatchCorr; pPars->fVerbose = pParSec->fVeryVerbose; if ( pParSec->fVerbose ) { printf( "Original miter: Latches = %5d. Nodes = %6d.\n", Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); } //Aig_ManDumpBlif( pNew, "after.blif", NULL, NULL ); // perform sequential cleanup clk = Abc_Clock(); if ( pNew->nRegs ) pNew = Aig_ManReduceLaches( pNew, 0 ); if ( pNew->nRegs ) pNew = Aig_ManConstReduce( pNew, 0, -1, -1, 0, 0 ); if ( pParSec->fVerbose ) { printf( "Sequential cleanup: Latches = %5d. Nodes = %6d. ", Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); ABC_PRT( "Time", Abc_Clock() - clk ); } RetValue = Fra_FraigMiterStatus( pNew ); if ( RetValue >= 0 ) goto finish; // perform phase abstraction clk = Abc_Clock(); if ( pParSec->fPhaseAbstract ) { extern Aig_Man_t * Saig_ManPhaseAbstractAuto( Aig_Man_t * p, int fVerbose ); pNew->nTruePis = Aig_ManCiNum(pNew) - Aig_ManRegNum(pNew); pNew->nTruePos = Aig_ManCoNum(pNew) - Aig_ManRegNum(pNew); pNew = Saig_ManPhaseAbstractAuto( pTemp = pNew, 0 ); Aig_ManStop( pTemp ); if ( pParSec->fVerbose ) { printf( "Phase abstraction: Latches = %5d. Nodes = %6d. ", Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); ABC_PRT( "Time", Abc_Clock() - clk ); } } // perform forward retiming if ( pParSec->fRetimeFirst && pNew->nRegs ) { clk = Abc_Clock(); // pNew = Rtm_ManRetime( pTemp = pNew, 1, 1000, 0 ); pNew = Saig_ManRetimeForward( pTemp = pNew, 100, 0 ); Aig_ManStop( pTemp ); if ( pParSec->fVerbose ) { printf( "Forward retiming: Latches = %5d. Nodes = %6d. ", Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); ABC_PRT( "Time", Abc_Clock() - clk ); } } // run latch correspondence clk = Abc_Clock(); if ( pNew->nRegs ) { pNew = Aig_ManDupOrdered( pTemp = pNew ); // pNew = Aig_ManDupDfs( pTemp = pNew ); Aig_ManStop( pTemp ); /* if ( RetValue == -1 && pParSec->TimeLimit ) { TimeLeft = (float)pParSec->TimeLimit - ((float)(Abc_Clock()-clkTotal)/(float)(CLOCKS_PER_SEC)); TimeLeft = Abc_MaxInt( TimeLeft, 0.0 ); if ( TimeLeft == 0.0 ) { if ( !pParSec->fSilent ) printf( "Runtime limit exceeded.\n" ); RetValue = -1; TimeOut = 1; goto finish; } } */ // pNew = Fra_FraigLatchCorrespondence( pTemp = pNew, 0, 1000, 1, pParSec->fVeryVerbose, &nIter, TimeLeft ); //Aig_ManDumpBlif( pNew, "ex.blif", NULL, NULL ); Ssw_ManSetDefaultParamsLcorr( pPars2 ); pNew = Ssw_LatchCorrespondence( pTemp = pNew, pPars2 ); nIter = pPars2->nIters; // prepare parameters for scorr Ssw_ManSetDefaultParams( pPars2 ); if ( pTemp->pSeqModel ) { if ( !Saig_ManVerifyCex( pTemp, pTemp->pSeqModel ) ) printf( "Fra_FraigSec(): Counter-example verification has FAILED.\n" ); if ( Saig_ManPiNum(p) != Saig_ManPiNum(pTemp) ) printf( "The counter-example is invalid because of phase abstraction.\n" ); else { ABC_FREE( p->pSeqModel ); p->pSeqModel = Abc_CexDup( pTemp->pSeqModel, Aig_ManRegNum(p) ); ABC_FREE( pTemp->pSeqModel ); } } if ( pNew == NULL ) { if ( p->pSeqModel ) { RetValue = 0; if ( !pParSec->fSilent ) { printf( "Networks are NOT EQUIVALENT after simulation. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( pParSec->fReportSolution && !pParSec->fRecursive ) { printf( "SOLUTION: FAIL " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } Aig_ManStop( pTemp ); return RetValue; } pNew = pTemp; RetValue = -1; TimeOut = 1; goto finish; } Aig_ManStop( pTemp ); if ( pParSec->fVerbose ) { printf( "Latch-corr (I=%3d): Latches = %5d. Nodes = %6d. ", nIter, Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); ABC_PRT( "Time", Abc_Clock() - clk ); } } /* if ( RetValue == -1 && pParSec->TimeLimit ) { TimeLeft = (float)pParSec->TimeLimit - ((float)(Abc_Clock()-clkTotal)/(float)(CLOCKS_PER_SEC)); TimeLeft = Abc_MaxInt( TimeLeft, 0.0 ); if ( TimeLeft == 0.0 ) { if ( !pParSec->fSilent ) printf( "Runtime limit exceeded.\n" ); RetValue = -1; TimeOut = 1; goto finish; } } */ // perform fraiging if ( pParSec->fFraiging ) { clk = Abc_Clock(); pNew = Fra_FraigEquivence( pTemp = pNew, 100, 0 ); Aig_ManStop( pTemp ); if ( pParSec->fVerbose ) { printf( "Fraiging: Latches = %5d. Nodes = %6d. ", Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); ABC_PRT( "Time", Abc_Clock() - clk ); } } if ( pNew->nRegs == 0 ) RetValue = Fra_FraigCec( &pNew, 100000, 0 ); RetValue = Fra_FraigMiterStatus( pNew ); if ( RetValue >= 0 ) goto finish; /* if ( RetValue == -1 && pParSec->TimeLimit ) { TimeLeft = (float)pParSec->TimeLimit - ((float)(Abc_Clock()-clkTotal)/(float)(CLOCKS_PER_SEC)); TimeLeft = Abc_MaxInt( TimeLeft, 0.0 ); if ( TimeLeft == 0.0 ) { if ( !pParSec->fSilent ) printf( "Runtime limit exceeded.\n" ); RetValue = -1; TimeOut = 1; goto finish; } } */ // perform min-area retiming if ( pParSec->fRetimeRegs && pNew->nRegs ) { // extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ); clk = Abc_Clock(); pNew->nTruePis = Aig_ManCiNum(pNew) - Aig_ManRegNum(pNew); pNew->nTruePos = Aig_ManCoNum(pNew) - Aig_ManRegNum(pNew); // pNew = Rtm_ManRetime( pTemp = pNew, 1, 1000, 0 ); pNew = Saig_ManRetimeMinArea( pTemp = pNew, 1000, 0, 0, 1, 0 ); Aig_ManStop( pTemp ); pNew = Aig_ManDupOrdered( pTemp = pNew ); Aig_ManStop( pTemp ); if ( pParSec->fVerbose ) { printf( "Min-reg retiming: Latches = %5d. Nodes = %6d. ", Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); ABC_PRT( "Time", Abc_Clock() - clk ); } } // perform seq sweeping while increasing the number of frames RetValue = Fra_FraigMiterStatus( pNew ); if ( RetValue == -1 && pParSec->fInduction ) for ( nFrames = 1; nFrames <= pParSec->nFramesMax; nFrames *= 2 ) { /* if ( RetValue == -1 && pParSec->TimeLimit ) { TimeLeft = (float)pParSec->TimeLimit - ((float)(Abc_Clock()-clkTotal)/(float)(CLOCKS_PER_SEC)); TimeLeft = Abc_MaxInt( TimeLeft, 0.0 ); if ( TimeLeft == 0.0 ) { if ( !pParSec->fSilent ) printf( "Runtime limit exceeded.\n" ); RetValue = -1; TimeOut = 1; goto finish; } } */ clk = Abc_Clock(); pPars->nFramesK = nFrames; pPars->TimeLimit = TimeLeft; pPars->fSilent = pParSec->fSilent; // pNew = Fra_FraigInduction( pTemp = pNew, pPars ); pPars2->nFramesK = nFrames; pPars2->nBTLimit = pParSec->nBTLimit; pPars2->nBTLimitGlobal = pParSec->nBTLimitGlobal; // pPars2->nBTLimit = 1000 * nFrames; if ( RetValue == -1 && pPars2->nConflicts > pPars2->nBTLimitGlobal ) { if ( !pParSec->fSilent ) printf( "Global conflict limit (%d) exceeded.\n", pPars2->nBTLimitGlobal ); RetValue = -1; TimeOut = 1; goto finish; } Aig_ManSetRegNum( pNew, pNew->nRegs ); // pNew = Ssw_SignalCorrespondence( pTemp = pNew, pPars2 ); if ( Aig_ManRegNum(pNew) > 0 ) pNew = Ssw_SignalCorrespondence( pTemp = pNew, pPars2 ); else pNew = Aig_ManDupSimpleDfs( pTemp = pNew ); if ( pNew == NULL ) { pNew = pTemp; RetValue = -1; TimeOut = 1; goto finish; } // printf( "Total conflicts = %d.\n", pPars2->nConflicts ); Aig_ManStop( pTemp ); RetValue = Fra_FraigMiterStatus( pNew ); if ( pParSec->fVerbose ) { printf( "K-step (K=%2d,I=%3d): Latches = %5d. Nodes = %6d. ", nFrames, pPars2->nIters, Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); ABC_PRT( "Time", Abc_Clock() - clk ); } if ( RetValue != -1 ) break; // perform retiming // if ( pParSec->fRetimeFirst && pNew->nRegs ) if ( pNew->nRegs ) { // extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ); clk = Abc_Clock(); pNew->nTruePis = Aig_ManCiNum(pNew) - Aig_ManRegNum(pNew); pNew->nTruePos = Aig_ManCoNum(pNew) - Aig_ManRegNum(pNew); // pNew = Rtm_ManRetime( pTemp = pNew, 1, 1000, 0 ); pNew = Saig_ManRetimeMinArea( pTemp = pNew, 1000, 0, 0, 1, 0 ); Aig_ManStop( pTemp ); pNew = Aig_ManDupOrdered( pTemp = pNew ); Aig_ManStop( pTemp ); if ( pParSec->fVerbose ) { printf( "Min-reg retiming: Latches = %5d. Nodes = %6d. ", Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); ABC_PRT( "Time", Abc_Clock() - clk ); } } if ( pNew->nRegs ) pNew = Aig_ManConstReduce( pNew, 0, -1, -1, 0, 0 ); // perform rewriting clk = Abc_Clock(); pNew = Aig_ManDupOrdered( pTemp = pNew ); Aig_ManStop( pTemp ); // pNew = Dar_ManRewriteDefault( pTemp = pNew ); pNew = Dar_ManCompress2( pTemp = pNew, 1, 0, 1, 0, 0 ); Aig_ManStop( pTemp ); if ( pParSec->fVerbose ) { printf( "Rewriting: Latches = %5d. Nodes = %6d. ", Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); ABC_PRT( "Time", Abc_Clock() - clk ); } // perform sequential simulation if ( pNew->nRegs ) { clk = Abc_Clock(); pSml = Fra_SmlSimulateSeq( pNew, 0, 128 * nFrames, 1 + 16/(1+Aig_ManNodeNum(pNew)/1000), 1 ); if ( pParSec->fVerbose ) { printf( "Seq simulation : Latches = %5d. Nodes = %6d. ", Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) ); ABC_PRT( "Time", Abc_Clock() - clk ); } if ( pSml->fNonConstOut ) { pNew->pSeqModel = Fra_SmlGetCounterExample( pSml ); // transfer to the original manager if ( Saig_ManPiNum(p) != Saig_ManPiNum(pNew) ) printf( "The counter-example is invalid because of phase abstraction.\n" ); else { ABC_FREE( p->pSeqModel ); p->pSeqModel = Abc_CexDup( pNew->pSeqModel, Aig_ManRegNum(p) ); ABC_FREE( pNew->pSeqModel ); } Fra_SmlStop( pSml ); Aig_ManStop( pNew ); RetValue = 0; if ( !pParSec->fSilent ) { printf( "Networks are NOT EQUIVALENT after simulation. " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } if ( pParSec->fReportSolution && !pParSec->fRecursive ) { printf( "SOLUTION: FAIL " ); ABC_PRT( "Time", Abc_Clock() - clkTotal ); } return RetValue; } Fra_SmlStop( pSml ); } } // get the miter status RetValue = Fra_FraigMiterStatus( pNew ); // try interplation clk = Abc_Clock(); Aig_ManSetRegNum( pNew, Aig_ManRegNum(pNew) ); if ( pParSec->fInterpolation && RetValue == -1 && Aig_ManRegNum(pNew) > 0 ) { Inter_ManParams_t Pars, * pPars = &Pars; int Depth; ABC_FREE( pNew->pSeqModel ); Inter_ManSetDefaultParams( pPars ); // pPars->nBTLimit = 100; pPars->nBTLimit = pParSec->nBTLimitInter; pPars->fVerbose = pParSec->fVeryVerbose; if ( Saig_ManPoNum(pNew) == 1 ) { RetValue = Inter_ManPerformInterpolation( pNew, pPars, &Depth ); } else if ( pParSec->fInterSeparate ) { Abc_Cex_t * pCex = NULL; Aig_Man_t * pTemp, * pAux; Aig_Obj_t * pObjPo; int i, Counter = 0; Saig_ManForEachPo( pNew, pObjPo, i ) { if ( Aig_ObjFanin0(pObjPo) == Aig_ManConst1(pNew) ) continue; if ( pPars->fVerbose ) printf( "Solving output %2d (out of %2d):\n", i, Saig_ManPoNum(pNew) ); pTemp = Aig_ManDupOneOutput( pNew, i, 1 ); pTemp = Aig_ManScl( pAux = pTemp, 1, 1, 0, -1, -1, 0, 0 ); Aig_ManStop( pAux ); if ( Saig_ManRegNum(pTemp) > 0 ) { RetValue = Inter_ManPerformInterpolation( pTemp, pPars, &Depth ); if ( pTemp->pSeqModel ) { pCex = p->pSeqModel = Abc_CexDup( pTemp->pSeqModel, Aig_ManRegNum(p) ); pCex->iPo = i; Aig_ManStop( pTemp ); break; } // if solved, remove the output if ( RetValue == 1 ) { Aig_ObjPatchFanin0( pNew, pObjPo, Aig_ManConst0(pNew) ); // printf( "Output %3d : Solved ", i ); } else { Counter++; // printf( "Output %3d : Undec ", i ); } } else Counter++; // Aig_ManPrintStats( pTemp ); Aig_ManStop( pTemp ); printf( "Solving output %3d (out of %3d) using interpolation.\r", i, Saig_ManPoNum(pNew) ); } Aig_ManCleanup( pNew ); if ( pCex == NULL ) { printf( "Interpolation left %d (out of %d) outputs unsolved \n", Counter, Saig_ManPoNum(pNew) ); if ( Counter ) RetValue = -1; } pNew = Aig_ManDupUnsolvedOutputs( pTemp = pNew, 1 ); Aig_ManStop( pTemp ); pNew = Aig_ManScl( pTemp = pNew, 1, 1, 0, -1, -1, 0, 0 ); Aig_ManStop( pTemp ); }
/**Function************************************************************* Synopsis [Postprocesses the mapped network for area recovery.] Description [This procedure assumes that the mapping is assigned. It iterates the loop, in which the required times are computed and the mapping is updated. It is conceptually similar to the paper: V. Manohararajah, S. D. Brown, Z. G. Vranesic, Heuristics for area minimization in LUT-based FPGA technology mapping. Proc. IWLS '04.] SideEffects [] SeeAlso [] ***********************************************************************/ int Fpga_MappingPostProcess( Fpga_Man_t * p ) { int fShowSwitching = 0; int fRecoverAreaFlow = 1; int fRecoverArea = 1; float aAreaTotalCur, aAreaTotalCur2; int Iter, clk; //if ( p->fVerbose ) // printf( "Best clock period = %5.2f\n", Fpga_TimeComputeArrivalMax(p) ); // compute area, set references, and collect nodes used in the mapping Iter = 1; aAreaTotalCur = Fpga_MappingSetRefsAndArea( p ); if ( p->fVerbose ) { printf( "Iteration %dD : Area = %8.1f ", Iter++, aAreaTotalCur ); if ( fShowSwitching ) printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); else printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) ); ABC_PRT( "Time", p->timeMatch ); } if ( !p->fAreaRecovery ) return 1; if ( fRecoverAreaFlow ) { clk = clock(); // compute the required times and the fanouts Fpga_TimeComputeRequiredGlobal( p, 1 ); // remap topologically Fpga_MappingMatches( p, 0 ); // get the resulting area // aAreaTotalCur = Fpga_MappingSetRefsAndArea( p ); aAreaTotalCur = Fpga_MappingAreaTrav( p ); // note that here we do not update the reference counter // for some reason, this works better on benchmarks if ( p->fVerbose ) { printf( "Iteration %dF : Area = %8.1f ", Iter++, aAreaTotalCur ); if ( fShowSwitching ) printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); else printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) ); ABC_PRT( "Time", clock() - clk ); } } // update reference counters aAreaTotalCur2 = Fpga_MappingSetRefsAndArea( p ); assert( aAreaTotalCur == aAreaTotalCur2 ); if ( fRecoverArea ) { clk = clock(); // compute the required times and the fanouts Fpga_TimeComputeRequiredGlobal( p, 0 ); // remap topologically if ( p->fSwitching ) Fpga_MappingMatchesSwitch( p ); else Fpga_MappingMatchesArea( p ); // get the resulting area aAreaTotalCur = Fpga_MappingSetRefsAndArea( p ); if ( p->fVerbose ) { printf( "Iteration %d%s : Area = %8.1f ", Iter++, (p->fSwitching?"S":"A"), aAreaTotalCur ); if ( fShowSwitching ) printf( "Switch = %8.1f ", Fpga_MappingGetSwitching(p,p->vMapping) ); else printf( "Delay = %5.2f ", Fpga_TimeComputeArrivalMax(p) ); ABC_PRT( "Time", clock() - clk ); } } p->fAreaGlo = aAreaTotalCur; return 1; }
/**Function************************************************************* Synopsis [Takes file with commands to be executed and the number of CPUs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int main( int argc, char * argv[] ) { FILE * pFile, * pOutput = stdout; pthread_t ThreadIds[MAX_COMM_NUM]; char * pBufferCopy, Buffer[MAX_COMM_NUM]; int i, nCPUs = 0, nLines = 0, Counter; clock_t clk = clock(); // check command line arguments if ( argc != 3 ) { fprintf( stderr, "Wrong number of command line arguments.\n" ); goto usage; } // get the number of CPUs nCPUs = atoi( argv[1] ); if ( nCPUs <= 0 ) { fprintf( pOutput, "Cannot read an integer represting the number of CPUs.\n" ); goto usage; } // open the file and make sure it is available pFile = fopen( argv[2], "r" ); if ( pFile == NULL ) { fprintf( pOutput, "Input file \"%s\" cannot be opened.\n", argv[2] ); goto usage; } // read commands and execute at most <num> of them at a time // assert(mutex == PTHREAD_MUTEX_INITIALIZER); while ( fgets( Buffer, MAX_COMM_NUM, pFile ) != NULL ) { // get the command from the file if ( Buffer[0] == '\n' || Buffer[0] == '\r' || Buffer[0] == '\t' || Buffer[0] == ' ' || Buffer[0] == '#') { continue; } if ( Buffer[strlen(Buffer)-1] == '\n' ) Buffer[strlen(Buffer)-1] = 0; if ( Buffer[strlen(Buffer)-1] == '\r' ) Buffer[strlen(Buffer)-1] = 0; // wait till there is an empty thread while ( 1 ) { assert(pthread_mutex_lock(&mutex) == 0); Counter = nThreadsRunning; assert(pthread_mutex_unlock(&mutex) == 0); if ( Counter < nCPUs - 1 ) break; // Sleep( 100 ); } // increament the number of threads running assert(pthread_mutex_lock(&mutex) == 0); nThreadsRunning++; printf( "Calling: %s\n", (char *)Buffer ); fflush( stdout ); assert(pthread_mutex_unlock(&mutex) == 0); // create thread to execute this command pBufferCopy = Abc_UtilStrsav( Buffer ); assert(pthread_create( &ThreadIds[nLines], NULL, Abc_RunThread, (void *)pBufferCopy ) == 0); if ( ++nLines == MAX_COMM_NUM ) { fprintf( pOutput, "Cannot execute more than %d commands from file \"%s\".\n", nLines, argv[2] ); break; } } // wait for all the threads to finish while ( 1 ) { assert(pthread_mutex_lock(&mutex) == 0); Counter = nThreadsRunning; assert(pthread_mutex_unlock(&mutex) == 0); if ( Counter == 0 ) break; } // cleanup assert(pthread_mutex_destroy(&mutex) == 0); // assert(mutex == NULL); fclose( pFile ); printf( "Finished processing commands in file \"%s\". ", argv[2] ); ABC_PRT( "Total time", clock() - clk ); return 0; usage: // skip the path name till the binary name for ( i = strlen(argv[0]) - 1; i > 0; i-- ) if ( argv[0][i-1] == '\\' || argv[0][i-1] == '/' ) break; // print usage message fprintf( pOutput, "usage: %s <num> <file>\n", argv[0]+i ); fprintf( pOutput, " executes command listed in <file> in parallel on <num> CPUs\n" ); fprintf( pOutput, "\n" ); return 1; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Performs technology mapping for the given object graph.] Description [The object graph is stored in the mapping manager. First, the AND nodes that fanout into POs are collected in the DFS order. Two preprocessing steps are performed: the k-feasible cuts are computed for each node and the truth tables are computed for each cut. Next, the delay-optimal matches are assigned for each node, followed by several iterations of area recoveryd: using area flow (global optimization) and using exact area at a node (local optimization).] SideEffects [] SeeAlso [] ***********************************************************************/ int Map_Mapping( Map_Man_t * p ) { int fShowSwitching = 0; int fUseAreaFlow = 1; int fUseExactArea = !p->fSwitching; int fUseExactAreaWithPhase = !p->fSwitching; abctime clk; ////////////////////////////////////////////////////////////////////// // perform pre-mapping computations // collect the nodes reachable from POs in the DFS order (including the choices) p->vAnds = Map_MappingDfs( p, 1 ); if ( p->fVerbose ) Map_MappingReportChoices( p ); Map_MappingSetChoiceLevels( p ); // should always be called before mapping! // return 1; // compute the cuts of nodes in the DFS order clk = Abc_Clock(); Map_MappingCuts( p ); p->timeCuts = Abc_Clock() - clk; // derive the truth tables clk = Abc_Clock(); Map_MappingTruths( p ); p->timeTruth = Abc_Clock() - clk; ////////////////////////////////////////////////////////////////////// //ABC_PRT( "Truths", Abc_Clock() - clk ); ////////////////////////////////////////////////////////////////////// // compute the minimum-delay mapping clk = Abc_Clock(); p->fMappingMode = 0; if ( !Map_MappingMatches( p ) ) return 0; p->timeMatch = Abc_Clock() - clk; // compute the references and collect the nodes used in the mapping Map_MappingSetRefs( p ); p->AreaBase = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { printf( "Delay : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", fShowSwitching? "Switch" : "Delay", fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaBase, 0.0 ); ABC_PRT( "Time", p->timeMatch ); } ////////////////////////////////////////////////////////////////////// if ( !p->fAreaRecovery ) { if ( p->fVerbose ) Map_MappingPrintOutputArrivals( p ); return 1; } ////////////////////////////////////////////////////////////////////// // perform area recovery using area flow clk = Abc_Clock(); if ( fUseAreaFlow ) { // compute the required times Map_TimeComputeRequiredGlobal( p ); // recover area flow p->fMappingMode = 1; Map_MappingMatches( p ); // compute the references and collect the nodes used in the mapping Map_MappingSetRefs( p ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { printf( "AreaFlow : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", fShowSwitching? "Switch" : "Delay", fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, Map_MappingGetAreaFlow(p), p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); ABC_PRT( "Time", Abc_Clock() - clk ); } } p->timeArea += Abc_Clock() - clk; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // perform area recovery using exact area clk = Abc_Clock(); if ( fUseExactArea ) { // compute the required times Map_TimeComputeRequiredGlobal( p ); // recover area p->fMappingMode = 2; Map_MappingMatches( p ); // compute the references and collect the nodes used in the mapping Map_MappingSetRefs( p ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", fShowSwitching? "Switch" : "Delay", fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, 0.0, p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); ABC_PRT( "Time", Abc_Clock() - clk ); } } p->timeArea += Abc_Clock() - clk; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // perform area recovery using exact area clk = Abc_Clock(); if ( fUseExactAreaWithPhase ) { // compute the required times Map_TimeComputeRequiredGlobal( p ); // recover area p->fMappingMode = 3; Map_MappingMatches( p ); // compute the references and collect the nodes used in the mapping Map_MappingSetRefs( p ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { printf( "Area : %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", fShowSwitching? "Switch" : "Delay", fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, 0.0, p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); ABC_PRT( "Time", Abc_Clock() - clk ); } } p->timeArea += Abc_Clock() - clk; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // perform area recovery using exact area clk = Abc_Clock(); if ( p->fSwitching ) { // compute the required times Map_TimeComputeRequiredGlobal( p ); // recover switching activity p->fMappingMode = 4; Map_MappingMatches( p ); // compute the references and collect the nodes used in the mapping Map_MappingSetRefs( p ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { printf( "Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", fShowSwitching? "Switch" : "Delay", fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, 0.0, p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); ABC_PRT( "Time", Abc_Clock() - clk ); } // compute the required times Map_TimeComputeRequiredGlobal( p ); // recover switching activity p->fMappingMode = 4; Map_MappingMatches( p ); // compute the references and collect the nodes used in the mapping Map_MappingSetRefs( p ); p->AreaFinal = Map_MappingGetArea( p, p->vMapping ); if ( p->fVerbose ) { printf( "Switching: %s = %8.2f Flow = %11.1f Area = %11.1f %4.1f %% ", fShowSwitching? "Switch" : "Delay", fShowSwitching? Map_MappingGetSwitching(p,p->vMapping) : p->fRequiredGlo, 0.0, p->AreaFinal, 100.0*(p->AreaBase-p->AreaFinal)/p->AreaBase ); ABC_PRT( "Time", Abc_Clock() - clk ); } } p->timeArea += Abc_Clock() - clk; ////////////////////////////////////////////////////////////////////// // print the arrival times of the latest outputs if ( p->fVerbose ) Map_MappingPrintOutputArrivals( p ); return 1; }
/**Function************************************************************* Synopsis [Load the network into FPGA manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) { extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne ); Vec_Int_t * vSwitching = NULL, * vSwitching2 = NULL; float * pSwitching = NULL, * pSwitching2 = NULL; If_Man_t * pIfMan; If_Obj_t * pIfObj; Aig_Obj_t * pNode, * pFanin, * pPrev; int i; abctime clk = Abc_Clock(); // set the number of registers (switch activity will be combinational) Aig_ManSetRegNum( p, 0 ); if ( pPars->fPower ) { vSwitching = Saig_ManComputeSwitchProbs( p, 48, 16, 0 ); if ( pPars->fVerbose ) { ABC_PRT( "Computing switching activity", Abc_Clock() - clk ); } pSwitching = (float *)vSwitching->pArray; vSwitching2 = Vec_IntStart( Aig_ManObjNumMax(p) ); pSwitching2 = (float *)vSwitching2->pArray; } // start the mapping manager and set its parameters pIfMan = If_ManStart( pPars ); pIfMan->vSwitching = vSwitching2; // load the AIG into the mapper Aig_ManForEachObj( p, pNode, i ) { if ( Aig_ObjIsAnd(pNode) ) { pIfObj = If_ManCreateAnd( pIfMan, If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ), If_NotCond( (If_Obj_t *)Aig_ObjFanin1(pNode)->pData, Aig_ObjFaninC1(pNode) ) ); // printf( "no%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) ); } else if ( Aig_ObjIsCi(pNode) ) { pIfObj = If_ManCreateCi( pIfMan ); If_ObjSetLevel( pIfObj, Aig_ObjLevel(pNode) ); // printf( "pi%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) ); if ( pIfMan->nLevelMax < (int)pIfObj->Level ) pIfMan->nLevelMax = (int)pIfObj->Level; } else if ( Aig_ObjIsCo(pNode) ) { pIfObj = If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) ); // printf( "po%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) ); } else if ( Aig_ObjIsConst1(pNode) ) pIfObj = If_ManConst1( pIfMan ); else // add the node to the mapper assert( 0 ); // save the result assert( Vec_PtrEntry(vAigToIf, i) == NULL ); Vec_PtrWriteEntry( vAigToIf, i, pIfObj ); pNode->pData = pIfObj; if ( vSwitching2 ) pSwitching2[pIfObj->Id] = pSwitching[pNode->Id]; // set up the choice node if ( Aig_ObjIsChoice( p, pNode ) ) { for ( pPrev = pNode, pFanin = Aig_ObjEquiv(p, pNode); pFanin; pPrev = pFanin, pFanin = Aig_ObjEquiv(p, pFanin) ) If_ObjSetChoice( (If_Obj_t *)pPrev->pData, (If_Obj_t *)pFanin->pData ); If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pData ); } // assert( If_ObjLevel(pIfObj) == Aig_ObjLevel(pNode) ); } if ( vSwitching ) Vec_IntFree( vSwitching ); return pIfMan; }
/**Function************************************************************* Synopsis [Deallocates the mapping manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Map_ManPrintTimeStats( Map_Man_t * p ) { printf( "N-canonical = %d. Matchings = %d. Phases = %d. ", p->nCanons, p->nMatches, p->nPhases ); printf( "Choice nodes = %d. Choices = %d.\n", p->nChoiceNodes, p->nChoices ); ABC_PRT( "ToMap", p->timeToMap ); ABC_PRT( "Cuts ", p->timeCuts ); ABC_PRT( "Truth", p->timeTruth ); ABC_PRT( "Match", p->timeMatch ); ABC_PRT( "Area ", p->timeArea ); ABC_PRT( "Sweep", p->timeSweep ); ABC_PRT( "ToNet", p->timeToNet ); ABC_PRT( "TOTAL", p->timeTotal ); if ( p->time1 ) { ABC_PRT( "time1", p->time1 ); } if ( p->time2 ) { ABC_PRT( "time2", p->time2 ); } if ( p->time3 ) { ABC_PRT( "time3", p->time3 ); } }