| /**CFile**************************************************************** | |
| FileName [retInit.c] | |
| SystemName [ABC: Logic synthesis and verification system.] | |
| PackageName [Retiming package.] | |
| Synopsis [Initial state computation for backward retiming.] | |
| Author [Alan Mishchenko] | |
| Affiliation [UC Berkeley] | |
| Date [Ver. 1.0. Started - Oct 31, 2006.] | |
| Revision [$Id: retInit.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $] | |
| ***********************************************************************/ | |
| #include "retInt.h" | |
| ABC_NAMESPACE_IMPL_START | |
| //////////////////////////////////////////////////////////////////////// | |
| /// DECLARATIONS /// | |
| //////////////////////////////////////////////////////////////////////// | |
| static int Abc_NtkRetimeVerifyModel( Abc_Ntk_t * pNtkCone, Vec_Int_t * vValues, int * pModel ); | |
| //////////////////////////////////////////////////////////////////////// | |
| /// FUNCTION DEFINITIONS /// | |
| //////////////////////////////////////////////////////////////////////// | |
| /**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 [Computes the results of simulating one node.] | |
| Description [Assumes that fanins have pCopy set to the input values.] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| int Abc_ObjSopSimulate( Abc_Obj_t * pObj ) | |
| { | |
| char * pCube, * pSop = (char *)pObj->pData; | |
| int nVars, Value, v, ResOr, ResAnd, ResVar; | |
| assert( pSop && !Abc_SopIsExorType(pSop) ); | |
| // simulate the SOP of the node | |
| ResOr = 0; | |
| nVars = Abc_SopGetVarNum(pSop); | |
| Abc_SopForEachCube( pSop, nVars, pCube ) | |
| { | |
| ResAnd = 1; | |
| Abc_CubeForEachVar( pCube, Value, v ) | |
| { | |
| if ( Value == '0' ) | |
| ResVar = 1 ^ ((int)(ABC_PTRUINT_T)Abc_ObjFanin(pObj, v)->pCopy); | |
| else if ( Value == '1' ) | |
| ResVar = (int)(ABC_PTRUINT_T)Abc_ObjFanin(pObj, v)->pCopy; | |
| else | |
| continue; | |
| ResAnd &= ResVar; | |
| } | |
| ResOr |= ResAnd; | |
| } | |
| // complement the result if necessary | |
| if ( !Abc_SopGetPhase(pSop) ) | |
| ResOr ^= 1; | |
| return ResOr; | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Verifies the counter-example.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| int Abc_NtkRetimeVerifyModel( Abc_Ntk_t * pNtkCone, Vec_Int_t * vValues, int * pModel ) | |
| { | |
| Vec_Ptr_t * vNodes; | |
| Abc_Obj_t * pObj; | |
| int i, Counter = 0; | |
| assert( Abc_NtkIsSopLogic(pNtkCone) ); | |
| // set the PIs | |
| Abc_NtkForEachPi( pNtkCone, pObj, i ) | |
| pObj->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)pModel[i]; | |
| // simulate the internal nodes | |
| vNodes = Abc_NtkDfs( pNtkCone, 0 ); | |
| Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) | |
| pObj->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)Abc_ObjSopSimulate( pObj ); | |
| Vec_PtrFree( vNodes ); | |
| // compare the outputs | |
| Abc_NtkForEachPo( pNtkCone, pObj, i ) | |
| pObj->pCopy = Abc_ObjFanin0(pObj)->pCopy; | |
| Abc_NtkForEachPo( pNtkCone, pObj, i ) | |
| Counter += (Vec_IntEntry(vValues, i) != (int)(ABC_PTRUINT_T)pObj->pCopy); | |
| if ( Counter > 0 ) | |
| printf( "%d outputs (out of %d) have a value mismatch.\n", Counter, Abc_NtkPoNum(pNtkCone) ); | |
| return 1; | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Transfer latch initial values to pCopy.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Abc_NtkRetimeTranferToCopy( Abc_Ntk_t * pNtk ) | |
| { | |
| Abc_Obj_t * pObj; | |
| int i; | |
| Abc_NtkForEachObj( pNtk, pObj, i ) | |
| if ( Abc_ObjIsLatch(pObj) ) | |
| pObj->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)Abc_LatchIsInit1(pObj); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Transfer latch initial values from pCopy.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Abc_NtkRetimeTranferFromCopy( Abc_Ntk_t * pNtk ) | |
| { | |
| Abc_Obj_t * pObj; | |
| int i; | |
| Abc_NtkForEachObj( pNtk, pObj, i ) | |
| if ( Abc_ObjIsLatch(pObj) ) | |
| pObj->pData = (void *)(ABC_PTRUINT_T)(pObj->pCopy? ABC_INIT_ONE : ABC_INIT_ZERO); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Transfer latch initial values to pCopy.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| Vec_Int_t * Abc_NtkRetimeCollectLatchValues( Abc_Ntk_t * pNtk ) | |
| { | |
| Vec_Int_t * vValues; | |
| Abc_Obj_t * pObj; | |
| int i; | |
| vValues = Vec_IntAlloc( Abc_NtkLatchNum(pNtk) ); | |
| Abc_NtkForEachObj( pNtk, pObj, i ) | |
| if ( Abc_ObjIsLatch(pObj) ) | |
| Vec_IntPush( vValues, Abc_LatchIsInit1(pObj) ); | |
| return vValues; | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Transfer latch initial values from pCopy.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Abc_NtkRetimeInsertLatchValues( Abc_Ntk_t * pNtk, Vec_Int_t * vValues ) | |
| { | |
| Abc_Obj_t * pObj; | |
| int i, Counter = 0; | |
| Abc_NtkForEachObj( pNtk, pObj, i ) | |
| if ( Abc_ObjIsLatch(pObj) ) | |
| pObj->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)Counter++; | |
| Abc_NtkForEachObj( pNtk, pObj, i ) | |
| if ( Abc_ObjIsLatch(pObj) ) | |
| pObj->pData = (Abc_Obj_t *)(ABC_PTRUINT_T)(vValues? (Vec_IntEntry(vValues,(int)(ABC_PTRUINT_T)pObj->pCopy)? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Transfer latch initial values to pCopy.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| Abc_Ntk_t * Abc_NtkRetimeBackwardInitialStart( Abc_Ntk_t * pNtk ) | |
| { | |
| Abc_Ntk_t * pNtkNew; | |
| Abc_Obj_t * pObj; | |
| int i; | |
| // create the network used for the initial state computation | |
| pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); | |
| // create POs corresponding to the initial values | |
| Abc_NtkForEachObj( pNtk, pObj, i ) | |
| if ( Abc_ObjIsLatch(pObj) ) | |
| pObj->pCopy = Abc_NtkCreatePo(pNtkNew); | |
| return pNtkNew; | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Transfer latch initial values to pCopy.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Abc_NtkRetimeBackwardInitialFinish( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, Vec_Int_t * vValuesOld, int fVerbose ) | |
| { | |
| Vec_Int_t * vValuesNew; | |
| Abc_Obj_t * pObj; | |
| int i; | |
| // create PIs corresponding to the initial values | |
| Abc_NtkForEachObj( pNtk, pObj, i ) | |
| if ( Abc_ObjIsLatch(pObj) ) | |
| Abc_ObjAddFanin( pObj->pCopy, Abc_NtkCreatePi(pNtkNew) ); | |
| // assign dummy node names | |
| Abc_NtkAddDummyPiNames( pNtkNew ); | |
| Abc_NtkAddDummyPoNames( pNtkNew ); | |
| // check the network | |
| if ( !Abc_NtkCheck( pNtkNew ) ) | |
| fprintf( stdout, "Abc_NtkRetimeBackwardInitialFinish(): Network check has failed.\n" ); | |
| // derive new initial values | |
| vValuesNew = Abc_NtkRetimeInitialValues( pNtkNew, vValuesOld, fVerbose ); | |
| // insert new initial values | |
| Abc_NtkRetimeInsertLatchValues( pNtk, vValuesNew ); | |
| if ( vValuesNew ) Vec_IntFree( vValuesNew ); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Cycles the circuit to create a new initial state.] | |
| Description [Simulates the circuit with random input for the given | |
| number of timeframes to get a better initial state.] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Abc_NtkCycleInitStateSop( Abc_Ntk_t * pNtk, int nFrames, int fVerbose ) | |
| { | |
| Vec_Ptr_t * vNodes; | |
| Abc_Obj_t * pObj; | |
| int i, f; | |
| assert( Abc_NtkIsSopLogic(pNtk) ); | |
| srand( 0x12341234 ); | |
| // initialize the values | |
| Abc_NtkForEachPi( pNtk, pObj, i ) | |
| pObj->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)(rand() & 1); | |
| Abc_NtkForEachLatch( pNtk, pObj, i ) | |
| pObj->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)Abc_LatchIsInit1(pObj); | |
| // simulate for the given number of timeframes | |
| vNodes = Abc_NtkDfs( pNtk, 0 ); | |
| for ( f = 0; f < nFrames; f++ ) | |
| { | |
| // simulate internal nodes | |
| Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) | |
| pObj->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)Abc_ObjSopSimulate( pObj ); | |
| // bring the results to the COs | |
| Abc_NtkForEachCo( pNtk, pObj, i ) | |
| pObj->pCopy = Abc_ObjFanin0(pObj)->pCopy; | |
| // assign PI values | |
| Abc_NtkForEachPi( pNtk, pObj, i ) | |
| pObj->pCopy = (Abc_Obj_t *)(ABC_PTRUINT_T)(rand() & 1); | |
| // transfer the latch values | |
| Abc_NtkForEachLatch( pNtk, pObj, i ) | |
| Abc_ObjFanout0(pObj)->pCopy = Abc_ObjFanin0(pObj)->pCopy; | |
| } | |
| Vec_PtrFree( vNodes ); | |
| // set the final values | |
| Abc_NtkForEachLatch( pNtk, pObj, i ) | |
| pObj->pData = (void *)(ABC_PTRUINT_T)(Abc_ObjFanout0(pObj)->pCopy ? ABC_INIT_ONE : ABC_INIT_ZERO); | |
| } | |
| //////////////////////////////////////////////////////////////////////// | |
| /// END OF FILE /// | |
| //////////////////////////////////////////////////////////////////////// | |
| ABC_NAMESPACE_IMPL_END | |