Skip to content

Commit

Permalink
Duplicating AIG after synthesis.
Browse files Browse the repository at this point in the history
  • Loading branch information
alanminko committed Jul 26, 2024
1 parent f8a6432 commit b5f4afa
Showing 1 changed file with 121 additions and 0 deletions.
121 changes: 121 additions & 0 deletions src/aig/gia/giaUtil.c
Original file line number Diff line number Diff line change
Expand Up @@ -3341,6 +3341,127 @@ Gia_Man_t * Gia_ManGenMux( int nIns, char * pNums )
return p;
}

/**Function*************************************************************
Synopsis [Returns 1 if this window has a topo error (forward path from an output to an input).]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManWindowCheckTopoError_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
{
if ( !Gia_ObjIsAnd(pObj) )
return 0;
if ( Gia_ObjIsTravIdPrevious(p, pObj) )
return 1; // there is an error
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return 0; // there is no error; visited this node before
Gia_ObjSetTravIdPrevious(p, pObj);
if ( Gia_ManWindowCheckTopoError_rec(p, Gia_ObjFanin0(pObj)) || Gia_ManWindowCheckTopoError_rec(p, Gia_ObjFanin1(pObj)) )
return 1;
Gia_ObjSetTravIdCurrent(p, pObj);
return 0;
}
int Gia_ManWindowCheckTopoError( Gia_Man_t * p, Vec_Int_t * vIns, Vec_Int_t * vOuts )
{
Gia_Obj_t * pObj; int i, fError = 0;
// outputs should be internal nodes
Gia_ManForEachObjVec( vOuts, p, pObj, i )
assert(Gia_ObjIsAnd(pObj));
// mark outputs
Gia_ManIncrementTravId( p );
Gia_ManForEachObjVec( vOuts, p, pObj, i )
Gia_ObjSetTravIdCurrent(p, pObj);
// start from inputs and make sure we do not reach any of the outputs
Gia_ManIncrementTravId( p );
Gia_ManForEachObjVec( vIns, p, pObj, i )
fError |= Gia_ManWindowCheckTopoError_rec(p, pObj);
return fError;
}

/**Function*************************************************************
Synopsis [Updates the AIG after multiple windows have been optimized.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManDupInsertWindows_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vMap, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins )
{
if ( ~pObj->Value )
return pObj->Value;
assert( Gia_ObjIsAnd(pObj) );
if ( Vec_IntEntry(vMap, Gia_ObjId(p, pObj)) == -1 ) // this is a regular node
{
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin0(pObj), vMap, vvIns, vvOuts, vWins );
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin1(pObj), vMap, vvIns, vvOuts, vWins );
return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
}
// this node is an output of a window
int iWin = Vec_IntEntry(vMap, Gia_ObjId(p, pObj));
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, iWin);
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, iWin);
Gia_Man_t * pWin = (Gia_Man_t *)Vec_PtrEntry(vWins, iWin);
// build transinvite fanins of window inputs
Gia_Obj_t * pNode; int i;
Gia_ManConst0(pWin)->Value = 0;
Gia_ManForEachObjVec( vIns, p, pNode, i )
Gia_ManPi(pWin, i)->Value = Gia_ManDupInsertWindows_rec( pNew, p, pNode, vMap, vvIns, vvOuts, vWins );
// add window nodes
Gia_ManForEachAnd( pWin, pNode, i )
pNode->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pNode), Gia_ObjFanin1Copy(pNode) );
// transfer to window outputs
Gia_ManForEachObjVec( vOuts, p, pNode, i )
pNode->Value = Gia_ObjFanin0Copy(Gia_ManPo(pWin, i));
assert( ~pObj->Value );
return pObj->Value;
}
Gia_Man_t * Gia_ManDupInsertWindows( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins )
{
// check consistency of input data
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, k, iNode;
Vec_PtrForEachEntry( Gia_Man_t *, vWins, pTemp, i ) {
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, i);
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, i);
assert( Vec_IntSize(vIns) == Gia_ManPiNum(pTemp) );
assert( Vec_IntSize(vOuts) == Gia_ManPoNum(pTemp) );
assert( !Gia_ManWindowCheckTopoError(p, vIns, vOuts) );
}
// create mapping of window outputs into window IDs
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ), * vOuts;
Vec_PtrForEachEntry( Vec_Int_t *, vvOuts, vOuts, i )
Vec_IntForEachEntry( vOuts, iNode, k )
Vec_IntWriteEntry( vMap, iNode, i );
// create the resulting AIG by performing DFS from the POs of the original AIG
// it goes recursively through original nodes and windows until it reaches the PIs of the original AIG
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManHashAlloc( pNew );
Gia_ManFillValue( p );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi(pNew);
Gia_ManForEachCo( p, pObj, i )
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin0(pObj), vMap, vvIns, vvOuts, vWins );
Gia_ManForEachCo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
// cleanup and return
Vec_IntFree( vMap );
pNew = Gia_ManCleanup( pTemp = pNew );
Gia_ManStop( pTemp );
Gia_ManPrint( pNew );
return pNew;
}

////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit b5f4afa

Please sign in to comment.