mirror of https://github.com/YosysHQ/abc.git
Duplicating AIG after synthesis.
This commit is contained in:
parent
f8a6432d75
commit
b5f4afa73b
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
Loading…
Reference in New Issue