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;
} }
......
/**CFile****************************************************************
FileName [ntlEc.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Equivalence checking procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntlEc.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntl.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Adds PIs to both models, so that they have the same PIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManCreateMissingInputs( Ntl_Mod_t * p1, Ntl_Mod_t * p2, int fSeq )
{
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
int i;
Ntl_ModelForEachPi( p1, pObj, i )
{
pNet = Ntl_ModelFindNet( p2, Ntl_ObjFanout0(pObj)->pName );
if ( pNet == NULL )
Ntl_ModelCreatePiWithName( p2, Ntl_ObjFanout0(pObj)->pName );
}
Ntl_ModelForEachPi( p2, pObj, i )
{
pNet = Ntl_ModelFindNet( p1, Ntl_ObjFanout0(pObj)->pName );
if ( pNet == NULL )
Ntl_ModelCreatePiWithName( p1, Ntl_ObjFanout0(pObj)->pName );
}
if ( !fSeq )
{
Ntl_ModelForEachLatch( p1, pObj, i )
{
pNet = Ntl_ModelFindNet( p2, Ntl_ObjFanout0(pObj)->pName );
if ( pNet == NULL )
Ntl_ModelCreatePiWithName( p2, Ntl_ObjFanout0(pObj)->pName );
}
Ntl_ModelForEachLatch( p2, pObj, i )
{
pNet = Ntl_ModelFindNet( p1, Ntl_ObjFanout0(pObj)->pName );
if ( pNet == NULL )
Ntl_ModelCreatePiWithName( p1, Ntl_ObjFanout0(pObj)->pName );
}
}
}
/**Function*************************************************************
Synopsis [Creates arrays of combinational inputs in the same order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManDeriveCommonCis( Ntl_Man_t * pMan1, Ntl_Man_t * pMan2, int fSeq )
{
Ntl_Mod_t * p1 = Ntl_ManRootModel(pMan1);
Ntl_Mod_t * p2 = Ntl_ManRootModel(pMan2);
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
int i;
if ( fSeq )
assert( Ntl_ModelPiNum(p1) == Ntl_ModelPiNum(p2) );
else
assert( Ntl_ModelCiNum(p1) == Ntl_ModelCiNum(p2) );
// order the CIs
Vec_PtrClear( pMan1->vCis );
Vec_PtrClear( pMan2->vCis );
Ntl_ModelForEachPi( p1, pObj, i )
{
pNet = Ntl_ModelFindNet( p2, Ntl_ObjFanout0(pObj)->pName );
if ( pNet == NULL )
{
printf( "Ntl_ManDeriveCommonCis(): Internal error!\n" );
return;
}
Vec_PtrPush( pMan1->vCis, pObj );
Vec_PtrPush( pMan2->vCis, pNet->pDriver );
}
if ( !fSeq )
{
Ntl_ModelForEachLatch( p1, pObj, i )
{
pNet = Ntl_ModelFindNet( p2, Ntl_ObjFanout0(pObj)->pName );
if ( pNet == NULL )
{
printf( "Ntl_ManDeriveCommonCis(): Internal error!\n" );
return;
}
Vec_PtrPush( pMan1->vCis, pObj );
Vec_PtrPush( pMan2->vCis, pNet->pDriver );
}
}
}
/**Function*************************************************************
Synopsis [Creates arrays of combinational outputs in the same order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManDeriveCommonCos( Ntl_Man_t * pMan1, Ntl_Man_t * pMan2, int fSeq )
{
Ntl_Mod_t * p1 = Ntl_ManRootModel(pMan1);
Ntl_Mod_t * p2 = Ntl_ManRootModel(pMan2);
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
int i;
// if ( fSeq )
// assert( Ntl_ModelPoNum(p1) == Ntl_ModelPoNum(p2) );
// else
// assert( Ntl_ModelCoNum(p1) == Ntl_ModelCoNum(p2) );
// remember PO in the corresponding net of the second design
Ntl_ModelForEachPo( p2, pObj, i )
Ntl_ObjFanin0(pObj)->pCopy = pObj;
// order the COs
Vec_PtrClear( pMan1->vCos );
Vec_PtrClear( pMan2->vCos );
Ntl_ModelForEachPo( p1, pObj, i )
{
pNet = Ntl_ModelFindNet( p2, Ntl_ObjFanin0(pObj)->pName );
if ( pNet == NULL )
{
printf( "Ntl_ManDeriveCommonCos(): Cannot find output %s in the second design. Skipping it!\n",
Ntl_ObjFanin0(pObj)->pName );
continue;
}
Vec_PtrPush( pMan1->vCos, pObj );
Vec_PtrPush( pMan2->vCos, pNet->pCopy );
}
if ( !fSeq )
{
Ntl_ModelForEachLatch( p2, pObj, i )
Ntl_ObjFanin0(pObj)->pCopy = pObj;
Ntl_ModelForEachLatch( p1, pObj, i )
{
pNet = Ntl_ModelFindNet( p2, Ntl_ObjFanin0(pObj)->pName );
if ( pNet == NULL )
{
printf( "Ntl_ManDeriveCommonCos(): Cannot find output %s in the second design. Skipping it!\n",
Ntl_ObjFanin0(pObj)->pName );
continue;
}
Vec_PtrPush( pMan1->vCos, pObj );
Vec_PtrPush( pMan2->vCos, pNet->pCopy );
}
}
}
/**Function*************************************************************
Synopsis [Prepares AIGs for combinational equivalence checking.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntl_ManPrepareCec( char * pFileName1, char * pFileName2, Aig_Man_t ** ppMan1, Aig_Man_t ** ppMan2 )
{
Ntl_Man_t * pMan1, * pMan2;
Ntl_Mod_t * pModel1, * pModel2;
*ppMan1 = NULL;
*ppMan2 = NULL;
// read the netlists
pMan1 = Ioa_ReadBlif( pFileName1, 1 );
pMan2 = Ioa_ReadBlif( pFileName2, 1 );
if ( !pMan1 || !pMan2 )
{
if ( pMan1 ) Ntl_ManFree( pMan1 );
if ( pMan2 ) Ntl_ManFree( pMan2 );
printf( "Ntl_ManPrepareCec(): Reading designs from file has failed.\n" );
return;
}
// make sure they are compatible
pModel1 = Ntl_ManRootModel( pMan1 );
pModel2 = Ntl_ManRootModel( pMan2 );
if ( Ntl_ModelCiNum(pModel1) != Ntl_ModelCiNum(pModel2) )
{
printf( "Warning: The number of inputs in the designs is different (%d and %d).\n",
Ntl_ModelCiNum(pModel1), Ntl_ModelCiNum(pModel2) );
}
if ( Ntl_ModelCoNum(pModel1) != Ntl_ModelCoNum(pModel2) )
{
printf( "Warning: The number of outputs in the designs is different (%d and %d).\n",
Ntl_ModelCoNum(pModel1), Ntl_ModelCoNum(pModel2) );
}
// normalize inputs/outputs
Ntl_ManCreateMissingInputs( pModel1, pModel2, 0 );
Ntl_ManDeriveCommonCis( pMan1, pMan2, 0 );
Ntl_ManDeriveCommonCos( pMan1, pMan2, 0 );
if ( Vec_PtrSize(pMan1->vCos) == 0 )
{
printf( "Ntl_ManPrepareCec(): There is no identically-named primary outputs to compare.\n" );
if ( pMan1 ) Ntl_ManFree( pMan1 );
if ( pMan2 ) Ntl_ManFree( pMan2 );
return;
}
// derive AIGs
*ppMan1 = Ntl_ManCollapseForCec( pMan1 );
*ppMan2 = Ntl_ManCollapseForCec( pMan2 );
// cleanup
Ntl_ManFree( pMan1 );
Ntl_ManFree( pMan2 );
}
/**Function*************************************************************
Synopsis [Prepares AIGs for sequential equivalence checking.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ntl_ManPrepareSec( char * pFileName1, char * pFileName2 )
{
Aig_Man_t * pAig;
Ntl_Man_t * pMan1, * pMan2;
Ntl_Mod_t * pModel1, * pModel2;
// read the netlists
pMan1 = Ioa_ReadBlif( pFileName1, 1 );
pMan2 = Ioa_ReadBlif( pFileName2, 1 );
if ( !pMan1 || !pMan2 )
{
if ( pMan1 ) Ntl_ManFree( pMan1 );
if ( pMan2 ) Ntl_ManFree( pMan2 );
printf( "Ntl_ManPrepareSec(): Reading designs from file has failed.\n" );
return NULL;
}
// make sure they are compatible
pModel1 = Ntl_ManRootModel( pMan1 );
pModel2 = Ntl_ManRootModel( pMan2 );
if ( Ntl_ModelLatchNum(pModel1) == 0 || Ntl_ModelLatchNum(pModel2) == 0 )
{
if ( pMan1 ) Ntl_ManFree( pMan1 );
if ( pMan2 ) Ntl_ManFree( pMan2 );
printf( "Ntl_ManPrepareSec(): The designs have no latches. Used combinational command \"*cec\".\n" );
return NULL;
}
if ( Ntl_ModelPiNum(pModel1) != Ntl_ModelPiNum(pModel2) )
{
printf( "Warning: The number of inputs in the designs is different (%d and %d).\n",
Ntl_ModelPiNum(pModel1), Ntl_ModelPiNum(pModel2) );
}
if ( Ntl_ModelPoNum(pModel1) != Ntl_ModelPoNum(pModel2) )
{
printf( "Warning: The number of outputs in the designs is different (%d and %d).\n",
Ntl_ModelPoNum(pModel1), Ntl_ModelPoNum(pModel2) );
}
// normalize inputs/outputs
Ntl_ManCreateMissingInputs( pModel1, pModel2, 1 );
Ntl_ManDeriveCommonCis( pMan1, pMan2, 1 );
Ntl_ManDeriveCommonCos( pMan1, pMan2, 1 );
if ( Vec_PtrSize(pMan1->vCos) == 0 )
{
printf( "Ntl_ManPrepareSec(): There is no identically-named primary outputs to compare.\n" );
if ( pMan1 ) Ntl_ManFree( pMan1 );
if ( pMan2 ) Ntl_ManFree( pMan2 );
return NULL;
}
// derive AIGs
pAig = Ntl_ManCollapseForSec( pMan1, pMan2 );
// cleanup
pMan1->pAig = pMan2->pAig = NULL;
Ntl_ManFree( pMan1 );
Ntl_ManFree( pMan2 );
return pAig;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...@@ -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 []
......
...@@ -218,6 +218,7 @@ static int Abc_CommandAbc8Lutpack ( Abc_Frame_t * pAbc, int argc, char ** arg ...@@ -218,6 +218,7 @@ static int Abc_CommandAbc8Lutpack ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandAbc8Balance ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Balance ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Speedup ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Speedup ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Fraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Fraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Sweep ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Cec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Cec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Scl ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Scl ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8Lcorr ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc8Lcorr ( Abc_Frame_t * pAbc, int argc, char ** argv );
...@@ -456,6 +457,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) ...@@ -456,6 +457,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC8", "*b", Abc_CommandAbc8Balance, 0 ); Cmd_CommandAdd( pAbc, "ABC8", "*b", Abc_CommandAbc8Balance, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*speedup", Abc_CommandAbc8Speedup, 0 ); Cmd_CommandAdd( pAbc, "ABC8", "*speedup", Abc_CommandAbc8Speedup, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*fraig", Abc_CommandAbc8Fraig, 0 ); Cmd_CommandAdd( pAbc, "ABC8", "*fraig", Abc_CommandAbc8Fraig, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*sw", Abc_CommandAbc8Sweep, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*cec", Abc_CommandAbc8Cec, 0 ); Cmd_CommandAdd( pAbc, "ABC8", "*cec", Abc_CommandAbc8Cec, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*scl", Abc_CommandAbc8Scl, 0 ); Cmd_CommandAdd( pAbc, "ABC8", "*scl", Abc_CommandAbc8Scl, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*lcorr", Abc_CommandAbc8Lcorr, 0 ); Cmd_CommandAdd( pAbc, "ABC8", "*lcorr", Abc_CommandAbc8Lcorr, 0 );
...@@ -14868,8 +14870,8 @@ int Abc_CommandAbc8Write( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -14868,8 +14870,8 @@ int Abc_CommandAbc8Write( Abc_Frame_t * pAbc, int argc, char ** argv )
int fAig; int fAig;
int c; int c;
extern void Ioa_WriteBlif( void * p, char * pFileName ); extern void Ioa_WriteBlif( void * p, char * pFileName );
extern int Ntl_ManInsertNtk( void * p, void * pNtk ); extern void * Ntl_ManInsertNtk( void * p, void * pNtk );
extern int Ntl_ManInsertAig( void * p, Aig_Man_t * pAig ); extern void * Ntl_ManInsertAig( void * p, Aig_Man_t * pAig );
extern void * Ntl_ManDup( void * pOld ); extern void * Ntl_ManDup( void * pOld );
extern void Ntl_ManFree( void * p ); extern void Ntl_ManFree( void * p );
...@@ -14895,16 +14897,19 @@ int Abc_CommandAbc8Write( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -14895,16 +14897,19 @@ int Abc_CommandAbc8Write( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1; return 1;
} }
// create the design to write // create the design to write
pTemp = Ntl_ManDup( pAbc->pAbc8Ntl ); pFileName = argv[globalUtilOptind];
if ( fAig ) if ( fAig )
{ {
if ( pAbc->pAbc8Aig != NULL ) if ( pAbc->pAbc8Aig != NULL )
{ {
if ( !Ntl_ManInsertAig( pTemp, pAbc->pAbc8Aig ) ) pTemp = Ntl_ManInsertAig( pAbc->pAbc8Ntl, pAbc->pAbc8Aig );
if ( pTemp == NULL )
{ {
printf( "Abc_CommandAbc8Write(): Inserting AIG has failed.\n" ); printf( "Abc_CommandAbc8Write(): Inserting AIG has failed.\n" );
return 1; return 1;
} }
Ioa_WriteBlif( pTemp, pFileName );
Ntl_ManFree( pTemp );
} }
else else
{ {
...@@ -14916,19 +14921,22 @@ int Abc_CommandAbc8Write( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -14916,19 +14921,22 @@ int Abc_CommandAbc8Write( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
if ( pAbc->pAbc8Nwk != NULL ) if ( pAbc->pAbc8Nwk != NULL )
{ {
if ( !Ntl_ManInsertNtk( pTemp, pAbc->pAbc8Nwk ) ) pTemp = Ntl_ManInsertNtk( pAbc->pAbc8Ntl, pAbc->pAbc8Nwk );
if ( pTemp == NULL )
{ {
printf( "Abc_CommandAbc8Write(): Inserting mapped network has failed.\n" ); printf( "Abc_CommandAbc8Write(): Inserting mapped network has failed.\n" );
return 1; return 1;
} }
Ioa_WriteBlif( pTemp, pFileName );
Ntl_ManFree( pTemp );
} }
else else
{
pTemp = pAbc->pAbc8Ntl;
printf( "Writing the original design.\n" ); printf( "Writing the original design.\n" );
}
// get the input file name
pFileName = argv[globalUtilOptind];
Ioa_WriteBlif( pTemp, pFileName ); Ioa_WriteBlif( pTemp, pFileName );
Ntl_ManFree( pTemp ); }
}
return 0; return 0;
usage: usage:
...@@ -15093,8 +15101,6 @@ int Abc_CommandAbc8If( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -15093,8 +15101,6 @@ int Abc_CommandAbc8If( Abc_Frame_t * pAbc, int argc, char ** argv )
If_Par_t Pars, * pPars = &Pars; If_Par_t Pars, * pPars = &Pars;
void * pNtkNew; void * pNtkNew;
int c; int c;
extern int Ntl_ManInsertTest( void * p, Aig_Man_t * pAig );
extern int Ntl_ManInsertTestIf( void * p, Aig_Man_t * pAig );
extern void * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars ); extern void * Nwk_MappingIf( Aig_Man_t * p, Tim_Man_t * pManTime, If_Par_t * pPars );
extern Tim_Man_t * Ntl_ManReadTimeMan( void * p ); extern Tim_Man_t * Ntl_ManReadTimeMan( void * p );
extern If_Lib_t * If_SetSimpleLutLib( int nLutSize ); extern If_Lib_t * If_SetSimpleLutLib( int nLutSize );
...@@ -15126,15 +15132,7 @@ int Abc_CommandAbc8If( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -15126,15 +15132,7 @@ int Abc_CommandAbc8If( Abc_Frame_t * pAbc, int argc, char ** argv )
printf( "Abc_CommandAbc8Write(): There is no AIG to map.\n" ); printf( "Abc_CommandAbc8Write(): There is no AIG to map.\n" );
return 1; return 1;
} }
/*
// get the input file name
if ( !Ntl_ManInsertTestIf( pAbc->pAbc8Ntl, pAbc->pAbc8Aig ) )
// if ( !Ntl_ManInsertTest( pAbc->pAbc8Ntl, pAbc->pAbc8Aig ) )
{
printf( "Abc_CommandAbc8Write(): Tranformation of the netlist has failed.\n" );
return 1;
}
*/
pNtkNew = Nwk_MappingIf( pAbc->pAbc8Aig, Ntl_ManReadTimeMan(pAbc->pAbc8Ntl), pPars ); pNtkNew = Nwk_MappingIf( pAbc->pAbc8Aig, Ntl_ManReadTimeMan(pAbc->pAbc8Ntl), pPars );
if ( pNtkNew == NULL ) if ( pNtkNew == NULL )
{ {
...@@ -16053,6 +16051,78 @@ usage: ...@@ -16053,6 +16051,78 @@ usage:
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_CommandAbc8Sweep( Abc_Frame_t * pAbc, int argc, char ** argv )
{
void * pNtlNew;
int fVerbose;
int c;
extern void * Ntl_ManSweep( void * p, Aig_Man_t * pAig, int fVerbose );
extern Aig_Man_t * Ntl_ManExtract( void * p );
// set defaults
fVerbose = 1;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
{
switch ( c )
{
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Ntl == NULL )
{
printf( "Abc_CommandAbc8Sweep(): There is no design to sweep.\n" );
return 1;
}
if ( pAbc->pAbc8Aig == NULL )
{
printf( "Abc_CommandAbc8Sweep(): There is no AIG to use.\n" );
return 1;
}
// sweep the current design
pNtlNew = Ntl_ManSweep( pAbc->pAbc8Ntl, pAbc->pAbc8Aig, fVerbose );
if ( pNtlNew == NULL )
{
printf( "Abc_CommandAbc8Sweep(): Sweeping has failed.\n" );
return 1;
}
// replace
Abc_FrameClearDesign();
pAbc->pAbc8Ntl = pNtlNew;
pAbc->pAbc8Aig = Ntl_ManExtract( pAbc->pAbc8Ntl );
if ( pAbc->pAbc8Aig == NULL )
{
printf( "Abc_CommandAbc8Sweep(): AIG extraction has failed.\n" );
return 1;
}
return 0;
usage:
fprintf( stdout, "usage: *sw [-h]\n" );
fprintf( stdout, "\t reads the design with whiteboxes\n" );
fprintf( stdout, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandAbc8Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandAbc8Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
Aig_Man_t * pAig1, * pAig2; Aig_Man_t * pAig1, * pAig2;
...@@ -16064,11 +16134,12 @@ int Abc_CommandAbc8Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -16064,11 +16134,12 @@ int Abc_CommandAbc8Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
int nConfLimit; int nConfLimit;
int fSmart; int fSmart;
int nPartSize; int nPartSize;
extern Aig_Man_t * Ntl_ManCollapse( void * p ); extern Aig_Man_t * Ntl_ManCollapse( void * p, int fSeq );
extern void * Ntl_ManDup( void * pOld ); extern void * Ntl_ManDup( void * pOld );
extern void Ntl_ManFree( void * p ); extern void Ntl_ManFree( void * p );
extern int Ntl_ManInsertNtk( void * p, void * pNtk ); extern void * Ntl_ManInsertNtk( void * p, void * pNtk );
extern void Ntl_ManPrepareCec( char * pFileName1, char * pFileName2, Aig_Man_t ** ppMan1, Aig_Man_t ** ppMan2 );
extern int Fra_FraigCecTop( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimit, int nPartSize, int fSmart, int fVerbose ); extern int Fra_FraigCecTop( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimit, int nPartSize, int fSmart, int fVerbose );
// set defaults // set defaults
...@@ -16116,31 +16187,42 @@ int Abc_CommandAbc8Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -16116,31 +16187,42 @@ int Abc_CommandAbc8Cec( Abc_Frame_t * pAbc, int argc, char ** argv )
pArgvNew = argv + globalUtilOptind; pArgvNew = argv + globalUtilOptind;
nArgcNew = argc - globalUtilOptind; nArgcNew = argc - globalUtilOptind;
if ( nArgcNew != 0 ) if ( nArgcNew != 0 && nArgcNew != 2 )
{
printf( "Currently can only compare current mapped network against the spec, or designs derived from two files.\n" );
return 0;
}
if ( nArgcNew == 2 )
{ {
printf( "Currently can only compare current network against the spec.\n" ); Ntl_ManPrepareCec( pArgvNew[0], pArgvNew[1], &pAig1, &pAig2 );
if ( !pAig1 || !pAig2 )
return 1;
Fra_FraigCecTop( pAig1, pAig2, nConfLimit, nPartSize, fSmart, fVerbose );
Aig_ManStop( pAig1 );
Aig_ManStop( pAig2 );
return 0; return 0;
} }
if ( pAbc->pAbc8Ntl == NULL ) if ( pAbc->pAbc8Ntl == NULL )
{ {
printf( "Abc_CommandAbc8Cec(): There is no design to verify.\n" ); printf( "Abc_CommandAbc8Cec(): There is no design to verify.\n" );
return 0; return 1;
} }
if ( pAbc->pAbc8Nwk == NULL ) if ( pAbc->pAbc8Nwk == NULL )
{ {
printf( "Abc_CommandAbc8Cec(): There is no mapped network to verify.\n" ); printf( "Abc_CommandAbc8Cec(): There is no mapped network to verify.\n" );
return 0; return 1;
} }
// derive AIGs // derive AIGs
pAig1 = Ntl_ManCollapse( pAbc->pAbc8Ntl ); pAig1 = Ntl_ManCollapse( pAbc->pAbc8Ntl, 0 );
pTemp = Ntl_ManDup( pAbc->pAbc8Ntl ); pTemp = Ntl_ManInsertNtk( pAbc->pAbc8Ntl, pAbc->pAbc8Nwk );
if ( !Ntl_ManInsertNtk( pTemp, pAbc->pAbc8Nwk ) ) if ( pTemp == NULL )
{ {
printf( "Abc_CommandAbc8Cec(): Inserting the design has failed.\n" ); printf( "Abc_CommandAbc8Cec(): Inserting the design has failed.\n" );
return 1; return 1;
} }
pAig2 = Ntl_ManCollapse( pTemp ); pAig2 = Ntl_ManCollapse( pTemp, 0 );
Ntl_ManFree( pTemp ); Ntl_ManFree( pTemp );
// perform verification // perform verification
...@@ -16160,7 +16242,7 @@ usage: ...@@ -16160,7 +16242,7 @@ usage:
fprintf( stdout, "\tfile1 : (optional) the file with the first network\n"); fprintf( stdout, "\tfile1 : (optional) the file with the first network\n");
fprintf( stdout, "\tfile2 : (optional) the file with the second network\n"); fprintf( stdout, "\tfile2 : (optional) the file with the second network\n");
fprintf( stdout, "\t if no files are given, uses the current network and its spec\n"); fprintf( stdout, "\t if no files are given, uses the current network and its spec\n");
fprintf( stdout, "\t if one file is given, uses the current network and the file\n"); fprintf( stdout, "\t if two files are given, compares designs derived from files\n");
return 1; return 1;
} }
...@@ -16177,7 +16259,77 @@ usage: ...@@ -16177,7 +16259,77 @@ usage:
***********************************************************************/ ***********************************************************************/
int Abc_CommandAbc8Scl( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandAbc8Scl( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
Aig_Man_t * pAigNew;
int c;
int fLatchConst;
int fLatchEqual;
int fVerbose;
extern Aig_Man_t * Ntl_ManScl( void * p, Aig_Man_t * pAig, int fLatchConst, int fLatchEqual, int fVerbose );
extern int Ntl_ManIsComb( void * p );
// set defaults
fLatchConst = 1;
fLatchEqual = 1;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "cevh" ) ) != EOF )
{
switch ( c )
{
case 'c':
fLatchConst ^= 1;
break;
case 'e':
fLatchEqual ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Ntl == NULL )
{
printf( "Abc_CommandAbc8Scl(): There is no design to SAT sweep.\n" );
return 1;
}
if ( pAbc->pAbc8Aig == NULL )
{
printf( "Abc_CommandAbc8Scl(): There is no AIG to SAT sweep.\n" );
return 1;
}
if ( Ntl_ManIsComb(pAbc->pAbc8Ntl) )
{
fprintf( stdout, "The network is combinational (run \"*fraig\").\n" );
return 0;
}
// get the input file name
pAigNew = Ntl_ManScl( pAbc->pAbc8Ntl, pAbc->pAbc8Aig, fLatchConst, fLatchEqual, fVerbose );
if ( pAigNew == NULL )
{
printf( "Abc_CommandAbc8Scl(): Tranformation of the AIG has failed.\n" );
return 1;
}
if ( pAbc->pAbc8Aig )
Aig_ManStop( pAbc->pAbc8Aig );
pAbc->pAbc8Aig = pAigNew;
return 0; return 0;
usage:
fprintf( stdout, "usage: *scl [-cevh]\n" );
fprintf( stdout, "\t performs sequential cleanup of the current network\n" );
fprintf( stdout, "\t by removing nodes and latches that do not feed into POs\n" );
fprintf( stdout, "\t-c : sweep stuck-at latches detected by ternary simulation [default = %s]\n", fLatchConst? "yes": "no" );
fprintf( stdout, "\t-e : merge equal latches (same data inputs and init states) [default = %s]\n", fLatchEqual? "yes": "no" );
fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -16193,7 +16345,92 @@ int Abc_CommandAbc8Scl( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -16193,7 +16345,92 @@ int Abc_CommandAbc8Scl( Abc_Frame_t * pAbc, int argc, char ** argv )
***********************************************************************/ ***********************************************************************/
int Abc_CommandAbc8Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandAbc8Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
Aig_Man_t * pAigNew;
int c;
int nFramesP;
int nConfMax;
int fVerbose;
extern Aig_Man_t * Ntl_ManLcorr( void * p, Aig_Man_t * pAig, int nConfMax, int fVerbose );
extern int Ntl_ManIsComb( void * p );
// set defaults
nFramesP = 0;
nConfMax = 10000;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "PCvh" ) ) != EOF )
{
switch ( c )
{
case 'P':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-P\" should be followed by an integer.\n" );
goto usage;
}
nFramesP = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nFramesP < 0 )
goto usage;
break;
case 'C':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-C\" should be followed by an integer.\n" );
goto usage;
}
nConfMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nConfMax < 0 )
goto usage;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Ntl == NULL )
{
printf( "Abc_CommandAbc8Ssw(): There is no design to SAT sweep.\n" );
return 1;
}
if ( pAbc->pAbc8Aig == NULL )
{
printf( "Abc_CommandAbc8Ssw(): There is no AIG to SAT sweep.\n" );
return 1;
}
if ( Ntl_ManIsComb(pAbc->pAbc8Ntl) )
{
fprintf( stdout, "The network is combinational (run \"*fraig\").\n" );
return 0; return 0;
}
// get the input file name
pAigNew = Ntl_ManLcorr( pAbc->pAbc8Ntl, pAbc->pAbc8Aig, nConfMax, fVerbose );
if ( pAigNew == NULL )
{
printf( "Abc_CommandAbc8Ssw(): Tranformation of the AIG has failed.\n" );
return 1;
}
if ( pAbc->pAbc8Aig )
Aig_ManStop( pAbc->pAbc8Aig );
pAbc->pAbc8Aig = pAigNew;
return 0;
usage:
fprintf( stdout, "usage: *lcorr [-C num] [-vh]\n" );
fprintf( stdout, "\t computes latch correspondence using 1-step induction\n" );
// fprintf( stdout, "\t-P num : number of time frames to use as the prefix [default = %d]\n", nFramesP );
fprintf( stdout, "\t-C num : max conflict number when proving latch equivalence [default = %d]\n", nConfMax );
fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -16209,7 +16446,184 @@ int Abc_CommandAbc8Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -16209,7 +16446,184 @@ int Abc_CommandAbc8Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
***********************************************************************/ ***********************************************************************/
int Abc_CommandAbc8Ssw( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandAbc8Ssw( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
Aig_Man_t * pAigNew;
Fra_Ssw_t Pars, * pPars = &Pars;
int c;
extern Aig_Man_t * Ntl_ManSsw( void * p, Aig_Man_t * pAig, Fra_Ssw_t * pPars );
extern int Ntl_ManIsComb( void * p );
// set defaults
pPars->nPartSize = 0;
pPars->nOverSize = 0;
pPars->nFramesP = 0;
pPars->nFramesK = 1;
pPars->nMaxImps = 5000;
pPars->nMaxLevs = 0;
pPars->fUseImps = 0;
pPars->fRewrite = 0;
pPars->fFraiging = 0;
pPars->fLatchCorr = 0;
pPars->fWriteImps = 0;
pPars->fUse1Hot = 0;
pPars->fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "PQNFILirfletvh" ) ) != EOF )
{
switch ( c )
{
case 'P':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-P\" should be followed by an integer.\n" );
goto usage;
}
pPars->nPartSize = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nPartSize < 2 )
goto usage;
break;
case 'Q':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-Q\" should be followed by an integer.\n" );
goto usage;
}
pPars->nOverSize = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nOverSize < 0 )
goto usage;
break;
case 'N':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-N\" should be followed by an integer.\n" );
goto usage;
}
pPars->nFramesP = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nFramesP < 0 )
goto usage;
break;
case 'F':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-F\" should be followed by an integer.\n" );
goto usage;
}
pPars->nFramesK = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nFramesK <= 0 )
goto usage;
break;
case 'I':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-I\" should be followed by an integer.\n" );
goto usage;
}
pPars->nMaxImps = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nMaxImps <= 0 )
goto usage;
break;
case 'L':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-L\" should be followed by an integer.\n" );
goto usage;
}
pPars->nMaxLevs = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nMaxLevs <= 0 )
goto usage;
break;
case 'i':
pPars->fUseImps ^= 1;
break;
case 'r':
pPars->fRewrite ^= 1;
break;
case 'f':
pPars->fFraiging ^= 1;
break;
case 'l':
pPars->fLatchCorr ^= 1;
break;
case 'e':
pPars->fWriteImps ^= 1;
break;
case 't':
pPars->fUse1Hot ^= 1;
break;
case 'v':
pPars->fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pAbc->pAbc8Ntl == NULL )
{
printf( "Abc_CommandAbc8Ssw(): There is no design to SAT sweep.\n" );
return 1;
}
if ( pAbc->pAbc8Aig == NULL )
{
printf( "Abc_CommandAbc8Ssw(): There is no AIG to SAT sweep.\n" );
return 1;
}
if ( Ntl_ManIsComb(pAbc->pAbc8Ntl) )
{
fprintf( stdout, "The network is combinational (run \"*fraig\").\n" );
return 0;
}
if ( pPars->nFramesK > 1 && pPars->fUse1Hot )
{
printf( "Currrently can only use one-hotness for simple induction (K=1).\n" );
return 0; return 0;
}
if ( pPars->nFramesP && pPars->fUse1Hot )
{
printf( "Currrently can only use one-hotness without prefix.\n" );
return 0;
}
// get the input file name
pAigNew = Ntl_ManSsw( pAbc->pAbc8Ntl, pAbc->pAbc8Aig, pPars );
if ( pAigNew == NULL )
{
printf( "Abc_CommandAbc8Ssw(): Tranformation of the AIG has failed.\n" );
return 1;
}
if ( pAbc->pAbc8Aig )
Aig_ManStop( pAbc->pAbc8Aig );
pAbc->pAbc8Aig = pAigNew;
return 0;
usage:
fprintf( stdout, "usage: *ssw [-PQNFL num] [-lrfetvh]\n" );
fprintf( stdout, "\t performs sequential sweep using K-step induction\n" );
fprintf( stdout, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize );
fprintf( stdout, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize );
fprintf( stdout, "\t-N num : number of time frames to use as the prefix [default = %d]\n", pPars->nFramesP );
fprintf( stdout, "\t-F num : number of time frames for induction (1=simple) [default = %d]\n", pPars->nFramesK );
fprintf( stdout, "\t-L num : max number of levels to consider (0=all) [default = %d]\n", pPars->nMaxLevs );
// fprintf( stdout, "\t-I num : max number of implications to consider [default = %d]\n", pPars->nMaxImps );
// fprintf( stdout, "\t-i : toggle using implications [default = %s]\n", pPars->fUseImps? "yes": "no" );
fprintf( stdout, "\t-l : toggle latch correspondence only [default = %s]\n", pPars->fLatchCorr? "yes": "no" );
fprintf( stdout, "\t-r : toggle AIG rewriting [default = %s]\n", pPars->fRewrite? "yes": "no" );
fprintf( stdout, "\t-f : toggle fraiging (combinational SAT sweeping) [default = %s]\n", pPars->fFraiging? "yes": "no" );
fprintf( stdout, "\t-e : toggle writing implications as assertions [default = %s]\n", pPars->fWriteImps? "yes": "no" );
fprintf( stdout, "\t-t : toggle using one-hotness conditions [default = %s]\n", pPars->fUse1Hot? "yes": "no" );
fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
return 1;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -16225,7 +16639,85 @@ int Abc_CommandAbc8Ssw( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -16225,7 +16639,85 @@ int Abc_CommandAbc8Ssw( Abc_Frame_t * pAbc, int argc, char ** argv )
***********************************************************************/ ***********************************************************************/
int Abc_CommandAbc8DSec( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandAbc8DSec( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
Aig_Man_t * pAig;
char ** pArgvNew;
int nArgcNew;
int c;
int fRetimeFirst;
int fFraiging;
int fVerbose;
int fVeryVerbose;
int nFrames;
extern int Fra_FraigSec( Aig_Man_t * p, int nFramesMax, int fRetimeFirst, int fFraiging, int fVerbose, int fVeryVerbose );
extern Aig_Man_t * Ntl_ManPrepareSec( char * pFileName1, char * pFileName2 );
// set defaults
nFrames = 16;
fRetimeFirst = 1;
fFraiging = 1;
fVerbose = 0;
fVeryVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Krfwvh" ) ) != EOF )
{
switch ( c )
{
case 'K':
if ( globalUtilOptind >= argc )
{
fprintf( stdout, "Command line switch \"-K\" should be followed by an integer.\n" );
goto usage;
}
nFrames = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nFrames < 0 )
goto usage;
break;
case 'r':
fRetimeFirst ^= 1;
break;
case 'f':
fFraiging ^= 1;
break;
case 'w':
fVeryVerbose ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
default:
goto usage;
}
}
pArgvNew = argv + globalUtilOptind;
nArgcNew = argc - globalUtilOptind;
if ( nArgcNew != 2 )
{
printf( "Only works for two designs written from files specified on the command line.\n" );
return 1;
}
pAig = Ntl_ManPrepareSec( pArgvNew[0], pArgvNew[1] );
Fra_FraigSec( pAig, nFrames, fRetimeFirst, fFraiging, fVerbose, fVeryVerbose );
Aig_ManStop( pAig );
return 0; return 0;
usage:
fprintf( stdout, "usage: *dsec [-K num] [-rfwvh] <file1> <file2>\n" );
fprintf( stdout, "\t performs sequential equivalence checking for two designs\n" );
fprintf( stdout, "\t-K num : the limit on the depth of induction [default = %d]\n", nFrames );
fprintf( stdout, "\t-r : toggles forward retiming at the beginning [default = %s]\n", fRetimeFirst? "yes": "no" );
fprintf( stdout, "\t-f : toggles the internal use of fraiging [default = %s]\n", fFraiging? "yes": "no" );
fprintf( stdout, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( stdout, "\t-w : toggles additional verbose output [default = %s]\n", fVeryVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n");
fprintf( stdout, "\tfile1 : the file with the first design\n");
fprintf( stdout, "\tfile2 : the file with the second design\n");
// fprintf( stdout, "\t if no files are given, uses the current network and its spec\n");
// fprintf( stdout, "\t if one file is given, uses the current network and the file\n");
return 1;
} }
......
...@@ -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