Commit c645bac3 by Alan Mishchenko

Version abc80410

parent 9d6b12dd
...@@ -3066,6 +3066,10 @@ SOURCE=.\src\aig\ntl\ntlCore.c ...@@ -3066,6 +3066,10 @@ SOURCE=.\src\aig\ntl\ntlCore.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\aig\ntl\ntlEc.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntl\ntlExtract.c SOURCE=.\src\aig\ntl\ntlExtract.c
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -3094,6 +3098,10 @@ SOURCE=.\src\aig\ntl\ntlReadBlif.c ...@@ -3094,6 +3098,10 @@ SOURCE=.\src\aig\ntl\ntlReadBlif.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\aig\ntl\ntlSweep.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntl\ntlTable.c SOURCE=.\src\aig\ntl\ntlTable.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
ABC: System for Sequential Synthesis and Verification
http://www.eecs.berkeley.edu/~alanmi/abc/
Copyright (c) The Regents of the University of California. All rights reserved. Copyright (c) The Regents of the University of California. All rights reserved.
Permission is hereby granted, without written agreement and without license or Permission is hereby granted, without written agreement and without license or
......
...@@ -140,6 +140,7 @@ struct Aig_Man_t_ ...@@ -140,6 +140,7 @@ struct Aig_Man_t_
void * pManCuts; void * pManCuts;
Vec_Ptr_t * vMapped; Vec_Ptr_t * vMapped;
Vec_Int_t * vFlopNums; Vec_Int_t * vFlopNums;
Vec_Int_t * vFlopReprs;
void * pSeqModel; void * pSeqModel;
Aig_Man_t * pManExdc; Aig_Man_t * pManExdc;
Vec_Ptr_t * vOnehots; Vec_Ptr_t * vOnehots;
...@@ -314,7 +315,7 @@ static inline void Aig_ObjClean( Aig_Obj_t * pObj ) { memset( pObj ...@@ -314,7 +315,7 @@ static inline void Aig_ObjClean( Aig_Obj_t * pObj ) { memset( pObj
static inline Aig_Obj_t * Aig_ObjFanout0( Aig_Man_t * p, Aig_Obj_t * pObj ) { assert(p->pFanData && pObj->Id < p->nFansAlloc); return Aig_ManObj(p, p->pFanData[5*pObj->Id] >> 1); } static inline Aig_Obj_t * Aig_ObjFanout0( Aig_Man_t * p, Aig_Obj_t * pObj ) { assert(p->pFanData && pObj->Id < p->nFansAlloc); return Aig_ManObj(p, p->pFanData[5*pObj->Id] >> 1); }
static inline Aig_Obj_t * Aig_ObjEquiv( Aig_Man_t * p, Aig_Obj_t * pObj ) { return p->pEquivs? p->pEquivs[pObj->Id] : NULL; } static inline Aig_Obj_t * Aig_ObjEquiv( Aig_Man_t * p, Aig_Obj_t * pObj ) { return p->pEquivs? p->pEquivs[pObj->Id] : NULL; }
static inline Aig_Obj_t * Aig_ObjRepr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return p->pReprs? p->pReprs[pObj->Id] : NULL; } static inline Aig_Obj_t * Aig_ObjRepr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return p->pReprs? p->pReprs[pObj->Id] : NULL; }
static inline int Aig_ObjPioNum( Aig_Obj_t * pObj ) { assert( !Aig_ObjIsNode(pObj) ); return (int)pObj->pNext; } static inline int Aig_ObjPioNum( Aig_Obj_t * pObj ) { assert( !Aig_ObjIsNode(pObj) ); return (int)(long)pObj->pNext; }
static inline int Aig_ObjWhatFanin( Aig_Obj_t * pObj, Aig_Obj_t * pFanin ) static inline int Aig_ObjWhatFanin( Aig_Obj_t * pObj, Aig_Obj_t * pFanin )
{ {
if ( Aig_ObjFanin0(pObj) == pFanin ) return 0; if ( Aig_ObjFanin0(pObj) == pFanin ) return 0;
...@@ -461,6 +462,7 @@ extern Aig_Obj_t * Aig_Compose( Aig_Man_t * p, Aig_Obj_t * pRoot, Aig_Obj_t ...@@ -461,6 +462,7 @@ extern Aig_Obj_t * Aig_Compose( Aig_Man_t * p, Aig_Obj_t * pRoot, Aig_Obj_t
extern void Aig_ObjCollectCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vNodes ); extern void Aig_ObjCollectCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vNodes );
extern int Aig_ObjCollectSuper( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper ); extern int Aig_ObjCollectSuper( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper );
/*=== aigDup.c ==========================================================*/ /*=== aigDup.c ==========================================================*/
extern Aig_Man_t * Aig_ManDup( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDupOrdered( Aig_Man_t * p ); extern Aig_Man_t * Aig_ManDupOrdered( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDupExor( Aig_Man_t * p ); extern Aig_Man_t * Aig_ManDupExor( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManDupDfs( Aig_Man_t * p ); extern Aig_Man_t * Aig_ManDupDfs( Aig_Man_t * p );
...@@ -560,6 +562,7 @@ extern int Aig_ManSeqCleanup( Aig_Man_t * p ); ...@@ -560,6 +562,7 @@ extern int Aig_ManSeqCleanup( Aig_Man_t * p );
extern int Aig_ManCountMergeRegs( Aig_Man_t * p ); extern int Aig_ManCountMergeRegs( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose ); extern Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose );
extern void Aig_ManComputeSccs( Aig_Man_t * p ); extern void Aig_ManComputeSccs( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManScl( Aig_Man_t * pAig, int fLatchConst, int fLatchEqual, int fVerbose );
/*=== aigShow.c ========================================================*/ /*=== aigShow.c ========================================================*/
extern void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold ); extern void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold );
/*=== aigTable.c ========================================================*/ /*=== aigTable.c ========================================================*/
......
...@@ -449,8 +449,8 @@ int Aig_ManChoiceLevel( Aig_Man_t * p ) ...@@ -449,8 +449,8 @@ int Aig_ManChoiceLevel( Aig_Man_t * p )
LevelMax = Aig_ObjLevel(pObj); LevelMax = Aig_ObjLevel(pObj);
} }
Aig_ManCleanPioNumbers( p ); Aig_ManCleanPioNumbers( p );
Aig_ManForEachNode( p, pObj, i ) // Aig_ManForEachNode( p, pObj, i )
assert( Aig_ObjLevel(pObj) > 0 ); // assert( Aig_ObjLevel(pObj) > 0 );
return LevelMax; return LevelMax;
} }
......
...@@ -33,6 +33,72 @@ ...@@ -33,6 +33,72 @@
Synopsis [Duplicates the AIG manager.] Synopsis [Duplicates the AIG manager.]
Description [Orders nodes as follows: PIs, ANDs, POs.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManDup( Aig_Man_t * p )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj, * pObjNew;
int i;
// create the new manager
pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
pNew->pName = Aig_UtilStrsav( p->pName );
pNew->pSpec = Aig_UtilStrsav( p->pSpec );
pNew->nRegs = p->nRegs;
pNew->nAsserts = p->nAsserts;
if ( p->vFlopNums )
pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
// create the PIs
Aig_ManCleanData( p );
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
Aig_ManConst1(pNew)->pHaig = Aig_ManConst1(p)->pHaig;
Aig_ManForEachPi( p, pObj, i )
{
pObjNew = Aig_ObjCreatePi( pNew );
pObjNew->pHaig = pObj->pHaig;
pObjNew->Level = pObj->Level;
pObj->pData = pObjNew;
}
// duplicate internal nodes
Aig_ManForEachObj( p, pObj, i )
if ( Aig_ObjIsBuf(pObj) )
{
pObjNew = Aig_ObjChild0Copy(pObj);
Aig_Regular(pObjNew)->pHaig = pObj->pHaig;
pObj->pData = pObjNew;
}
else if ( Aig_ObjIsNode(pObj) )
{
pObjNew = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
Aig_Regular(pObjNew)->pHaig = pObj->pHaig;
pObj->pData = pObjNew;
}
// add the POs
Aig_ManForEachPo( p, pObj, i )
{
pObjNew = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
pObjNew->pHaig = pObj->pHaig;
pObj->pData = pObjNew;
}
assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
// duplicate the timing manager
if ( p->pManTime )
pNew->pManTime = Tim_ManDup( p->pManTime, 0 );
// check the resulting network
if ( !Aig_ManCheck(pNew) )
printf( "Aig_ManDup(): The check has failed.\n" );
return pNew;
}
/**Function*************************************************************
Synopsis [Duplicates the AIG manager.]
Description [Assumes topological ordering of the nodes.] Description [Assumes topological ordering of the nodes.]
SideEffects [] SideEffects []
...@@ -543,7 +609,7 @@ Aig_Man_t * Aig_ManDupRepres( Aig_Man_t * p ) ...@@ -543,7 +609,7 @@ Aig_Man_t * Aig_ManDupRepres( Aig_Man_t * p )
} }
// check the new manager // check the new manager
if ( !Aig_ManCheck(pNew) ) if ( !Aig_ManCheck(pNew) )
printf( "Aig_ManDupReprentative: Check has failed.\n" ); printf( "Aig_ManDupRepres: Check has failed.\n" );
return pNew; return pNew;
} }
...@@ -616,7 +682,7 @@ Aig_Man_t * Aig_ManDupRepresDfs( Aig_Man_t * p ) ...@@ -616,7 +682,7 @@ Aig_Man_t * Aig_ManDupRepresDfs( Aig_Man_t * p )
} }
// check the new manager // check the new manager
if ( !Aig_ManCheck(pNew) ) if ( !Aig_ManCheck(pNew) )
printf( "Aig_ManDupReprentative: Check has failed.\n" ); printf( "Aig_ManDupRepresDfs: Check has failed.\n" );
return pNew; return pNew;
} }
......
...@@ -206,6 +206,7 @@ void Aig_ManStop( Aig_Man_t * p ) ...@@ -206,6 +206,7 @@ void Aig_ManStop( Aig_Man_t * p )
if ( p->vLevelR ) Vec_IntFree( p->vLevelR ); if ( p->vLevelR ) Vec_IntFree( p->vLevelR );
if ( p->vLevels ) Vec_VecFree( p->vLevels ); if ( p->vLevels ) Vec_VecFree( p->vLevels );
if ( p->vFlopNums) Vec_IntFree( p->vFlopNums ); if ( p->vFlopNums) Vec_IntFree( p->vFlopNums );
if ( p->vFlopReprs)Vec_IntFree( p->vFlopReprs );
if ( p->pManExdc ) Aig_ManStop( p->pManExdc ); if ( p->pManExdc ) Aig_ManStop( p->pManExdc );
if ( p->vOnehots ) Vec_VecFree( (Vec_Vec_t *)p->vOnehots ); if ( p->vOnehots ) Vec_VecFree( (Vec_Vec_t *)p->vOnehots );
FREE( p->pData ); FREE( p->pData );
......
...@@ -258,6 +258,8 @@ void Aig_ObjPatchFanin0( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFaninNew ...@@ -258,6 +258,8 @@ void Aig_ObjPatchFanin0( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFaninNew
Aig_ObjDeref( pFaninOld ); Aig_ObjDeref( pFaninOld );
// update the fanin // update the fanin
pObj->pFanin0 = pFaninNew; pObj->pFanin0 = pFaninNew;
pObj->Level = Aig_ObjLevelNew( pObj );
pObj->fPhase = Aig_ObjPhaseReal(pObj->pFanin0);
// increment ref and add fanout // increment ref and add fanout
if ( p->pFanData ) if ( p->pFanData )
Aig_ObjAddFanout( p, Aig_ObjFanin0(pObj), pObj ); Aig_ObjAddFanout( p, Aig_ObjFanin0(pObj), pObj );
......
...@@ -278,6 +278,8 @@ Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p, int fOrdered ) ...@@ -278,6 +278,8 @@ Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p, int fOrdered )
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
Aig_ManForEachPi( p, pObj, i ) Aig_ManForEachPi( p, pObj, i )
pObj->pData = Aig_ObjCreatePi(pNew); pObj->pData = Aig_ObjCreatePi(pNew);
// Aig_ManForEachPi( p, pObj, i )
// pObj->pData = Aig_ObjGetRepr( p, pObj );
// map the internal nodes // map the internal nodes
if ( fOrdered ) if ( fOrdered )
{ {
......
...@@ -44,25 +44,52 @@ Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap ) ...@@ -44,25 +44,52 @@ Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap )
{ {
Aig_Man_t * pNew; Aig_Man_t * pNew;
Aig_Obj_t * pObj, * pObjMapped; Aig_Obj_t * pObj, * pObjMapped;
int i; int i, nTruePis;
// create the new manager // create the new manager
pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
pNew->pName = Aig_UtilStrsav( p->pName ); pNew->pName = Aig_UtilStrsav( p->pName );
pNew->pSpec = Aig_UtilStrsav( p->pSpec ); pNew->pSpec = Aig_UtilStrsav( p->pSpec );
pNew->nRegs = p->nRegs; pNew->nRegs = p->nRegs;
pNew->nAsserts = p->nAsserts; pNew->nAsserts = p->nAsserts;
assert( p->vFlopNums == NULL || Vec_IntSize(p->vFlopNums) == p->nRegs );
if ( p->vFlopNums ) if ( p->vFlopNums )
pNew->vFlopNums = Vec_IntDup( p->vFlopNums ); pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
if ( p->vFlopReprs )
pNew->vFlopReprs = Vec_IntDup( p->vFlopReprs );
// create the PIs // create the PIs
Aig_ManCleanData( p ); Aig_ManCleanData( p );
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
Aig_ManForEachPi( p, pObj, i ) Aig_ManForEachPi( p, pObj, i )
pObj->pData = Aig_ObjCreatePi(pNew); pObj->pData = Aig_ObjCreatePi(pNew);
// implement the mapping // implement the mapping
nTruePis = Aig_ManPiNum(p)-Aig_ManRegNum(p);
if ( p->vFlopReprs )
{
Aig_ManForEachLoSeq( p, pObj, i )
pObj->pNext = (Aig_Obj_t *)(long)Vec_IntEntry( p->vFlopNums, i-nTruePis );
}
Aig_ManForEachPi( p, pObj, i ) Aig_ManForEachPi( p, pObj, i )
{ {
pObjMapped = Vec_PtrEntry( vMap, i ); pObjMapped = Vec_PtrEntry( vMap, i );
pObj->pData = Aig_NotCond( Aig_Regular(pObjMapped)->pData, Aig_IsComplement(pObjMapped) ); pObj->pData = Aig_NotCond( Aig_Regular(pObjMapped)->pData, Aig_IsComplement(pObjMapped) );
if ( pNew->vFlopReprs && i >= nTruePis && pObj != pObjMapped )
{
Vec_IntPush( pNew->vFlopReprs, Aig_ObjPioNum(pObj) );
if ( Aig_ObjIsConst1( Aig_Regular(pObjMapped) ) )
Vec_IntPush( pNew->vFlopReprs, -1 );
else
{
assert( !Aig_IsComplement(pObjMapped) );
assert( Aig_ObjIsPi(pObjMapped) );
assert( Aig_ObjPioNum(pObj) != Aig_ObjPioNum(pObjMapped) );
Vec_IntPush( pNew->vFlopReprs, Aig_ObjPioNum(pObjMapped) );
}
}
}
if ( p->vFlopReprs )
{
Aig_ManForEachLoSeq( p, pObj, i )
pObj->pNext = NULL;
} }
// duplicate internal nodes // duplicate internal nodes
Aig_ManForEachObj( p, pObj, i ) Aig_ManForEachObj( p, pObj, i )
...@@ -158,16 +185,15 @@ int Aig_ManSeqCleanup( Aig_Man_t * p ) ...@@ -158,16 +185,15 @@ int Aig_ManSeqCleanup( Aig_Man_t * p )
if ( p->vFlopNums ) if ( p->vFlopNums )
{ {
int nTruePos = Aig_ManPoNum(p)-Aig_ManRegNum(p); int nTruePos = Aig_ManPoNum(p)-Aig_ManRegNum(p);
// remember numbers of flops in the flops int iNum, k = 0;
Aig_ManForEachLiSeq( p, pObj, i ) Aig_ManForEachPo( p, pObj, i )
pObj->pNext = (Aig_Obj_t *)(long)Vec_IntEntry( p->vFlopNums, i - nTruePos ); if ( i >= nTruePos && Aig_ObjIsTravIdCurrent(p, pObj) )
// reset the flop numbers {
Vec_PtrForEachEntryStart( vNodes, pObj, i, nTruePos ) iNum = Vec_IntEntry( p->vFlopNums, i - nTruePos );
Vec_IntWriteEntry( p->vFlopNums, i - nTruePos, (int)(long)pObj->pNext ); Vec_IntWriteEntry( p->vFlopNums, k++, iNum );
Vec_IntShrink( p->vFlopNums, Vec_PtrSize(vNodes) - nTruePos ); }
// clean the next pointer assert( k == Vec_PtrSize(vNodes) - nTruePos );
Aig_ManForEachLiSeq( p, pObj, i ) Vec_IntShrink( p->vFlopNums, k );
pObj->pNext = NULL;
} }
// collect new CIs/COs // collect new CIs/COs
vCis = Vec_PtrAlloc( Aig_ManPiNum(p) ); vCis = Vec_PtrAlloc( Aig_ManPiNum(p) );
...@@ -505,6 +531,54 @@ void Aig_ManComputeSccs( Aig_Man_t * p ) ...@@ -505,6 +531,54 @@ void Aig_ManComputeSccs( Aig_Man_t * p )
Vec_VecFree( (Vec_Vec_t *)vSupports ); Vec_VecFree( (Vec_Vec_t *)vSupports );
} }
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManScl( Aig_Man_t * pAig, int fLatchConst, int fLatchEqual, int fVerbose )
{
Aig_Man_t * pAigInit, * pAigNew;
Aig_Obj_t * pFlop1, * pFlop2;
int i, Entry1, Entry2, nTruePis;
// store the original AIG
assert( pAig->vFlopNums == NULL );
pAigInit = pAig;
pAig = Aig_ManDup( pAig );
// create storage for latch numbers
pAig->vFlopNums = Vec_IntStartNatural( pAig->nRegs );
pAig->vFlopReprs = Vec_IntAlloc( 100 );
Aig_ManSeqCleanup( pAig );
if ( fLatchConst && pAig->nRegs )
pAig = Aig_ManConstReduce( pAig, fVerbose );
if ( fLatchEqual && pAig->nRegs )
pAig = Aig_ManReduceLaches( pAig, fVerbose );
// translate pairs into reprs
nTruePis = Aig_ManPiNum(pAigInit)-Aig_ManRegNum(pAigInit);
Aig_ManReprStart( pAigInit, Aig_ManObjNumMax(pAigInit) );
Vec_IntForEachEntry( pAig->vFlopReprs, Entry1, i )
{
Entry2 = Vec_IntEntry( pAig->vFlopReprs, ++i );
pFlop1 = Aig_ManPi( pAigInit, nTruePis + Entry1 );
pFlop2 = (Entry2 == -1)? Aig_ManConst1(pAigInit) : Aig_ManPi( pAigInit, nTruePis + Entry2 );
assert( pFlop1 != pFlop2 );
if ( pFlop1->Id > pFlop2->Id )
pAigInit->pReprs[pFlop1->Id] = pFlop2;
else
pAigInit->pReprs[pFlop2->Id] = pFlop1;
}
Aig_ManStop( pAig );
// Aig_ManSeqCleanup( pAigInit );
pAigNew = Aig_ManDupRepr( pAigInit, 0 );
Aig_ManSeqCleanup( pAigNew );
return pAigNew;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
......
...@@ -47,13 +47,18 @@ int Fra_FraigSec( Aig_Man_t * p, int nFramesMax, int fRetimeFirst, int fFraiging ...@@ -47,13 +47,18 @@ int Fra_FraigSec( Aig_Man_t * p, int nFramesMax, int fRetimeFirst, int fFraiging
Aig_Man_t * pNew, * pTemp; Aig_Man_t * pNew, * pTemp;
int nFrames, RetValue, nIter, clk, clkTotal = clock(); int nFrames, RetValue, nIter, clk, clkTotal = clock();
int fLatchCorr = 0; int fLatchCorr = 0;
// try the miter before solving
RetValue = Fra_FraigMiterStatus( p );
if ( RetValue == 0 || RetValue == 1 )
goto finish;
// prepare parameters // prepare parameters
memset( pPars, 0, sizeof(Fra_Ssw_t) ); memset( pPars, 0, sizeof(Fra_Ssw_t) );
pPars->fLatchCorr = fLatchCorr; pPars->fLatchCorr = fLatchCorr;
pPars->fVerbose = fVeryVerbose; pPars->fVerbose = fVeryVerbose;
pNew = Aig_ManDupOrdered( p ); pNew = Aig_ManDup( p );
// pNew = Aig_ManDupDfs( p );
if ( fVerbose ) if ( fVerbose )
{ {
printf( "Original miter: Latches = %5d. Nodes = %6d.\n", printf( "Original miter: Latches = %5d. Nodes = %6d.\n",
...@@ -208,6 +213,7 @@ PRT( "Time", clock() - clkTotal ); ...@@ -208,6 +213,7 @@ PRT( "Time", clock() - clkTotal );
// get the miter status // get the miter status
RetValue = Fra_FraigMiterStatus( pNew ); RetValue = Fra_FraigMiterStatus( pNew );
finish:
// report the miter // report the miter
if ( RetValue == 1 ) if ( RetValue == 1 )
{ {
......
...@@ -145,7 +145,7 @@ static void Ioa_ObjSetAigerNum( Aig_Obj_t * pObj, unsigned Num ) { pObj->iD ...@@ -145,7 +145,7 @@ static void Ioa_ObjSetAigerNum( Aig_Obj_t * pObj, unsigned Num ) { pObj->iD
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ioa_WriteAigerEncode( char * pBuffer, int Pos, unsigned x ) int Ioa_WriteAigerEncode( unsigned char * pBuffer, int Pos, unsigned x )
{ {
unsigned char ch; unsigned char ch;
while (x & ~0x7f) while (x & ~0x7f)
...@@ -332,8 +332,8 @@ void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int ...@@ -332,8 +332,8 @@ void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int
uLit0 = Ioa_ObjMakeLit( Ioa_ObjAigerNum(Aig_ObjFanin0(pObj)), Aig_ObjFaninC0(pObj) ); uLit0 = Ioa_ObjMakeLit( Ioa_ObjAigerNum(Aig_ObjFanin0(pObj)), Aig_ObjFaninC0(pObj) );
uLit1 = Ioa_ObjMakeLit( Ioa_ObjAigerNum(Aig_ObjFanin1(pObj)), Aig_ObjFaninC1(pObj) ); uLit1 = Ioa_ObjMakeLit( Ioa_ObjAigerNum(Aig_ObjFanin1(pObj)), Aig_ObjFaninC1(pObj) );
assert( uLit0 < uLit1 ); assert( uLit0 < uLit1 );
Pos = Ioa_WriteAigerEncode( pBuffer, Pos, (unsigned)(uLit - uLit1) ); Pos = Ioa_WriteAigerEncode( pBuffer, Pos, uLit - uLit1 );
Pos = Ioa_WriteAigerEncode( pBuffer, Pos, (unsigned)(uLit1 - uLit0) ); Pos = Ioa_WriteAigerEncode( pBuffer, Pos, uLit1 - uLit0 );
if ( Pos > nBufferSize - 10 ) if ( Pos > nBufferSize - 10 )
{ {
printf( "Ioa_WriteAiger(): AIGER generation has failed because the allocated buffer is too small.\n" ); printf( "Ioa_WriteAiger(): AIGER generation has failed because the allocated buffer is too small.\n" );
......
SRC += src/aig/ntl/ntlCheck.c \ SRC += src/aig/ntl/ntlCheck.c \
src/aig/ntl/ntlCore.c \ src/aig/ntl/ntlCore.c \
src/aig/ntl/ntlEc.c \
src/aig/ntl/ntlExtract.c \ src/aig/ntl/ntlExtract.c \
src/aig/ntl/ntlFraig.c \ src/aig/ntl/ntlFraig.c \
src/aig/ntl/ntlInsert.c \ src/aig/ntl/ntlInsert.c \
...@@ -7,6 +8,7 @@ SRC += src/aig/ntl/ntlCheck.c \ ...@@ -7,6 +8,7 @@ SRC += src/aig/ntl/ntlCheck.c \
src/aig/ntl/ntlMap.c \ src/aig/ntl/ntlMap.c \
src/aig/ntl/ntlObj.c \ src/aig/ntl/ntlObj.c \
src/aig/ntl/ntlReadBlif.c \ src/aig/ntl/ntlReadBlif.c \
src/aig/ntl/ntlSweep.c \
src/aig/ntl/ntlTable.c \ src/aig/ntl/ntlTable.c \
src/aig/ntl/ntlTime.c \ src/aig/ntl/ntlTime.c \
src/aig/ntl/ntlUtil.c \ src/aig/ntl/ntlUtil.c \
......
...@@ -54,8 +54,9 @@ typedef enum { ...@@ -54,8 +54,9 @@ typedef enum {
NTL_OBJ_PO, // 2: primary output NTL_OBJ_PO, // 2: primary output
NTL_OBJ_LATCH, // 3: latch node NTL_OBJ_LATCH, // 3: latch node
NTL_OBJ_NODE, // 4: logic node NTL_OBJ_NODE, // 4: logic node
NTL_OBJ_BOX, // 5: white box or black box NTL_OBJ_LUT1, // 5: inverter/buffer
NTL_OBJ_VOID // 6: unused object NTL_OBJ_BOX, // 6: white box or black box
NTL_OBJ_VOID // 7: unused object
} Ntl_Type_t; } Ntl_Type_t;
struct Ntl_Man_t_ struct Ntl_Man_t_
...@@ -122,7 +123,7 @@ struct Ntl_Net_t_ ...@@ -122,7 +123,7 @@ struct Ntl_Net_t_
Ntl_Obj_t * pDriver; // driver of the net Ntl_Obj_t * pDriver; // driver of the net
char nVisits; // the number of times the net is visited char nVisits; // the number of times the net is visited
char fMark; // temporary mark char fMark; // temporary mark
char fCompl; // complemented attribue char fCompl; // complemented attribute
char pName[0]; // the name of this net char pName[0]; // the name of this net
}; };
...@@ -148,6 +149,7 @@ static inline Ntl_Mod_t * Ntl_ManRootModel( Ntl_Man_t * p ) { return Vec_P ...@@ -148,6 +149,7 @@ static inline Ntl_Mod_t * Ntl_ManRootModel( Ntl_Man_t * p ) { return Vec_P
static inline int Ntl_ModelPiNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_PI]; } static inline int Ntl_ModelPiNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_PI]; }
static inline int Ntl_ModelPoNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_PO]; } static inline int Ntl_ModelPoNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_PO]; }
static inline int Ntl_ModelNodeNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_NODE]; } static inline int Ntl_ModelNodeNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_NODE]; }
static inline int Ntl_ModelLut1Num( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_LUT1]; }
static inline int Ntl_ModelLatchNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_LATCH]; } static inline int Ntl_ModelLatchNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_LATCH]; }
static inline int Ntl_ModelBoxNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_BOX]; } static inline int Ntl_ModelBoxNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_BOX]; }
static inline int Ntl_ModelCiNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_PI] + p->nObjs[NTL_OBJ_LATCH]; } static inline int Ntl_ModelCiNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_PI] + p->nObjs[NTL_OBJ_LATCH]; }
...@@ -228,27 +230,35 @@ static inline void Ntl_ObjSetFanout( Ntl_Obj_t * p, Ntl_Net_t * pNet, int ...@@ -228,27 +230,35 @@ static inline void Ntl_ObjSetFanout( Ntl_Obj_t * p, Ntl_Net_t * pNet, int
/*=== ntlCore.c ==========================================================*/ /*=== ntlCore.c ==========================================================*/
extern int Ntl_ManInsertTest( Ntl_Man_t * p, Aig_Man_t * pAig ); extern int Ntl_ManInsertTest( Ntl_Man_t * p, Aig_Man_t * pAig );
extern int Ntl_ManInsertTestIf( Ntl_Man_t * p, Aig_Man_t * pAig ); extern int Ntl_ManInsertTestIf( Ntl_Man_t * p, Aig_Man_t * pAig );
/*=== ntlEc.c ==========================================================*/
extern void Ntl_ManPrepareCec( char * pFileName1, char * pFileName2, Aig_Man_t ** ppMan1, Aig_Man_t ** ppMan2 );
extern Aig_Man_t * Ntl_ManPrepareSec( char * pFileName1, char * pFileName2 );
/*=== ntlExtract.c ==========================================================*/ /*=== ntlExtract.c ==========================================================*/
extern Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p ); extern Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p );
extern Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p ); extern Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p, int fSeq );
extern Aig_Man_t * Ntl_ManCollapseForCec( Ntl_Man_t * p );
extern Aig_Man_t * Ntl_ManCollapseForSec( Ntl_Man_t * p1, Ntl_Man_t * p2 );
extern char * Ntl_SopFromTruth( Ntl_Man_t * p, unsigned * pTruth, int nVars, Vec_Int_t * vCover ); extern char * Ntl_SopFromTruth( Ntl_Man_t * p, unsigned * pTruth, int nVars, Vec_Int_t * vCover );
/*=== ntlInsert.c ==========================================================*/ /*=== ntlInsert.c ==========================================================*/
extern int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig ); extern Ntl_Man_t * Ntl_ManInsertMapping( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig );
extern int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig ); extern Ntl_Man_t * Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig );
extern int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ); extern Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk );
/*=== ntlCheck.c ==========================================================*/ /*=== ntlCheck.c ==========================================================*/
extern int Ntl_ManCheck( Ntl_Man_t * pMan ); extern int Ntl_ManCheck( Ntl_Man_t * pMan );
extern int Ntl_ModelCheck( Ntl_Mod_t * pModel ); extern int Ntl_ModelCheck( Ntl_Mod_t * pModel );
extern void Ntl_ModelFixNonDrivenNets( Ntl_Mod_t * pModel ); extern void Ntl_ModelFixNonDrivenNets( Ntl_Mod_t * pModel );
/*=== ntlMan.c ============================================================*/ /*=== ntlMan.c ============================================================*/
extern Ntl_Man_t * Ntl_ManAlloc( char * pFileName ); extern Ntl_Man_t * Ntl_ManAlloc( char * pFileName );
extern void Ntl_ManCleanup( Ntl_Man_t * p );
extern Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * p ); extern Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * p );
extern Ntl_Man_t * Ntl_ManDup( Ntl_Man_t * p ); extern Ntl_Man_t * Ntl_ManDup( Ntl_Man_t * p );
extern void Ntl_ManFree( Ntl_Man_t * p ); extern void Ntl_ManFree( Ntl_Man_t * p );
extern int Ntl_ManIsComb( Ntl_Man_t * p );
extern Ntl_Mod_t * Ntl_ManFindModel( Ntl_Man_t * p, char * pName ); extern Ntl_Mod_t * Ntl_ManFindModel( Ntl_Man_t * p, char * pName );
extern void Ntl_ManPrintStats( Ntl_Man_t * p ); extern void Ntl_ManPrintStats( Ntl_Man_t * p );
extern Tim_Man_t * Ntl_ManReadTimeMan( Ntl_Man_t * p ); extern Tim_Man_t * Ntl_ManReadTimeMan( Ntl_Man_t * p );
extern Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName ); extern Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName );
extern Ntl_Mod_t * Ntl_ModelStartFrom( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld );
extern Ntl_Mod_t * Ntl_ModelDup( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld ); extern Ntl_Mod_t * Ntl_ModelDup( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld );
extern void Ntl_ModelFree( Ntl_Mod_t * p ); extern void Ntl_ModelFree( Ntl_Mod_t * p );
/*=== ntlMap.c ============================================================*/ /*=== ntlMap.c ============================================================*/
...@@ -263,15 +273,19 @@ extern Ntl_Obj_t * Ntl_ModelCreateLatch( Ntl_Mod_t * pModel ); ...@@ -263,15 +273,19 @@ extern Ntl_Obj_t * Ntl_ModelCreateLatch( Ntl_Mod_t * pModel );
extern Ntl_Obj_t * Ntl_ModelCreateNode( Ntl_Mod_t * pModel, int nFanins ); extern Ntl_Obj_t * Ntl_ModelCreateNode( Ntl_Mod_t * pModel, int nFanins );
extern Ntl_Obj_t * Ntl_ModelCreateBox( Ntl_Mod_t * pModel, int nFanins, int nFanouts ); extern Ntl_Obj_t * Ntl_ModelCreateBox( Ntl_Mod_t * pModel, int nFanins, int nFanouts );
extern Ntl_Obj_t * Ntl_ModelDupObj( Ntl_Mod_t * pModel, Ntl_Obj_t * pOld ); extern Ntl_Obj_t * Ntl_ModelDupObj( Ntl_Mod_t * pModel, Ntl_Obj_t * pOld );
extern Ntl_Obj_t * Ntl_ModelCreatePiWithName( Ntl_Mod_t * pModel, char * pName );
extern char * Ntl_ManStoreName( Ntl_Man_t * p, char * pName ); extern char * Ntl_ManStoreName( Ntl_Man_t * p, char * pName );
extern char * Ntl_ManStoreSop( Ntl_Man_t * p, char * pSop ); extern char * Ntl_ManStoreSop( Ntl_Man_t * p, char * pSop );
extern char * Ntl_ManStoreFileName( Ntl_Man_t * p, char * pFileName ); extern char * Ntl_ManStoreFileName( Ntl_Man_t * p, char * pFileName );
/*=== ntlSweep.c ==========================================================*/
extern Ntl_Man_t * Ntl_ManSweep( Ntl_Man_t * p, Aig_Man_t * pAig, int fVerbose );
/*=== ntlTable.c ==========================================================*/ /*=== ntlTable.c ==========================================================*/
extern Ntl_Net_t * Ntl_ModelFindNet( Ntl_Mod_t * p, char * pName ); extern Ntl_Net_t * Ntl_ModelFindNet( Ntl_Mod_t * p, char * pName );
extern Ntl_Net_t * Ntl_ModelFindOrCreateNet( Ntl_Mod_t * p, char * pName ); extern Ntl_Net_t * Ntl_ModelFindOrCreateNet( Ntl_Mod_t * p, char * pName );
extern int Ntl_ModelFindPioNumber( Ntl_Mod_t * p, char * pName, int * pNumber ); extern int Ntl_ModelFindPioNumber( Ntl_Mod_t * p, char * pName, int * pNumber );
extern int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet ); extern int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet );
extern void Ntl_ModelDeleteNet( Ntl_Mod_t * p, Ntl_Net_t * pNet ); extern void Ntl_ModelDeleteNet( Ntl_Mod_t * p, Ntl_Net_t * pNet );
extern int Ntl_ModelCountNets( Ntl_Mod_t * p );
/*=== ntlTime.c ==========================================================*/ /*=== ntlTime.c ==========================================================*/
extern Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p ); extern Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p );
/*=== ntlReadBlif.c ==========================================================*/ /*=== ntlReadBlif.c ==========================================================*/
...@@ -279,9 +293,15 @@ extern Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck ); ...@@ -279,9 +293,15 @@ extern Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck );
/*=== ntlWriteBlif.c ==========================================================*/ /*=== ntlWriteBlif.c ==========================================================*/
extern void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName ); extern void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName );
/*=== ntlUtil.c ==========================================================*/ /*=== ntlUtil.c ==========================================================*/
extern int Ntl_ModelCountLut1( Ntl_Mod_t * pRoot );
extern int Ntl_ManCountSimpleCoDrivers( Ntl_Man_t * p );
extern int Ntl_ManTransformCoDrivers( Ntl_Man_t * p ); extern int Ntl_ManTransformCoDrivers( Ntl_Man_t * p );
extern int Ntl_ManReconnectCoDrivers( Ntl_Man_t * p );
extern Vec_Ptr_t * Ntl_ManCollectCiNames( Ntl_Man_t * p ); extern Vec_Ptr_t * Ntl_ManCollectCiNames( Ntl_Man_t * p );
extern Vec_Ptr_t * Ntl_ManCollectCoNames( Ntl_Man_t * p ); extern Vec_Ptr_t * Ntl_ManCollectCoNames( Ntl_Man_t * p );
extern void Ntl_ManMarkCiCoNets( Ntl_Man_t * p );
extern void Ntl_ManUnmarkCiCoNets( Ntl_Man_t * p );
extern int Ntl_ManCheckNetsAreNotMarked( Ntl_Mod_t * pModel );
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [] Synopsis [Checks one model.]
Description [] Description []
...@@ -49,12 +49,12 @@ int Ntl_ModelCheck( Ntl_Mod_t * pModel ) ...@@ -49,12 +49,12 @@ int Ntl_ModelCheck( Ntl_Mod_t * pModel )
{ {
if ( pNet->pName == NULL ) if ( pNet->pName == NULL )
{ {
printf( "Net %d does not have a name\n", i ); printf( "Net in bin %d does not have a name\n", i );
fStatus = 0; fStatus = 0;
} }
if ( pNet->pDriver == NULL ) if ( pNet->pDriver == NULL )
{ {
printf( "Net %d (%s) does not have a driver\n", i, pNet->pName ); printf( "Net %s does not have a driver\n", pNet->pName );
fStatus = 0; fStatus = 0;
} }
} }
...@@ -78,7 +78,7 @@ int Ntl_ModelCheck( Ntl_Mod_t * pModel ) ...@@ -78,7 +78,7 @@ int Ntl_ModelCheck( Ntl_Mod_t * pModel )
/**Function************************************************************* /**Function*************************************************************
Synopsis [] Synopsis [Checks the netlist.]
Description [] Description []
...@@ -131,7 +131,7 @@ int Ntl_ManCheck( Ntl_Man_t * pMan ) ...@@ -131,7 +131,7 @@ int Ntl_ManCheck( Ntl_Man_t * pMan )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Reads the verilog file.] Synopsis [Fixed problems with non-driven nets in the model.]
Description [] Description []
......
...@@ -69,10 +69,13 @@ Aig_Man_t * Ntl_ManPerformSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdate ...@@ -69,10 +69,13 @@ Aig_Man_t * Ntl_ManPerformSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdate
***********************************************************************/ ***********************************************************************/
int Ntl_ManInsertTest( Ntl_Man_t * p, Aig_Man_t * pAig ) int Ntl_ManInsertTest( Ntl_Man_t * p, Aig_Man_t * pAig )
{ {
Ntl_Man_t * pNew;
Vec_Ptr_t * vMapping; Vec_Ptr_t * vMapping;
int RetValue; int RetValue;
vMapping = Ntl_MappingFromAig( pAig ); vMapping = Ntl_MappingFromAig( pAig );
RetValue = Ntl_ManInsert( p, vMapping, pAig ); pNew = Ntl_ManInsertMapping( p, vMapping, pAig );
RetValue = (pNew != NULL);
Ntl_ManFree( pNew );
Vec_PtrFree( vMapping ); Vec_PtrFree( vMapping );
return RetValue; return RetValue;
} }
...@@ -90,10 +93,13 @@ int Ntl_ManInsertTest( Ntl_Man_t * p, Aig_Man_t * pAig ) ...@@ -90,10 +93,13 @@ int Ntl_ManInsertTest( Ntl_Man_t * p, Aig_Man_t * pAig )
***********************************************************************/ ***********************************************************************/
int Ntl_ManInsertTestIf( Ntl_Man_t * p, Aig_Man_t * pAig ) int Ntl_ManInsertTestIf( Ntl_Man_t * p, Aig_Man_t * pAig )
{ {
Ntl_Man_t * pNew;
Vec_Ptr_t * vMapping; Vec_Ptr_t * vMapping;
int RetValue; int RetValue;
vMapping = Ntl_MappingIf( p, pAig ); vMapping = Ntl_MappingIf( p, pAig );
RetValue = Ntl_ManInsert( p, vMapping, pAig ); pNew = Ntl_ManInsertMapping( p, vMapping, pAig );
RetValue = (pNew != NULL);
Ntl_ManFree( pNew );
Vec_PtrFree( vMapping ); Vec_PtrFree( vMapping );
return RetValue; return RetValue;
} }
......
...@@ -467,6 +467,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p ) ...@@ -467,6 +467,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
Ntl_Obj_t * pObj; Ntl_Obj_t * pObj;
Ntl_Net_t * pNet; Ntl_Net_t * pNet;
int i, nUselessObjects; int i, nUselessObjects;
Ntl_ManCleanup( p );
assert( Vec_PtrSize(p->vCis) == 0 ); assert( Vec_PtrSize(p->vCis) == 0 );
assert( Vec_PtrSize(p->vCos) == 0 ); assert( Vec_PtrSize(p->vCos) == 0 );
assert( Vec_PtrSize(p->vNodes) == 0 ); assert( Vec_PtrSize(p->vNodes) == 0 );
...@@ -540,7 +541,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p ) ...@@ -540,7 +541,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
Aig_ObjCreatePo( p->pAig, pNet->pCopy ); Aig_ObjCreatePo( p->pAig, pNet->pCopy );
} }
// report the number of dangling objects // report the number of dangling objects
nUselessObjects = Ntl_ModelNodeNum(pRoot) + Ntl_ModelBoxNum(pRoot) - Vec_PtrSize(p->vNodes); nUselessObjects = Ntl_ModelNodeNum(pRoot) + Ntl_ModelLut1Num(pRoot) + Ntl_ModelBoxNum(pRoot) - Vec_PtrSize(p->vNodes);
if ( nUselessObjects ) if ( nUselessObjects )
printf( "The number of nodes that do not feed into POs = %d.\n", nUselessObjects ); printf( "The number of nodes that do not feed into POs = %d.\n", nUselessObjects );
// cleanup the AIG // cleanup the AIG
...@@ -658,7 +659,7 @@ int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet ) ...@@ -658,7 +659,7 @@ int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p ) Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p, int fSeq )
{ {
Aig_Man_t * pAig; Aig_Man_t * pAig;
Ntl_Mod_t * pRoot; Ntl_Mod_t * pRoot;
...@@ -694,6 +695,8 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p ) ...@@ -694,6 +695,8 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p )
assert( Ntl_ObjFanoutNum(pObj) == 1 ); assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj); pNet = Ntl_ObjFanout0(pObj);
pNet->pCopy = Aig_ObjCreatePi( p->pAig ); pNet->pCopy = Aig_ObjCreatePi( p->pAig );
if ( fSeq && (pObj->LatchId & 3) == 1 )
pNet->pCopy = Aig_Not(pNet->pCopy);
if ( pNet->nVisits ) if ( pNet->nVisits )
{ {
printf( "Ntl_ManCollapse(): Latch output is duplicated or defined as a primary input.\n" ); printf( "Ntl_ManCollapse(): Latch output is duplicated or defined as a primary input.\n" );
...@@ -721,6 +724,60 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p ) ...@@ -721,6 +724,60 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p )
printf( "Ntl_ManCollapse(): Error: Combinational loop is detected.\n" ); printf( "Ntl_ManCollapse(): Error: Combinational loop is detected.\n" );
return 0; return 0;
} }
if ( fSeq && (pObj->LatchId & 3) == 1 )
Aig_ObjCreatePo( p->pAig, Aig_Not(pNet->pCopy) );
else
Aig_ObjCreatePo( p->pAig, pNet->pCopy );
}
// cleanup the AIG
Aig_ManCleanup( p->pAig );
pAig = p->pAig; p->pAig = NULL;
return pAig;
}
/**Function*************************************************************
Synopsis [Derives AIG for CEC.]
Description [Uses CIs/COs collected in the internal arrays.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ntl_ManCollapseForCec( Ntl_Man_t * p )
{
Aig_Man_t * pAig;
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
int i;
// create the manager
p->pAig = Aig_ManStart( 10000 );
p->pAig->pName = Aig_UtilStrsav( p->pName );
p->pAig->pSpec = Aig_UtilStrsav( p->pSpec );
// set the inputs
Ntl_ManForEachCiNet( p, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
pNet->pCopy = Aig_ObjCreatePi( p->pAig );
if ( pNet->nVisits )
{
printf( "Ntl_ManCollapseForCec(): Primary input appears twice in the list.\n" );
return 0;
}
pNet->nVisits = 2;
}
// derive the outputs
Ntl_ManForEachCoNet( p, pObj, i )
{
pNet = Ntl_ObjFanin0(pObj);
if ( !Ntl_ManCollapse_rec( p, pNet ) )
{
printf( "Ntl_ManCollapseForCec(): Error: Combinational loop is detected.\n" );
return 0;
}
Aig_ObjCreatePo( p->pAig, pNet->pCopy ); Aig_ObjCreatePo( p->pAig, pNet->pCopy );
} }
// cleanup the AIG // cleanup the AIG
...@@ -731,6 +788,164 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p ) ...@@ -731,6 +788,164 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Performs DFS.]
Description [Checks for combinational loops. Collects PI/PO nets.
Collects nodes in the topological order.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ntl_ManCollapseForSec( Ntl_Man_t * p1, Ntl_Man_t * p2 )
{
Aig_Man_t * pAig;
Aig_Obj_t * pMiter;
Ntl_Mod_t * pRoot1, * pRoot2;
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
Vec_Ptr_t * vPairs;
int i;
assert( Vec_PtrSize(p1->vCis) > 0 );
assert( Vec_PtrSize(p1->vCos) > 0 );
assert( Vec_PtrSize(p1->vCis) == Vec_PtrSize(p2->vCis) );
assert( Vec_PtrSize(p1->vCos) == Vec_PtrSize(p2->vCos) );
// create the manager
pAig = p1->pAig = p2->pAig = Aig_ManStart( 10000 );
pAig->pName = Aig_UtilStrsav( p1->pName );
pAig->pSpec = Aig_UtilStrsav( p1->pSpec );
vPairs = Vec_PtrStart( 2 * Vec_PtrSize(p1->vCos) );
// placehoder output to be used later for the miter output
Aig_ObjCreatePo( pAig, Aig_ManConst1(pAig) );
/////////////////////////////////////////////////////
// primary inputs
Ntl_ManForEachCiNet( p1, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
pNet->pCopy = Aig_ObjCreatePi( pAig );
if ( pNet->nVisits )
{
printf( "Ntl_ManCollapseForSec(): Primary input appears twice in the list.\n" );
return 0;
}
pNet->nVisits = 2;
}
// latch outputs
pRoot1 = Ntl_ManRootModel(p1);
Ntl_ModelForEachLatch( pRoot1, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
pNet->pCopy = Aig_ObjCreatePi( pAig );
if ( (pObj->LatchId & 3) == 1 )
pNet->pCopy = Aig_Not(pNet->pCopy);
if ( pNet->nVisits )
{
printf( "Ntl_ManCollapseForSec(): Latch output is duplicated or defined as a primary input.\n" );
return 0;
}
pNet->nVisits = 2;
}
// derive the outputs
Ntl_ManForEachCoNet( p1, pObj, i )
{
pNet = Ntl_ObjFanin0(pObj);
if ( !Ntl_ManCollapse_rec( p1, pNet ) )
{
printf( "Ntl_ManCollapseForSec(): Error: Combinational loop is detected.\n" );
return 0;
}
// Aig_ObjCreatePo( pAig, pNet->pCopy );
Vec_PtrWriteEntry( vPairs, 2 * i, pNet->pCopy );
}
// visit the nodes starting from latch inputs outputs
Ntl_ModelForEachLatch( pRoot1, pObj, i )
{
pNet = Ntl_ObjFanin0(pObj);
if ( !Ntl_ManCollapse_rec( p1, pNet ) )
{
printf( "Ntl_ManCollapseForSec(): Error: Combinational loop is detected.\n" );
return 0;
}
if ( (pObj->LatchId & 3) == 1 )
Aig_ObjCreatePo( pAig, Aig_Not(pNet->pCopy) );
else
Aig_ObjCreatePo( pAig, pNet->pCopy );
}
/////////////////////////////////////////////////////
// primary inputs
Ntl_ManForEachCiNet( p2, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
pNet->pCopy = Aig_ManPi( pAig, i );
if ( pNet->nVisits )
{
printf( "Ntl_ManCollapseForSec(): Primary input appears twice in the list.\n" );
return 0;
}
pNet->nVisits = 2;
}
// latch outputs
pRoot2 = Ntl_ManRootModel(p2);
Ntl_ModelForEachLatch( pRoot2, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
pNet->pCopy = Aig_ObjCreatePi( pAig );
if ( (pObj->LatchId & 3) == 1 )
pNet->pCopy = Aig_Not(pNet->pCopy);
if ( pNet->nVisits )
{
printf( "Ntl_ManCollapseForSec(): Latch output is duplicated or defined as a primary input.\n" );
return 0;
}
pNet->nVisits = 2;
}
// derive the outputs
Ntl_ManForEachCoNet( p2, pObj, i )
{
pNet = Ntl_ObjFanin0(pObj);
if ( !Ntl_ManCollapse_rec( p2, pNet ) )
{
printf( "Ntl_ManCollapseForSec(): Error: Combinational loop is detected.\n" );
return 0;
}
// Aig_ObjCreatePo( pAig, pNet->pCopy );
Vec_PtrWriteEntry( vPairs, 2 * i + 1, pNet->pCopy );
}
// visit the nodes starting from latch inputs outputs
Ntl_ModelForEachLatch( pRoot2, pObj, i )
{
pNet = Ntl_ObjFanin0(pObj);
if ( !Ntl_ManCollapse_rec( p2, pNet ) )
{
printf( "Ntl_ManCollapseForSec(): Error: Combinational loop is detected.\n" );
return 0;
}
if ( (pObj->LatchId & 3) == 1 )
Aig_ObjCreatePo( pAig, Aig_Not(pNet->pCopy) );
else
Aig_ObjCreatePo( pAig, pNet->pCopy );
}
/////////////////////////////////////////////////////
pMiter = Aig_Miter(pAig, vPairs);
Vec_PtrFree( vPairs );
Aig_ObjPatchFanin0( pAig, Aig_ManPo(pAig,0), pMiter );
pAig->nRegs = Ntl_ModelLatchNum( pRoot1 ) + Ntl_ModelLatchNum( pRoot2 );
Aig_ManCleanup( pAig );
return pAig;
}
/**Function*************************************************************
Synopsis [Increments reference counter of the net.] Synopsis [Increments reference counter of the net.]
Description [] Description []
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
***********************************************************************/ ***********************************************************************/
#include "ntl.h" #include "ntl.h"
#include "fra.h"
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// DECLARATIONS /// /// DECLARATIONS ///
...@@ -30,10 +31,10 @@ ...@@ -30,10 +31,10 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [Returns AIG with WB after fraiging.] Synopsis [Transfers equivalence class info from pAigCol to pAig.]
Description [pAig points to the nodes of pNew derived using it. Description [pAig points to the nodes of netlist (pNew) derived using it.
pNew points to the nodes of pAigCol derived using it.] pNew points to the nodes of the collapsed AIG (pAigCol) derived using it.]
SideEffects [] SideEffects []
...@@ -59,6 +60,9 @@ Aig_Obj_t ** Ntl_ManFraigDeriveClasses( Aig_Man_t * pAig, Ntl_Man_t * pNew, Aig_ ...@@ -59,6 +60,9 @@ Aig_Obj_t ** Ntl_ManFraigDeriveClasses( Aig_Man_t * pAig, Ntl_Man_t * pNew, Aig_
} }
// create mapping from the collapsed manager into the original manager // create mapping from the collapsed manager into the original manager
// (each node in the collapsed manager may have more than one equivalent node
// in the original manager; this procedure finds the first node in the original
// manager that is equivalent to the given node in the collapsed manager)
pMapBack = ALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAigCol) ); pMapBack = ALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAigCol) );
memset( pMapBack, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(pAigCol) ); memset( pMapBack, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(pAigCol) );
Aig_ManForEachObj( pAig, pObj, i ) Aig_ManForEachObj( pAig, pObj, i )
...@@ -115,16 +119,15 @@ Aig_Man_t * Ntl_ManFraig( Ntl_Man_t * p, Aig_Man_t * pAig, int nPartSize, int nC ...@@ -115,16 +119,15 @@ Aig_Man_t * Ntl_ManFraig( Ntl_Man_t * p, Aig_Man_t * pAig, int nPartSize, int nC
assert( pAig->pReprs == NULL ); assert( pAig->pReprs == NULL );
// create a new netlist whose nodes are in 1-to-1 relationship with AIG // create a new netlist whose nodes are in 1-to-1 relationship with AIG
pNew = Ntl_ManDup( p ); pNew = Ntl_ManInsertAig( p, pAig );
if ( !Ntl_ManInsertAig( pNew, pAig ) ) if ( pNew == NULL )
{ {
Ntl_ManFree( pNew );
printf( "Ntk_ManFraig(): Inserting AIG has failed.\n" ); printf( "Ntk_ManFraig(): Inserting AIG has failed.\n" );
return NULL; return NULL;
} }
// collapse the AIG // collapse the AIG
pAigCol = Ntl_ManCollapse( pNew ); pAigCol = Ntl_ManCollapse( pNew, 0 );
// perform fraiging for the given design // perform fraiging for the given design
if ( nPartSize == 0 ) if ( nPartSize == 0 )
nPartSize = Aig_ManPoNum(pAigCol); nPartSize = Aig_ManPoNum(pAigCol);
...@@ -148,6 +151,153 @@ Aig_Man_t * Ntl_ManFraig( Ntl_Man_t * p, Aig_Man_t * pAig, int nPartSize, int nC ...@@ -148,6 +151,153 @@ Aig_Man_t * Ntl_ManFraig( Ntl_Man_t * p, Aig_Man_t * pAig, int nPartSize, int nC
return pTemp; return pTemp;
} }
/**Function*************************************************************
Synopsis [Performs sequential cleanup.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ntl_ManScl( Ntl_Man_t * p, Aig_Man_t * pAig, int fLatchConst, int fLatchEqual, int fVerbose )
{
Ntl_Man_t * pNew;
Aig_Man_t * pAigCol, * pTemp;
assert( pAig->pReprs == NULL );
// create a new netlist whose nodes are in 1-to-1 relationship with AIG
pNew = Ntl_ManInsertAig( p, pAig );
if ( pNew == NULL )
{
printf( "Ntk_ManFraig(): Inserting AIG has failed.\n" );
return NULL;
}
// collapse the AIG
pAigCol = Ntl_ManCollapse( pNew, 1 );
// perform fraiging for the given design
pAigCol->nRegs = Ntl_ModelLatchNum(Ntl_ManRootModel(p));
pTemp = Aig_ManScl( pAigCol, fLatchConst, fLatchEqual, fVerbose );
Aig_ManStop( pTemp );
// transfer equivalence classes to the original AIG
pAig->pReprs = Ntl_ManFraigDeriveClasses( pAig, pNew, pAigCol );
pAig->nReprsAlloc = Aig_ManObjNumMax(pAig);
// cleanup
Aig_ManStop( pAigCol );
Ntl_ManFree( pNew );
// derive the new AIG
pTemp = Aig_ManDupRepresDfs( pAig );
// duplicate the timing manager
if ( pAig->pManTime )
pTemp->pManTime = Tim_ManDup( pAig->pManTime, 0 );
// reset levels
Aig_ManChoiceLevel( pTemp );
return pTemp;
}
/**Function*************************************************************
Synopsis [Returns AIG with WB after fraiging.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ntl_ManLcorr( Ntl_Man_t * p, Aig_Man_t * pAig, int nConfMax, int fVerbose )
{
Ntl_Man_t * pNew;
Aig_Man_t * pAigCol, * pTemp;
assert( pAig->pReprs == NULL );
// create a new netlist whose nodes are in 1-to-1 relationship with AIG
pNew = Ntl_ManInsertAig( p, pAig );
if ( pNew == NULL )
{
printf( "Ntk_ManFraig(): Inserting AIG has failed.\n" );
return NULL;
}
// collapse the AIG
pAigCol = Ntl_ManCollapse( pNew, 1 );
// perform fraiging for the given design
pAigCol->nRegs = Ntl_ModelLatchNum(Ntl_ManRootModel(p));
pTemp = Fra_FraigLatchCorrespondence( pAigCol, 0, nConfMax, 0, fVerbose, NULL );
Aig_ManStop( pTemp );
// transfer equivalence classes to the original AIG
pAig->pReprs = Ntl_ManFraigDeriveClasses( pAig, pNew, pAigCol );
pAig->nReprsAlloc = Aig_ManObjNumMax(pAig);
// cleanup
Aig_ManStop( pAigCol );
Ntl_ManFree( pNew );
// derive the new AIG
pTemp = Aig_ManDupRepresDfs( pAig );
// duplicate the timing manager
if ( pAig->pManTime )
pTemp->pManTime = Tim_ManDup( pAig->pManTime, 0 );
// reset levels
Aig_ManChoiceLevel( pTemp );
return pTemp;
}
/**Function*************************************************************
Synopsis [Returns AIG with WB after fraiging.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ntl_ManSsw( Ntl_Man_t * p, Aig_Man_t * pAig, Fra_Ssw_t * pPars )
{
Ntl_Man_t * pNew;
Aig_Man_t * pAigCol, * pTemp;
assert( pAig->pReprs == NULL );
// create a new netlist whose nodes are in 1-to-1 relationship with AIG
pNew = Ntl_ManInsertAig( p, pAig );
if ( pNew == NULL )
{
printf( "Ntk_ManFraig(): Inserting AIG has failed.\n" );
return NULL;
}
// collapse the AIG
pAigCol = Ntl_ManCollapse( pNew, 1 );
// perform fraiging for the given design
pAigCol->nRegs = Ntl_ModelLatchNum(Ntl_ManRootModel(p));
pTemp = Fra_FraigInduction( pAigCol, pPars );
Aig_ManStop( pTemp );
// transfer equivalence classes to the original AIG
pAig->pReprs = Ntl_ManFraigDeriveClasses( pAig, pNew, pAigCol );
pAig->nReprsAlloc = Aig_ManObjNumMax(pAig);
// cleanup
Aig_ManStop( pAigCol );
Ntl_ManFree( pNew );
// derive the new AIG
pTemp = Aig_ManDupRepresDfs( pAig );
// duplicate the timing manager
if ( pAig->pManTime )
pTemp->pManTime = Tim_ManDup( pAig->pManTime, 0 );
// reset levels
Aig_ManChoiceLevel( pTemp );
return pTemp;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig ) Ntl_Man_t * Ntl_ManInsertMapping( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
{ {
char Buffer[100]; char Buffer[100];
Vec_Ptr_t * vCopies; Vec_Ptr_t * vCopies;
...@@ -50,16 +50,14 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig ) ...@@ -50,16 +50,14 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
Ntl_Net_t * pNet, * pNetCo; Ntl_Net_t * pNet, * pNetCo;
Ntl_Lut_t * pLut; Ntl_Lut_t * pLut;
int i, k, nDigits; int i, k, nDigits;
assert( Vec_PtrSize(p->vCis) == Aig_ManPiNum(pAig) );
assert( Vec_PtrSize(p->vCos) == Aig_ManPoNum(pAig) );
p = Ntl_ManStartFrom( p );
pRoot = Ntl_ManRootModel( p );
assert( Ntl_ModelNodeNum(pRoot) == 0 );
// map the AIG back onto the design // map the AIG back onto the design
Ntl_ManForEachCiNet( p, pNet, i ) Ntl_ManForEachCiNet( p, pNet, i )
pNet->pCopy = Aig_ManPi( pAig, i ); pNet->pCopy = Aig_ManPi( pAig, i );
Ntl_ManForEachCoNet( p, pNet, i )
pNet->pCopy = Aig_ObjChild0( Aig_ManPo( pAig, i ) );
// remove old nodes
pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachNode( pRoot, pNode, i )
Vec_PtrWriteEntry( pRoot->vObjs, pNode->Id, NULL );
pRoot->nObjs[NTL_OBJ_NODE] = 0;
// start mapping of AIG nodes into their copies // start mapping of AIG nodes into their copies
vCopies = Vec_PtrStart( Aig_ManObjNumMax(pAig) ); vCopies = Vec_PtrStart( Aig_ManObjNumMax(pAig) );
Ntl_ManForEachCiNet( p, pNet, i ) Ntl_ManForEachCiNet( p, pNet, i )
...@@ -101,19 +99,19 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig ) ...@@ -101,19 +99,19 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
Vec_IntFree( vCover ); Vec_IntFree( vCover );
// mark CIs and outputs of the registers // mark CIs and outputs of the registers
Ntl_ManForEachCiNet( p, pNetCo, i ) Ntl_ManForEachCiNet( p, pNetCo, i )
pNetCo->nVisits = 101; // using "101" is harmless because nVisits can only be 0, 1 or 2 pNetCo->fMark = 1;
// update the CO pointers // update the CO pointers
Ntl_ManForEachCoNet( p, pNetCo, i ) Ntl_ManForEachCoNet( p, pNetCo, i )
{ {
if ( pNetCo->nVisits == 101 ) if ( pNetCo->fMark )
continue; continue;
pNetCo->nVisits = 101; pNetCo->fMark = 1;
pNet = Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pCopy)->Id ); pNet = Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pCopy)->Id );
pNode = Ntl_ModelCreateNode( pRoot, 1 ); pNode = Ntl_ModelCreateNode( pRoot, 1 );
pNode->pSop = Aig_IsComplement(pNetCo->pCopy)? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" ); pNode->pSop = Aig_IsComplement(pNetCo->pCopy)? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" );
Ntl_ObjSetFanin( pNode, pNet, 0 ); Ntl_ObjSetFanin( pNode, pNet, 0 );
// update the CO driver net // update the CO driver net
pNetCo->pDriver = NULL; assert( pNetCo->pDriver == NULL );
if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) ) if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) )
{ {
printf( "Ntl_ManInsert(): Internal error: PO net has more than one fanin.\n" ); printf( "Ntl_ManInsert(): Internal error: PO net has more than one fanin.\n" );
...@@ -121,7 +119,11 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig ) ...@@ -121,7 +119,11 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
} }
} }
Vec_PtrFree( vCopies ); Vec_PtrFree( vCopies );
return 1; // clean CI/CO marks
Ntl_ManUnmarkCiCoNets( p );
if ( !Ntl_ManCheck( p ) )
printf( "Ntl_ManInsertNtk: The check has failed for design %s.\n", p->pName );
return p;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -135,7 +137,7 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig ) ...@@ -135,7 +137,7 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig ) Ntl_Man_t * Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
{ {
char Buffer[100]; char Buffer[100];
Ntl_Mod_t * pRoot; Ntl_Mod_t * pRoot;
...@@ -145,17 +147,13 @@ int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig ) ...@@ -145,17 +147,13 @@ int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
int i, nDigits, Counter; int i, nDigits, Counter;
assert( Vec_PtrSize(p->vCis) == Aig_ManPiNum(pAig) ); assert( Vec_PtrSize(p->vCis) == Aig_ManPiNum(pAig) );
assert( Vec_PtrSize(p->vCos) == Aig_ManPoNum(pAig) ); assert( Vec_PtrSize(p->vCos) == Aig_ManPoNum(pAig) );
p = Ntl_ManStartFrom( p );
pRoot = Ntl_ManRootModel( p );
assert( Ntl_ModelNodeNum(pRoot) == 0 );
// set the correspondence between the PI/PO nodes // set the correspondence between the PI/PO nodes
Aig_ManCleanData( pAig ); Aig_ManCleanData( pAig );
Ntl_ManForEachCiNet( p, pNet, i ) Ntl_ManForEachCiNet( p, pNet, i )
Aig_ManPi( pAig, i )->pData = pNet; Aig_ManPi( pAig, i )->pData = pNet;
// Ntl_ManForEachCoNet( p, pNet, i )
// Nwk_ManCo( pNtk, i )->pCopy = pNet;
// remove old nodes
pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachNode( pRoot, pNode, i )
Vec_PtrWriteEntry( pRoot->vObjs, pNode->Id, NULL );
pRoot->nObjs[NTL_OBJ_NODE] = 0;
// create constant node if needed // create constant node if needed
if ( Aig_ManConst1(pAig)->nRefs > 0 ) if ( Aig_ManConst1(pAig)->nRefs > 0 )
{ {
...@@ -213,13 +211,13 @@ int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig ) ...@@ -213,13 +211,13 @@ int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
} }
// mark CIs and outputs of the registers // mark CIs and outputs of the registers
Ntl_ManForEachCiNet( p, pNetCo, i ) Ntl_ManForEachCiNet( p, pNetCo, i )
pNetCo->nVisits = 101; pNetCo->fMark = 1;
// update the CO pointers // update the CO pointers
Ntl_ManForEachCoNet( p, pNetCo, i ) Ntl_ManForEachCoNet( p, pNetCo, i )
{ {
if ( pNetCo->nVisits == 101 ) if ( pNetCo->fMark )
continue; continue;
pNetCo->nVisits = 101; pNetCo->fMark = 1;
// get the corresponding PO and its driver // get the corresponding PO and its driver
pObj = Aig_ManPo( pAig, i ); pObj = Aig_ManPo( pAig, i );
pFanin = Aig_ObjFanin0( pObj ); pFanin = Aig_ObjFanin0( pObj );
...@@ -229,14 +227,18 @@ int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig ) ...@@ -229,14 +227,18 @@ int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
pNode->pSop = Aig_ObjFaninC0(pObj)? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" ); pNode->pSop = Aig_ObjFaninC0(pObj)? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" );
Ntl_ObjSetFanin( pNode, pNet, 0 ); Ntl_ObjSetFanin( pNode, pNet, 0 );
// update the CO driver net // update the CO driver net
pNetCo->pDriver = NULL; assert( pNetCo->pDriver == NULL );
if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) ) if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) )
{ {
printf( "Ntl_ManInsert(): Internal error: PO net has more than one fanin.\n" ); printf( "Ntl_ManInsertAig(): Internal error: PO net has more than one fanin.\n" );
return 0; return 0;
} }
} }
return 1; // clean CI/CO marks
Ntl_ManUnmarkCiCoNets( p );
if ( !Ntl_ManCheck( p ) )
printf( "Ntl_ManInsertAig: The check has failed for design %s.\n", p->pName );
return p;
} }
...@@ -251,7 +253,7 @@ int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig ) ...@@ -251,7 +253,7 @@ int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) Ntl_Man_t * Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
{ {
char Buffer[100]; char Buffer[100];
Vec_Ptr_t * vObjs; Vec_Ptr_t * vObjs;
...@@ -265,16 +267,12 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) ...@@ -265,16 +267,12 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
unsigned * pTruth; unsigned * pTruth;
assert( Vec_PtrSize(p->vCis) == Nwk_ManCiNum(pNtk) ); assert( Vec_PtrSize(p->vCis) == Nwk_ManCiNum(pNtk) );
assert( Vec_PtrSize(p->vCos) == Nwk_ManCoNum(pNtk) ); assert( Vec_PtrSize(p->vCos) == Nwk_ManCoNum(pNtk) );
p = Ntl_ManStartFrom( p );
pRoot = Ntl_ManRootModel( p );
assert( Ntl_ModelNodeNum(pRoot) == 0 );
// set the correspondence between the PI/PO nodes // set the correspondence between the PI/PO nodes
Ntl_ManForEachCiNet( p, pNet, i ) Ntl_ManForEachCiNet( p, pNet, i )
Nwk_ManCi( pNtk, i )->pCopy = pNet; Nwk_ManCi( pNtk, i )->pCopy = pNet;
// Ntl_ManForEachCoNet( p, pNet, i )
// Nwk_ManCo( pNtk, i )->pCopy = pNet;
// remove old nodes
pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachNode( pRoot, pNode, i )
Vec_PtrWriteEntry( pRoot->vObjs, pNode->Id, NULL );
pRoot->nObjs[NTL_OBJ_NODE] = 0;
// create a new node for each LUT // create a new node for each LUT
vTruth = Vec_IntAlloc( 1 << 16 ); vTruth = Vec_IntAlloc( 1 << 16 );
vCover = Vec_IntAlloc( 1 << 16 ); vCover = Vec_IntAlloc( 1 << 16 );
...@@ -298,7 +296,7 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) ...@@ -298,7 +296,7 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
pNet = pFanin->pCopy; pNet = pFanin->pCopy;
if ( pNet == NULL ) if ( pNet == NULL )
{ {
printf( "Ntl_ManInsert(): Internal error: Net not found.\n" ); printf( "Ntl_ManInsertNtk(): Internal error: Net not found.\n" );
return 0; return 0;
} }
Ntl_ObjSetFanin( pNode, pNet, k ); Ntl_ObjSetFanin( pNode, pNet, k );
...@@ -307,13 +305,13 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) ...@@ -307,13 +305,13 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
sprintf( Buffer, "lut%0*d", nDigits, i ); sprintf( Buffer, "lut%0*d", nDigits, i );
if ( (pNet = Ntl_ModelFindNet( pRoot, Buffer )) ) if ( (pNet = Ntl_ModelFindNet( pRoot, Buffer )) )
{ {
printf( "Ntl_ManInsert(): Internal error: Intermediate net name is not unique.\n" ); printf( "Ntl_ManInsertNtk(): Internal error: Intermediate net name is not unique.\n" );
return 0; return 0;
} }
pNet = Ntl_ModelFindOrCreateNet( pRoot, Buffer ); pNet = Ntl_ModelFindOrCreateNet( pRoot, Buffer );
if ( !Ntl_ModelSetNetDriver( pNode, pNet ) ) if ( !Ntl_ModelSetNetDriver( pNode, pNet ) )
{ {
printf( "Ntl_ManInsert(): Internal error: Net has more than one fanin.\n" ); printf( "Ntl_ManInsertNtk(): Internal error: Net has more than one fanin.\n" );
return 0; return 0;
} }
pObj->pCopy = pNet; pObj->pCopy = pNet;
...@@ -323,13 +321,13 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) ...@@ -323,13 +321,13 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
Vec_IntFree( vTruth ); Vec_IntFree( vTruth );
// mark CIs and outputs of the registers // mark CIs and outputs of the registers
Ntl_ManForEachCiNet( p, pNetCo, i ) Ntl_ManForEachCiNet( p, pNetCo, i )
pNetCo->nVisits = 101; pNetCo->fMark = 1;
// update the CO pointers // update the CO pointers
Ntl_ManForEachCoNet( p, pNetCo, i ) Ntl_ManForEachCoNet( p, pNetCo, i )
{ {
if ( pNetCo->nVisits == 101 ) if ( pNetCo->fMark )
continue; continue;
pNetCo->nVisits = 101; pNetCo->fMark = 1;
// get the corresponding PO and its driver // get the corresponding PO and its driver
pObj = Nwk_ManCo( pNtk, i ); pObj = Nwk_ManCo( pNtk, i );
pFanin = Nwk_ObjFanin0( pObj ); pFanin = Nwk_ObjFanin0( pObj );
...@@ -339,14 +337,18 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk ) ...@@ -339,14 +337,18 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
pNode->pSop = pObj->fCompl /*Aig_IsComplement(pNetCo->pCopy)*/? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" ); pNode->pSop = pObj->fCompl /*Aig_IsComplement(pNetCo->pCopy)*/? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" );
Ntl_ObjSetFanin( pNode, pNet, 0 ); Ntl_ObjSetFanin( pNode, pNet, 0 );
// update the CO driver net // update the CO driver net
pNetCo->pDriver = NULL; assert( pNetCo->pDriver == NULL );
if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) ) if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) )
{ {
printf( "Ntl_ManInsert(): Internal error: PO net has more than one fanin.\n" ); printf( "Ntl_ManInsertNtk(): Internal error: PO net has more than one fanin.\n" );
return 0; return 0;
} }
} }
return 1; // clean CI/CO marks
Ntl_ManUnmarkCiCoNets( p );
if ( !Ntl_ManCheck( p ) )
printf( "Ntl_ManInsertNtk: The check has failed for design %s.\n", p->pName );
return p;
} }
......
...@@ -61,7 +61,36 @@ Ntl_Man_t * Ntl_ManAlloc( char * pFileName ) ...@@ -61,7 +61,36 @@ Ntl_Man_t * Ntl_ManAlloc( char * pFileName )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Duplicates the interface of the top level model.] Synopsis [Cleanups extended representation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManCleanup( Ntl_Man_t * p )
{
Vec_PtrClear( p->vCis );
Vec_PtrClear( p->vCos );
Vec_PtrClear( p->vNodes );
Vec_IntClear( p->vBox1Cos );
if ( p->pAig )
{
Aig_ManStop( p->pAig );
p->pAig = NULL;
}
if ( p->pManTime )
{
Tim_ManStop( p->pManTime );
p->pManTime = NULL;
}
}
/**Function*************************************************************
Synopsis [Duplicates the design without the nodes of the root model.]
Description [] Description []
...@@ -72,12 +101,36 @@ Ntl_Man_t * Ntl_ManAlloc( char * pFileName ) ...@@ -72,12 +101,36 @@ Ntl_Man_t * Ntl_ManAlloc( char * pFileName )
***********************************************************************/ ***********************************************************************/
Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * pOld ) Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * pOld )
{ {
return NULL; Ntl_Man_t * pNew;
Ntl_Mod_t * pModel;
Ntl_Obj_t * pBox;
Ntl_Net_t * pNet;
int i, k;
pNew = Ntl_ManAlloc( pOld->pSpec );
Vec_PtrForEachEntry( pOld->vModels, pModel, i )
if ( i == 0 )
{
Ntl_ManMarkCiCoNets( pOld );
pModel->pCopy = Ntl_ModelStartFrom( pNew, pModel );
Ntl_ManUnmarkCiCoNets( pOld );
}
else
pModel->pCopy = Ntl_ModelDup( pNew, pModel );
Vec_PtrForEachEntry( pOld->vModels, pModel, i )
Ntl_ModelForEachBox( pModel, pBox, k )
((Ntl_Obj_t *)pBox->pCopy)->pImplem = pBox->pImplem->pCopy;
Ntl_ManForEachCiNet( pOld, pNet, i )
Vec_PtrPush( pNew->vCis, pNet->pCopy );
Ntl_ManForEachCoNet( pOld, pNet, i )
Vec_PtrPush( pNew->vCos, pNet->pCopy );
if ( pOld->pManTime )
pNew->pManTime = Tim_ManDup( pOld->pManTime, 0 );
return pNew;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Duplicates the interface of the top level model.] Synopsis [Duplicates the design.]
Description [] Description []
...@@ -144,6 +197,22 @@ void Ntl_ManFree( Ntl_Man_t * p ) ...@@ -144,6 +197,22 @@ void Ntl_ManFree( Ntl_Man_t * p )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Returns 1 if the design is combinational.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManIsComb( Ntl_Man_t * p )
{
return Ntl_ModelLatchNum(Ntl_ManRootModel(p)) == 0;
}
/**Function*************************************************************
Synopsis [Find the model with the given name.] Synopsis [Find the model with the given name.]
Description [] Description []
...@@ -183,10 +252,13 @@ void Ntl_ManPrintStats( Ntl_Man_t * p ) ...@@ -183,10 +252,13 @@ void Ntl_ManPrintStats( Ntl_Man_t * p )
printf( "po = %5d ", Ntl_ModelPoNum(pRoot) ); printf( "po = %5d ", Ntl_ModelPoNum(pRoot) );
printf( "lat = %5d ", Ntl_ModelLatchNum(pRoot) ); printf( "lat = %5d ", Ntl_ModelLatchNum(pRoot) );
printf( "node = %5d ", Ntl_ModelNodeNum(pRoot) ); printf( "node = %5d ", Ntl_ModelNodeNum(pRoot) );
printf( "inv/buf = %5d ", Ntl_ModelLut1Num(pRoot) );
printf( "box = %4d ", Ntl_ModelBoxNum(pRoot) ); printf( "box = %4d ", Ntl_ModelBoxNum(pRoot) );
printf( "mod = %3d", Vec_PtrSize(p->vModels) ); printf( "mod = %3d ", Vec_PtrSize(p->vModels) );
printf( "net = %d", Ntl_ModelCountNets(pRoot) );
printf( "\n" ); printf( "\n" );
fflush( stdout ); fflush( stdout );
assert( Ntl_ModelLut1Num(pRoot) == Ntl_ModelCountLut1(pRoot) );
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -237,6 +309,50 @@ Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName ) ...@@ -237,6 +309,50 @@ Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Duplicates the model without nodes but with CI/CO nets.]
Description [The CI/CO nets of the old model should be marked before
calling this procedure.]
SideEffects []
SeeAlso []
***********************************************************************/
Ntl_Mod_t * Ntl_ModelStartFrom( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld )
{
Ntl_Mod_t * pModelNew;
Ntl_Net_t * pNet;
Ntl_Obj_t * pObj;
int i, k;
pModelNew = Ntl_ModelAlloc( pManNew, pModelOld->pName );
Ntl_ModelForEachNet( pModelOld, pNet, i )
if ( pNet->fMark )
pNet->pCopy = Ntl_ModelFindOrCreateNet( pModelNew, pNet->pName );
else
pNet->pCopy = NULL;
Ntl_ModelForEachObj( pModelOld, pObj, i )
{
if ( Ntl_ObjIsNode(pObj) )
continue;
pObj->pCopy = Ntl_ModelDupObj( pModelNew, pObj );
Ntl_ObjForEachFanin( pObj, pNet, k )
if ( pNet->pCopy != NULL )
Ntl_ObjSetFanin( pObj->pCopy, pNet->pCopy, k );
Ntl_ObjForEachFanout( pObj, pNet, k )
if ( pNet->pCopy != NULL )
Ntl_ObjSetFanout( pObj->pCopy, pNet->pCopy, k );
if ( Ntl_ObjIsLatch(pObj) )
((Ntl_Obj_t *)pObj->pCopy)->LatchId = pObj->LatchId;
}
pModelNew->vDelays = pModelOld->vDelays? Vec_IntDup( pModelOld->vDelays ) : NULL;
pModelNew->vArrivals = pModelOld->vArrivals? Vec_IntDup( pModelOld->vArrivals ) : NULL;
pModelNew->vRequireds = pModelOld->vRequireds? Vec_IntDup( pModelOld->vRequireds ) : NULL;
return pModelNew;
}
/**Function*************************************************************
Synopsis [Duplicates the model.] Synopsis [Duplicates the model.]
Description [] Description []
...@@ -286,6 +402,7 @@ Ntl_Mod_t * Ntl_ModelDup( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld ) ...@@ -286,6 +402,7 @@ Ntl_Mod_t * Ntl_ModelDup( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld )
***********************************************************************/ ***********************************************************************/
void Ntl_ModelFree( Ntl_Mod_t * p ) void Ntl_ModelFree( Ntl_Mod_t * p )
{ {
assert( Ntl_ManCheckNetsAreNotMarked(p) );
if ( p->vRequireds ) Vec_IntFree( p->vRequireds ); if ( p->vRequireds ) Vec_IntFree( p->vRequireds );
if ( p->vArrivals ) Vec_IntFree( p->vArrivals ); if ( p->vArrivals ) Vec_IntFree( p->vArrivals );
if ( p->vDelays ) Vec_IntFree( p->vDelays ); if ( p->vDelays ) Vec_IntFree( p->vDelays );
......
...@@ -131,6 +131,9 @@ Ntl_Obj_t * Ntl_ModelCreateNode( Ntl_Mod_t * pModel, int nFanins ) ...@@ -131,6 +131,9 @@ Ntl_Obj_t * Ntl_ModelCreateNode( Ntl_Mod_t * pModel, int nFanins )
p->Type = NTL_OBJ_NODE; p->Type = NTL_OBJ_NODE;
p->nFanins = nFanins; p->nFanins = nFanins;
p->nFanouts = 1; p->nFanouts = 1;
if ( nFanins == 1 )
pModel->nObjs[NTL_OBJ_LUT1]++;
else
pModel->nObjs[NTL_OBJ_NODE]++; pModel->nObjs[NTL_OBJ_NODE]++;
return p; return p;
} }
...@@ -188,6 +191,30 @@ Ntl_Obj_t * Ntl_ModelDupObj( Ntl_Mod_t * pModel, Ntl_Obj_t * pOld ) ...@@ -188,6 +191,30 @@ Ntl_Obj_t * Ntl_ModelDupObj( Ntl_Mod_t * pModel, Ntl_Obj_t * pOld )
return pNew; return pNew;
} }
/**Function*************************************************************
Synopsis [Creates the primary input with the given name.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntl_Obj_t * Ntl_ModelCreatePiWithName( Ntl_Mod_t * pModel, char * pName )
{
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
pNet = Ntl_ModelFindOrCreateNet( pModel, pName );
if ( pNet->pDriver )
return NULL;
pObj = Ntl_ModelCreatePi( pModel );
Ntl_ModelSetNetDriver( pObj, pNet );
return pObj;
}
/**Function************************************************************* /**Function*************************************************************
Synopsis [Allocates memory and copies the name into it.] Synopsis [Allocates memory and copies the name into it.]
......
...@@ -109,7 +109,7 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck ) ...@@ -109,7 +109,7 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck )
FILE * pFile; FILE * pFile;
Ioa_ReadMan_t * p; Ioa_ReadMan_t * p;
Ntl_Man_t * pDesign; Ntl_Man_t * pDesign;
int nNodes; // int nNodes;
// check that the file is available // check that the file is available
pFile = fopen( pFileName, "rb" ); pFile = fopen( pFileName, "rb" );
...@@ -166,8 +166,8 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck ) ...@@ -166,8 +166,8 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck )
} }
// transform the design by removing the CO drivers // transform the design by removing the CO drivers
if ( (nNodes = Ntl_ManTransformCoDrivers(pDesign)) ) // if ( (nNodes = Ntl_ManReconnectCoDrivers(pDesign)) )
printf( "The design was transformed by removing %d buf/inv CO drivers.\n", nNodes ); // printf( "The design was transformed by removing %d buf/inv CO drivers.\n", nNodes );
//Ioa_WriteBlif( pDesign, "_temp_.blif" ); //Ioa_WriteBlif( pDesign, "_temp_.blif" );
return pDesign; return pDesign;
} }
......
/**CFile****************************************************************
FileName [ntlSweep.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Performs structural sweep of the netlist.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntlSweep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntl.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Detects logic that does not fanout into POs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManSweepMark_rec( Ntl_Man_t * p, Ntl_Obj_t * pObj )
{
Ntl_Net_t * pNet;
int i;
if ( pObj->fMark )
return;
pObj->fMark = 1;
Ntl_ObjForEachFanin( pObj, pNet, i )
Ntl_ManSweepMark_rec( p, pNet->pDriver );
}
/**Function*************************************************************
Synopsis [Detects logic that does not fanout into POs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManSweepMark( Ntl_Man_t * p )
{
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pObj;
int i;
// get the root model
pRoot = Ntl_ManRootModel( p );
// clear net visited flags
Ntl_ModelForEachObj( pRoot, pObj, i )
assert( pObj->fMark == 0 );
// label the primary inputs
Ntl_ModelForEachPi( pRoot, pObj, i )
pObj->fMark = 1;
// start from the primary outputs
Ntl_ModelForEachPo( pRoot, pObj, i )
Ntl_ManSweepMark_rec( p, pObj );
}
/**Function*************************************************************
Synopsis [Derives new netlist by sweeping current netlist with the current AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntl_Man_t * Ntl_ManSweep( Ntl_Man_t * p, Aig_Man_t * pAig, int fVerbose )
{
int nObjsOld[NTL_OBJ_VOID];
Ntl_Man_t * pNew;
Ntl_Mod_t * pRoot;
Ntl_Net_t * pNet;
Ntl_Obj_t * pObj;
int i, k, nNetsOld;
// insert the AIG into the netlist
pNew = Ntl_ManInsertAig( p, pAig );
if ( pNew == NULL )
{
printf( "Ntl_ManSweep(): Inserting AIG has failed.\n" );
return NULL;
}
// remember the number of objects
pRoot = Ntl_ManRootModel( pNew );
for ( i = 0; i < NTL_OBJ_VOID; i++ )
nObjsOld[i] = pRoot->nObjs[i];
nNetsOld = Ntl_ModelCountNets(pRoot);
// mark the nets that do not fanout into POs
Ntl_ManSweepMark( pNew );
// remove the useless objects and their nets
Ntl_ModelForEachObj( pRoot, pObj, i )
{
if ( pObj->fMark )
{
pObj->fMark = 0;
continue;
}
// remove the fanout nets
Ntl_ObjForEachFanout( pObj, pNet, k )
Ntl_ModelDeleteNet( pRoot, Ntl_ObjFanout0(pObj) );
// remove the object
if ( Ntl_ObjIsNode(pObj) && Ntl_ObjFaninNum(pObj) == 1 )
pRoot->nObjs[NTL_OBJ_LUT1]--;
else
pRoot->nObjs[pObj->Type]--;
Vec_PtrWriteEntry( pRoot->vObjs, pObj->Id, NULL );
pObj->Id = NTL_OBJ_NONE;
}
// print detailed statistics of sweeping
if ( fVerbose )
{
printf( "Sweep:" );
printf( " Node = %d (%4.1f %%)",
nObjsOld[NTL_OBJ_NODE] - pRoot->nObjs[NTL_OBJ_NODE],
!nObjsOld[NTL_OBJ_NODE]? 0.0: 100.0 * (nObjsOld[NTL_OBJ_NODE] - pRoot->nObjs[NTL_OBJ_NODE]) / nObjsOld[NTL_OBJ_NODE] );
printf( " Buf/Inv = %d (%4.1f %%)",
nObjsOld[NTL_OBJ_LUT1] - pRoot->nObjs[NTL_OBJ_LUT1],
!nObjsOld[NTL_OBJ_LUT1]? 0.0: 100.0 * (nObjsOld[NTL_OBJ_LUT1] - pRoot->nObjs[NTL_OBJ_LUT1]) / nObjsOld[NTL_OBJ_LUT1] );
printf( " Lat = %d (%4.1f %%)",
nObjsOld[NTL_OBJ_LATCH] - pRoot->nObjs[NTL_OBJ_LATCH],
!nObjsOld[NTL_OBJ_LATCH]? 0.0: 100.0 * (nObjsOld[NTL_OBJ_LATCH] - pRoot->nObjs[NTL_OBJ_LATCH]) / nObjsOld[NTL_OBJ_LATCH] );
printf( " Box = %d (%4.1f %%)",
nObjsOld[NTL_OBJ_BOX] - pRoot->nObjs[NTL_OBJ_BOX],
!nObjsOld[NTL_OBJ_BOX]? 0.0: 100.0 * (nObjsOld[NTL_OBJ_BOX] - pRoot->nObjs[NTL_OBJ_BOX]) / nObjsOld[NTL_OBJ_BOX] );
printf( "\n" );
// printf( "Also, sweep reduced %d nets.\n", nNetsOld - Ntl_ModelCountNets(pRoot) );
}
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...@@ -239,6 +239,26 @@ int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet ) ...@@ -239,6 +239,26 @@ int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet )
return 1; return 1;
} }
/**Function*************************************************************
Synopsis [Finds or creates the net.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ModelCountNets( Ntl_Mod_t * p )
{
Ntl_Net_t * pNet;
int i, Counter = 0;
Ntl_ModelForEachNet( p, pNet, i )
Counter++;
return Counter;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -30,7 +30,28 @@ ...@@ -30,7 +30,28 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [Returns 1 if netlist was written by ABC with added bufs/invs.] Synopsis [Counts COs that are connected to the internal nodes through invs/bufs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ModelCountLut1( Ntl_Mod_t * pRoot )
{
Ntl_Obj_t * pObj;
int i, Counter = 0;
Ntl_ModelForEachNode( pRoot, pObj, i )
if ( Ntl_ObjFaninNum(pObj) == 1 )
Counter++;
return Counter;
}
/**Function*************************************************************
Synopsis [Connects COs to the internal nodes other than inv/bufs.]
Description [Should be called immediately after reading from file.] Description [Should be called immediately after reading from file.]
...@@ -39,6 +60,63 @@ ...@@ -39,6 +60,63 @@
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ntl_ManCountSimpleCoDriversOne( Ntl_Net_t * pNetCo )
{
Ntl_Net_t * pNetFanin;
// skip the case when the net is not driven by a node
if ( !Ntl_ObjIsNode(pNetCo->pDriver) )
return 0;
// skip the case when the node is not an inv/buf
if ( Ntl_ObjFaninNum(pNetCo->pDriver) != 1 )
return 0;
// skip the case when the second-generation driver is not a node
pNetFanin = Ntl_ObjFanin0(pNetCo->pDriver);
if ( !Ntl_ObjIsNode(pNetFanin->pDriver) )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Counts COs that are connected to the internal nodes through invs/bufs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManCountSimpleCoDrivers( Ntl_Man_t * p )
{
Ntl_Net_t * pNetCo;
Ntl_Obj_t * pObj;
Ntl_Mod_t * pRoot;
int i, k, Counter;
Counter = 0;
pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachPo( pRoot, pObj, i )
Counter += Ntl_ManCountSimpleCoDriversOne( Ntl_ObjFanin0(pObj) );
Ntl_ModelForEachLatch( pRoot, pObj, i )
Counter += Ntl_ManCountSimpleCoDriversOne( Ntl_ObjFanin0(pObj) );
Ntl_ModelForEachBox( pRoot, pObj, i )
Ntl_ObjForEachFanin( pObj, pNetCo, k )
Counter += Ntl_ManCountSimpleCoDriversOne( pNetCo );
return Counter;
}
/**Function*************************************************************
Synopsis [Removes the CO drivers that are bufs/invs.]
Description [Should be called immediately after reading from file.]
SideEffects [This procedure does not work because the internal net
(pNetFanin) may have other drivers.]
SeeAlso []
***********************************************************************/
int Ntl_ManTransformCoDrivers( Ntl_Man_t * p ) int Ntl_ManTransformCoDrivers( Ntl_Man_t * p )
{ {
Vec_Ptr_t * vCoNets; Vec_Ptr_t * vCoNets;
...@@ -110,7 +188,71 @@ int Ntl_ManTransformCoDrivers( Ntl_Man_t * p ) ...@@ -110,7 +188,71 @@ int Ntl_ManTransformCoDrivers( Ntl_Man_t * p )
Counter++; Counter++;
} }
Vec_PtrFree( vCoNets ); Vec_PtrFree( vCoNets );
pRoot->nObjs[NTL_OBJ_NODE] -= Counter; pRoot->nObjs[NTL_OBJ_LUT1] -= Counter;
return Counter;
}
/**Function*************************************************************
Synopsis [Connects COs to the internal nodes other than inv/bufs.]
Description [Should be called immediately after reading from file.]
SideEffects [This procedure does not work because the internal net
(pNetFanin) may have other drivers.]
SeeAlso []
***********************************************************************/
int Ntl_ManReconnectCoDriverOne( Ntl_Net_t * pNetCo )
{
Ntl_Net_t * pNetFanin;
// skip the case when the net is not driven by a node
if ( !Ntl_ObjIsNode(pNetCo->pDriver) )
return 0;
// skip the case when the node is not an inv/buf
if ( Ntl_ObjFaninNum(pNetCo->pDriver) != 1 )
return 0;
// skip the case when the second-generation driver is not a node
pNetFanin = Ntl_ObjFanin0(pNetCo->pDriver);
if ( !Ntl_ObjIsNode(pNetFanin->pDriver) )
return 0;
// set the complemented attribute of the net
pNetCo->fCompl = (int)(pNetCo->pDriver->pSop[0] == '0');
// drive the CO net with the second-generation driver
pNetCo->pDriver = NULL;
pNetFanin->pDriver->pFanio[pNetFanin->pDriver->nFanins] = NULL;
if ( !Ntl_ModelSetNetDriver( pNetFanin->pDriver, pNetCo ) )
printf( "Ntl_ManReconnectCoDriverOne(): Cannot connect the net.\n" );
return 1;
}
/**Function*************************************************************
Synopsis [Connects COs to the internal nodes other than inv/bufs.]
Description [Should be called immediately after reading from file.]
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManReconnectCoDrivers( Ntl_Man_t * p )
{
Ntl_Net_t * pNetCo;
Ntl_Obj_t * pObj;
Ntl_Mod_t * pRoot;
int i, k, Counter;
Counter = 0;
pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachPo( pRoot, pObj, i )
Counter += Ntl_ManReconnectCoDriverOne( Ntl_ObjFanin0(pObj) );
Ntl_ModelForEachLatch( pRoot, pObj, i )
Counter += Ntl_ManReconnectCoDriverOne( Ntl_ObjFanin0(pObj) );
Ntl_ModelForEachBox( pRoot, pObj, i )
Ntl_ObjForEachFanin( pObj, pNetCo, k )
Counter += Ntl_ManReconnectCoDriverOne( pNetCo );
return Counter; return Counter;
} }
...@@ -158,6 +300,68 @@ Vec_Ptr_t * Ntl_ManCollectCoNames( Ntl_Man_t * p ) ...@@ -158,6 +300,68 @@ Vec_Ptr_t * Ntl_ManCollectCoNames( Ntl_Man_t * p )
return vNames; return vNames;
} }
/**Function*************************************************************
Synopsis [Marks the CI/CO nets.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManMarkCiCoNets( Ntl_Man_t * p )
{
Ntl_Net_t * pNet;
int i;
Ntl_ManForEachCiNet( p, pNet, i )
pNet->fMark = 1;
Ntl_ManForEachCoNet( p, pNet, i )
pNet->fMark = 1;
}
/**Function*************************************************************
Synopsis [Unmarks the CI/CO nets.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManUnmarkCiCoNets( Ntl_Man_t * p )
{
Ntl_Net_t * pNet;
int i;
Ntl_ManForEachCiNet( p, pNet, i )
pNet->fMark = 0;
Ntl_ManForEachCoNet( p, pNet, i )
pNet->fMark = 0;
}
/**Function*************************************************************
Synopsis [Unmarks the CI/CO nets.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManCheckNetsAreNotMarked( Ntl_Mod_t * pModel )
{
Ntl_Net_t * pNet;
int i;
Ntl_ModelForEachNet( pModel, pNet, i )
assert( pNet->fMark == 0 );
return 1;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -100,7 +100,6 @@ void Nwk_ManPrintLutSizes( Nwk_Man_t * p, If_Lib_t * pLutLib ) ...@@ -100,7 +100,6 @@ void Nwk_ManPrintLutSizes( Nwk_Man_t * p, If_Lib_t * pLutLib )
printf( "LUTs by size: " ); printf( "LUTs by size: " );
for ( i = 0; i <= pLutLib->LutMax; i++ ) for ( i = 0; i <= pLutLib->LutMax; i++ )
printf( "%d:%d ", i, Counters[i] ); printf( "%d:%d ", i, Counters[i] );
printf( "\n" );
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -124,6 +123,7 @@ void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib ) ...@@ -124,6 +123,7 @@ void Nwk_ManPrintStats( Nwk_Man_t * p, If_Lib_t * pLutLib )
printf( "co = %5d ", Nwk_ManCoNum(p) ); printf( "co = %5d ", Nwk_ManCoNum(p) );
printf( "lat = %5d ", Nwk_ManLatchNum(p) ); printf( "lat = %5d ", Nwk_ManLatchNum(p) );
printf( "node = %5d ", Nwk_ManNodeNum(p) ); printf( "node = %5d ", Nwk_ManNodeNum(p) );
printf( "edge = %5d ", Nwk_ManGetTotalFanins(p) );
printf( "aig = %6d ", Nwk_ManGetAigNodeNum(p) ); printf( "aig = %6d ", Nwk_ManGetAigNodeNum(p) );
printf( "lev = %3d ", Nwk_ManLevel(p) ); printf( "lev = %3d ", Nwk_ManLevel(p) );
// printf( "lev2 = %3d ", Nwk_ManLevelBackup(p) ); // printf( "lev2 = %3d ", Nwk_ManLevelBackup(p) );
......
...@@ -725,7 +725,8 @@ bool Abc_NtkCompareBoxes( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb ) ...@@ -725,7 +725,8 @@ bool Abc_NtkCompareBoxes( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
Description [] Description []
SideEffects [] SideEffects [Ordering POs by name is a very bad idea! It destroys
the natural order of the logic in the circuit.]
SeeAlso [] SeeAlso []
......
...@@ -1288,15 +1288,20 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fRetim ...@@ -1288,15 +1288,20 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fRetim
Abc_Ntk_t * Abc_NtkDarLatchSweep( Abc_Ntk_t * pNtk, int fLatchConst, int fLatchEqual, int fVerbose ) Abc_Ntk_t * Abc_NtkDarLatchSweep( Abc_Ntk_t * pNtk, int fLatchConst, int fLatchEqual, int fVerbose )
{ {
Abc_Ntk_t * pNtkAig; Abc_Ntk_t * pNtkAig;
Aig_Man_t * pMan; Aig_Man_t * pMan, * pTemp;
pMan = Abc_NtkToDar( pNtk, 0, 1 ); pMan = Abc_NtkToDar( pNtk, 0, 1 );
if ( pMan == NULL ) if ( pMan == NULL )
return NULL; return NULL;
Aig_ManSeqCleanup( pMan ); // Aig_ManSeqCleanup( pMan );
if ( fLatchConst && pMan->nRegs ) // if ( fLatchConst && pMan->nRegs )
pMan = Aig_ManConstReduce( pMan, fVerbose ); // pMan = Aig_ManConstReduce( pMan, fVerbose );
if ( fLatchEqual && pMan->nRegs ) // if ( fLatchEqual && pMan->nRegs )
pMan = Aig_ManReduceLaches( pMan, fVerbose ); // pMan = Aig_ManReduceLaches( pMan, fVerbose );
if ( pMan->vFlopNums )
Vec_IntFree( pMan->vFlopNums );
pMan->vFlopNums = NULL;
pMan = Aig_ManScl( pTemp = pMan, fLatchConst, fLatchEqual, fVerbose );
Aig_ManStop( pTemp );
pNtkAig = Abc_NtkFromDarSeqSweep( pNtk, pMan ); pNtkAig = Abc_NtkFromDarSeqSweep( pNtk, pMan );
Aig_ManStop( pMan ); Aig_ManStop( pMan );
return pNtkAig; return pNtkAig;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment