/**Function************************************************************* Synopsis [Retimes node forward by one latch.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_ObjRetimeForward( Abc_Obj_t * pObj ) { Abc_Obj_t * pFanout; int Init0, Init1, Init, i; assert( Abc_ObjFaninNum(pObj) == 2 ); assert( Seq_ObjFaninL0(pObj) >= 1 ); assert( Seq_ObjFaninL1(pObj) >= 1 ); // remove the init values from the fanins Init0 = Seq_NodeDeleteFirst( pObj, 0 ); Init1 = Seq_NodeDeleteFirst( pObj, 1 ); assert( Init0 != ABC_INIT_NONE ); assert( Init1 != ABC_INIT_NONE ); // take into account the complements in the node if ( Abc_ObjFaninC0(pObj) ) { if ( Init0 == ABC_INIT_ZERO ) Init0 = ABC_INIT_ONE; else if ( Init0 == ABC_INIT_ONE ) Init0 = ABC_INIT_ZERO; } if ( Abc_ObjFaninC1(pObj) ) { if ( Init1 == ABC_INIT_ZERO ) Init1 = ABC_INIT_ONE; else if ( Init1 == ABC_INIT_ONE ) Init1 = ABC_INIT_ZERO; } // compute the value at the output of the node if ( Init0 == ABC_INIT_ZERO || Init1 == ABC_INIT_ZERO ) Init = ABC_INIT_ZERO; else if ( Init0 == ABC_INIT_ONE && Init1 == ABC_INIT_ONE ) Init = ABC_INIT_ONE; else Init = ABC_INIT_DC; // make sure the label is clean Abc_ObjForEachFanout( pObj, pFanout, i ) assert( pFanout->fMarkC == 0 ); // add the init values to the fanouts Abc_ObjForEachFanout( pObj, pFanout, i ) { if ( pFanout->fMarkC ) continue; pFanout->fMarkC = 1; if ( Abc_ObjFaninId0(pFanout) != Abc_ObjFaninId1(pFanout) ) Seq_NodeInsertLast( pFanout, Abc_ObjFanoutEdgeNum(pObj, pFanout), Init ); else { assert( Abc_ObjFanin0(pFanout) == pObj ); Seq_NodeInsertLast( pFanout, 0, Init ); Seq_NodeInsertLast( pFanout, 1, Init ); } } // clean the label Abc_ObjForEachFanout( pObj, pFanout, i ) pFanout->fMarkC = 0; }
/**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 [Finalizes the network using the existing network as a model.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) { Abc_Obj_t * pObj, * pDriver, * pDriverNew; int i; // set the COs of the strashed network Abc_NtkForEachCo( pNtk, pObj, i ) { pDriver = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) ); pDriverNew = Abc_ObjNotCond(pDriver->pCopy, Abc_ObjFaninC0(pObj)); Abc_ObjAddFanin( pObj->pCopy, pDriverNew ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned Abc_Ntk4VarObj( Vec_Ptr_t * vNodes ) { Abc_Obj_t * pObj; unsigned uTruth0, uTruth1; int i; Vec_PtrForEachEntry( vNodes, pObj, i ) { uTruth0 = (unsigned)(Abc_ObjFanin0(pObj)->pCopy); uTruth1 = (unsigned)(Abc_ObjFanin1(pObj)->pCopy); if ( Abc_ObjFaninC0(pObj) ) uTruth0 = ~uTruth0; if ( Abc_ObjFaninC1(pObj) ) uTruth1 = ~uTruth1; pObj->pCopy = (void *)(uTruth0 & uTruth1); }
Vec_PtrForEachEntry( vNodes, pNode, i ) { Extra_ProgressBarUpdate( pProgress, i, NULL ); // add the node to the mapper pNodeFpga = Fpga_NodeAnd( pMan, Fpga_NotCond( Abc_ObjFanin0(pNode)->pCopy, Abc_ObjFaninC0(pNode) ), Fpga_NotCond( Abc_ObjFanin1(pNode)->pCopy, Abc_ObjFaninC1(pNode) ) ); assert( pNode->pCopy == NULL ); // remember the node pNode->pCopy = (Abc_Obj_t *)pNodeFpga; if ( pSwitching ) Fpga_NodeSetSwitching( pNodeFpga, pSwitching[pNode->Id] ); // set up the choice node if ( Abc_AigNodeIsChoice( pNode ) ) for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData ) { Fpga_NodeSetNextE( (Fpga_Node_t *)pPrev->pCopy, (Fpga_Node_t *)pFanin->pCopy ); Fpga_NodeSetRepr( (Fpga_Node_t *)pFanin->pCopy, (Fpga_Node_t *)pNode->pCopy ); } }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_Ntk4VarObjPrint_rec( Abc_Obj_t * pObj ) { if ( pObj == Abc_AigConst1(pObj->pNtk) ) { printf( "1" ); return; } if ( Abc_ObjIsPi(pObj) ) { printf( "%c", pObj->Id - 1 + 'a' ); return; } printf( "(" ); Abc_Ntk4VarObjPrint_rec( Abc_ObjFanin0(pObj) ); if ( Abc_ObjFaninC0(pObj) ) printf( "\'" ); Abc_Ntk4VarObjPrint_rec( Abc_ObjFanin1(pObj) ); if ( Abc_ObjFaninC1(pObj) ) printf( "\'" ); printf( ")" ); }
/**Function************************************************************* Synopsis [Converts the network from ABC into the AIG manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NodeFanin0Copy2( Abc_Obj_t * pObj ) { return Abc_LitNotCond( Abc_ObjFanin0(pObj)->iTemp, Abc_ObjFaninC0(pObj) ); }
static inline int Abc_ObjGetXsimFanin0( Abc_Obj_t * pObj ) { int RetValue; RetValue = Abc_ObjGetXsim(Abc_ObjFanin0(pObj)); return Abc_ObjFaninC0(pObj)? Abc_XsimInv(RetValue) : RetValue; }
/**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 [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)); }
/**Function************************************************************* Synopsis [Verifies sequential equivalence by fraiging followed by SAT.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkCecFraigPart( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nPartSize, int fVerbose ) { extern int Cmd_CommandExecute( void * pAbc, char * sCommand ); extern void * Abc_FrameGetGlobalFrame(); Prove_Params_t Params, * pParams = &Params; Abc_Ntk_t * pMiter, * pMiterPart; Abc_Obj_t * pObj; int i, RetValue, Status, nOutputs; // solve the CNF using the SAT solver Prove_ParamsSetDefault( pParams ); pParams->nItersMax = 5; // pParams->fVerbose = 1; assert( nPartSize > 0 ); // get the miter of the two networks pMiter = Abc_NtkMiter( pNtk1, pNtk2, 1, nPartSize ); if ( pMiter == NULL ) { printf( "Miter computation has failed.\n" ); return; } RetValue = Abc_NtkMiterIsConstant( pMiter ); if ( RetValue == 0 ) { printf( "Networks are NOT EQUIVALENT after structural hashing.\n" ); // report the error pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, 1 ); Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); FREE( pMiter->pModel ); Abc_NtkDelete( pMiter ); return; } if ( RetValue == 1 ) { printf( "Networks are equivalent after structural hashing.\n" ); Abc_NtkDelete( pMiter ); return; } Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "unset progressbar" ); // solve the problem iteratively for each output of the miter Status = 1; nOutputs = 0; Abc_NtkForEachPo( pMiter, pObj, i ) { if ( Abc_ObjFanin0(pObj) == Abc_AigConst1(pMiter) ) { if ( Abc_ObjFaninC0(pObj) ) // complemented -> const 0 RetValue = 1; else RetValue = 0; pMiterPart = NULL; } else { // get the cone of this output pMiterPart = Abc_NtkCreateCone( pMiter, Abc_ObjFanin0(pObj), Abc_ObjName(pObj), 0 ); if ( Abc_ObjFaninC0(pObj) ) Abc_ObjXorFaninC( Abc_NtkPo(pMiterPart,0), 0 ); // solve the cone // RetValue = Abc_NtkMiterProve( &pMiterPart, pParams ); RetValue = Abc_NtkIvyProve( &pMiterPart, pParams ); } if ( RetValue == -1 ) { printf( "Networks are undecided (resource limits is reached).\r" ); Status = -1; } else if ( RetValue == 0 ) { int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiterPart, pMiterPart->pModel ); if ( pSimInfo[0] != 1 ) printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" ); else printf( "Networks are NOT EQUIVALENT. \n" ); free( pSimInfo ); Status = 0; break; } else { printf( "Finished part %d (out of %d)\r", i+1, Abc_NtkPoNum(pMiter) ); nOutputs += nPartSize; } // if ( pMiter->pModel ) // Abc_NtkVerifyReportError( pNtk1, pNtk2, pMiter->pModel ); if ( pMiterPart ) Abc_NtkDelete( pMiterPart ); } Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "set progressbar" ); if ( Status == 1 ) printf( "Networks are equivalent. \n" ); else if ( Status == -1 ) printf( "Timed out after verifying %d outputs (out of %d).\n", nOutputs, Abc_NtkCoNum(pNtk1) ); Abc_NtkDelete( pMiter ); }
// clean the label Abc_ObjForEachFanout( pObj, pFanout, i ) pFanout->fMarkC = 0; // update the fanin edges Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable ); Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable ); Seq_NodeInsertFirst( pObj, 0, ABC_INIT_DC ); Seq_NodeInsertFirst( pObj, 1, ABC_INIT_DC ); return 0; } // the initial values on the fanout edges contain 0, 1, or unknown // the new values on the fanin edges will be unknown // add new AND-gate to the network pNodeNew = Abc_NtkCreateNode( pNtkNew ); pNodeNew->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); // add PO fanouts if any if ( fMet0 ) { Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew ); Vec_IntPush( vValues, 0 ); } if ( fMet1 ) { Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew ); Vec_IntPush( vValues, 1 ); } // make sure the label is clean Abc_ObjForEachFanout( pObj, pFanout, i )
Abc_Ntk_t * My_Command_Associative(Abc_Ntk_t * pNtk) {// check abc.h and abcNtk.c(Abc_ntkDup, duplication) freeXXX //a new network to return printf("inside the My_Command_Associative\n"); Abc_Ntk_t * new_pNtk; Abc_Obj_t * pObj; int i, j,k,m; int changed = 0; //check partial nodes satisfying a certain associative law Abc_NtkForEachObj( pNtk, pObj, i) { //printf("Node ID: %d \n", Abc_ObjId(pObj)); //printf("FanInNum: %d \n",Abc_ObjFaninNum(pObj)); if(changed <1 && Abc_ObjFaninNum(pObj) == 2 && !Abc_ObjFaninC0(pObj) && !Abc_ObjFaninC1(pObj) ) { Abc_Obj_t * pFanin_0 = Abc_ObjFanin0(pObj); Abc_Obj_t * pFanin_1 = Abc_ObjFanin1(pObj); // (x*y)*z => x*(y*z) if(changed <1 && Abc_ObjFaninNum(pFanin_0) == 2 && !Abc_ObjFaninC0(pFanin_0) && !Abc_ObjFaninC1(pFanin_0) ) // (x*y)*z => x*(y*z) { printf("1st Condition, Node ID: %d\n",Abc_ObjId(pObj) ); printf("Abc_ObjFaninNum(pFanin_0): Node ID: %d\n",Abc_ObjId(pFanin_0) ); Abc_Obj_t * tempObj; Abc_Obj_t * pFanin_0_0 = Abc_ObjFanin0(pFanin_0); Abc_Obj_t * pFanin_0_1 = Abc_ObjFanin1(pFanin_0); Abc_Obj_t * NewParentNode = Abc_NtkDupObj(pNtk, pObj, 1); Abc_Obj_t * NewChildNode = Abc_NtkDupObj(pNtk, pFanin_0, 1); int FanoutNum = Abc_ObjFanoutNum(pObj); for (j=0; j<FanoutNum; j++) { tempObj = Abc_ObjFanout(pObj, j); Abc_ObjDeleteFanin( tempObj , pObj ); Abc_ObjAddFanin( tempObj, NewParentNode); } printf("ParentNode Created and connected\n" ); Abc_ObjAddFanin(NewParentNode,pFanin_0_0 ); Abc_ObjAddFanin( NewParentNode, NewChildNode ); Abc_ObjAddFanin( NewChildNode, pFanin_0_1); Abc_ObjAddFanin(NewChildNode,pFanin_1 ); printf("ChildNode Created and connected\n" ); printf("Abc_ObjFanoutNum(pFanin_0): %d\n",Abc_ObjFanoutNum(pFanin_0) ); if(Abc_ObjFanoutNum(pFanin_0)>1) { printf("pFanin_0 's FanOut > 1\n" ); } else { Abc_ObjForEachFanin(pFanin_0,tempObj, k ) { Abc_ObjDeleteFanin(pFanin_0,tempObj); } Abc_NtkDeleteObj(pFanin_0); } Abc_ObjForEachFanin(pObj,tempObj, k ) { Abc_ObjDeleteFanin(pObj,tempObj); }