Commit e258fcb2 by Alan Mishchenko

Version abc80326

parent 85207c75
......@@ -3050,15 +3050,19 @@ SOURCE=.\src\aig\ntl\ntl.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntl\ntlAig.c
SOURCE=.\src\aig\ntl\ntlCheck.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntl\ntlCheck.c
SOURCE=.\src\aig\ntl\ntlCore.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntl\ntlExtract.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntl\ntlDfs.c
SOURCE=.\src\aig\ntl\ntlInsert.c
# End Source File
# Begin Source File
......@@ -3089,6 +3093,42 @@ SOURCE=.\src\aig\ntl\ntlTime.c
SOURCE=.\src\aig\ntl\ntlWriteBlif.c
# End Source File
# End Group
# Begin Group "ntk"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\aig\ntk\ntk.h
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkDfs.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkFanio.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkMan.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkMap.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkObj.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkTiming.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ntk\ntkUtil.c
# End Source File
# End Group
# Begin Group "tim"
# PROP Default_Filter ""
......
......@@ -47,6 +47,7 @@ extern "C" {
typedef struct Aig_Man_t_ Aig_Man_t;
typedef struct Aig_Obj_t_ Aig_Obj_t;
typedef struct Aig_Box_t_ Aig_Box_t;
typedef struct Aig_MmFixed_t_ Aig_MmFixed_t;
typedef struct Aig_MmFlex_t_ Aig_MmFlex_t;
typedef struct Aig_MmStep_t_ Aig_MmStep_t;
......@@ -61,7 +62,8 @@ typedef enum {
AIG_OBJ_AND, // 5: AND node
AIG_OBJ_EXOR, // 6: EXOR node
AIG_OBJ_LATCH, // 7: latch
AIG_OBJ_VOID // 8: unused object
AIG_OBJ_BOX, // 8: latch
AIG_OBJ_VOID // 9: unused object
} Aig_Type_t;
// the AIG node
......@@ -71,11 +73,11 @@ struct Aig_Obj_t_ // 8 words
Aig_Obj_t * pFanin0; // fanin
Aig_Obj_t * pFanin1; // fanin
Aig_Obj_t * pHaig; // pointer to the HAIG node
unsigned int Type : 3; // object type
unsigned int Type : 4; // object type
unsigned int fPhase : 1; // value under 000...0 pattern
unsigned int fMarkA : 1; // multipurpose mask
unsigned int fMarkB : 1; // multipurpose mask
unsigned int nRefs : 26; // reference count
unsigned int nRefs : 25; // reference count
unsigned Level : 24; // the level of this node
unsigned nCuts : 8; // the number of cuts
int TravId; // unique ID of last traversal involving the node
......@@ -87,6 +89,16 @@ struct Aig_Obj_t_ // 8 words
};
};
// the AIG box
struct Aig_Box_t_
{
int nInputs; // the number of box inputs (POs)
int i1Input; // the first PO of the interval
int nOutputs; // the number of box outputs (PIs)
int i1Output; // the first PI of the interval
float ** pTable; // the delay table of the box
};
// the AIG manager
struct Aig_Man_t_
{
......@@ -317,6 +329,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_ObjEquiv( Aig_Man_t * p, Aig_Obj_t * pObj ) { return p->pEquivs? p->pEquivs[pObj->Id] : NULL; }
static inline Aig_Obj_t * Aig_ObjHaig( Aig_Obj_t * pObj ) { assert( Aig_Regular(pObj)->pHaig ); return Aig_NotCond( Aig_Regular(pObj)->pHaig, Aig_IsComplement(pObj) ); }
static inline int Aig_ObjPioNum( Aig_Obj_t * pObj ) { assert( !Aig_ObjIsNode(pObj) ); return (int)pObj->pNext; }
static inline int Aig_ObjWhatFanin( Aig_Obj_t * pObj, Aig_Obj_t * pFanin )
{
if ( Aig_ObjFanin0(pObj) == pFanin ) return 0;
......@@ -597,6 +610,9 @@ extern void Aig_ManPrintVerbose( Aig_Man_t * p, int fHaig );
extern void Aig_ManDump( Aig_Man_t * p );
extern void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName );
extern void Aig_ManDumpVerilog( Aig_Man_t * p, char * pFileName );
extern void Aig_ManSetPioNumbers( Aig_Man_t * p );
extern void Aig_ManCleanPioNumbers( Aig_Man_t * p );
/*=== aigWin.c =========================================================*/
extern void Aig_ManFindCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVisited, int nSizeLimit, int nFanoutLimit );
......
......@@ -85,7 +85,7 @@ Aig_Man_t * Aig_ManStart( int nNodesMax )
Aig_Man_t * Aig_ManStartFrom( Aig_Man_t * p )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj;
Aig_Obj_t * pObj, * pObjNew;
int i;
// create the new manager
pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
......@@ -93,7 +93,11 @@ Aig_Man_t * Aig_ManStartFrom( Aig_Man_t * p )
// create the PIs
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
Aig_ManForEachPi( p, pObj, i )
pObj->pData = Aig_ObjCreatePi(pNew);
{
pObjNew = Aig_ObjCreatePi( pNew );
pObjNew->Level = pObj->Level;
pObj->pData = pObjNew;
}
return pNew;
}
......@@ -154,17 +158,11 @@ Aig_Man_t * Aig_ManDup( Aig_Man_t * p, int fOrdered )
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
if ( fOrdered )
{
Aig_ManForEachObj( p, pObj, i )
{
if ( Aig_ObjIsBuf(pObj) )
{
if ( pNew->pManHaig == NULL )
......@@ -187,28 +185,70 @@ Aig_Man_t * Aig_ManDup( Aig_Man_t * p, int fOrdered )
pObj->pData = pObjNew;
}
}
else if ( Aig_ObjIsPi(pObj) )
{
pObjNew = Aig_ObjCreatePi( pNew );
pObjNew->pHaig = pObj->pHaig;
pObjNew->Level = pObj->Level;
pObj->pData = pObjNew;
}
else if ( Aig_ObjIsPo(pObj) )
{
pObjNew = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
pObjNew->pHaig = pObj->pHaig;
pObj->pData = pObjNew;
}
else
assert( 0 );
}
}
else
{
/*
Aig_ManForEachPi( p, pObj, i )
{
pObjNew = Aig_ObjCreatePi( pNew );
pObjNew->pHaig = pObj->pHaig;
pObjNew->Level = pObj->Level;
pObj->pData = pObjNew;
}
*/
Aig_ManForEachObj( p, pObj, i )
if ( !Aig_ObjIsPo(pObj) )
{
Aig_ManDup_rec( pNew, p, pObj );
assert( pObj->Level == ((Aig_Obj_t*)pObj->pData)->Level );
if ( Aig_ObjIsPi(pObj) )
{
pObjNew = Aig_ObjCreatePi( pNew );
pObjNew->pHaig = pObj->pHaig;
pObjNew->Level = pObj->Level;
pObj->pData = pObjNew;
}
else if ( Aig_ObjIsPo(pObj) )
{
Aig_ManDup_rec( pNew, p, Aig_ObjFanin0(pObj) );
// assert( pObj->Level == ((Aig_Obj_t*)pObj->pData)->Level );
pObjNew = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
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;
}
*/
}
// add the POs
assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
// pass the HAIG to the new AIG
p->pManHaig = NULL;
Aig_ManForEachObj( p, pObj, i )
pObj->pHaig = NULL;
// 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" );
......
......@@ -848,6 +848,48 @@ void Aig_ManDumpVerilog( Aig_Man_t * p, char * pFileName )
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
Synopsis [Sets the PI/PO numbers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManSetPioNumbers( Aig_Man_t * p )
{
Aig_Obj_t * pObj;
int i;
Aig_ManForEachPi( p, pObj, i )
pObj->pNext = (Aig_Obj_t *)i;
Aig_ManForEachPo( p, pObj, i )
pObj->pNext = (Aig_Obj_t *)i;
}
/**Function*************************************************************
Synopsis [Sets the PI/PO numbers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManCleanPioNumbers( Aig_Man_t * p )
{
Aig_Obj_t * pObj;
int i;
Aig_ManForEachPi( p, pObj, i )
pObj->pNext = NULL;
Aig_ManForEachPo( p, pObj, i )
pObj->pNext = NULL;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......
......@@ -212,6 +212,11 @@ int Bdc_ManDecompose( Bdc_Man_t * p, unsigned * puFunc, unsigned * puCare, int n
p->nWords = Kit_TruthWordNum( nVars );
p->nNodesMax = nNodesMax;
Bdc_ManPrepare( p, vDivs );
if ( puCare && Kit_TruthIsConst0( puCare, nVars ) )
{
p->pRoot = Bdc_Not(p->pNodes);
return 0;
}
// copy the function
Bdc_IsfStart( p, pIsf );
if ( puCare )
......
......@@ -91,7 +91,7 @@ extern int Dar_ManRefactor( Aig_Man_t * pAig, Dar_RefPar_t * pPars )
extern Aig_Man_t * Dar_ManRewriteDefault( Aig_Man_t * pAig );
extern Aig_Man_t * Dar_ManRwsat( Aig_Man_t * pAig, int fBalance, int fVerbose );
extern Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fVerbose );
extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fVerbose );
extern Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fVerbose );
extern Aig_Man_t * Dar_ManChoice( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int nConfMax, int nLevelMax, int fVerbose );
#ifdef __cplusplus
......
......@@ -19,6 +19,7 @@
***********************************************************************/
#include "darInt.h"
#include "tim.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -62,10 +63,50 @@ Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel )
// map the PI nodes
Aig_ManCleanData( p );
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
Aig_ManForEachPi( p, pObj, i )
pObj->pData = Aig_ObjCreatePi(pNew);
// balance the AIG
vStore = Vec_VecAlloc( 50 );
if ( p->pManTime != NULL )
{
float arrTime;
Tim_ManIncrementTravId( p->pManTime );
Aig_ManSetPioNumbers( p );
Aig_ManForEachObj( p, pObj, i )
{
if ( Aig_ObjIsAnd(pObj) || Aig_ObjIsConst1(pObj) )
continue;
if ( Aig_ObjIsPi(pObj) )
{
// copy the PI
pObjNew = Aig_ObjCreatePi(pNew);
pObj->pData = pObjNew;
// set the arrival time of the new PI
arrTime = Tim_ManGetPiArrival( p->pManTime, Aig_ObjPioNum(pObj) );
pObjNew->Level = (int)arrTime;
}
else if ( Aig_ObjIsPo(pObj) )
{
// perform balancing
pDriver = Aig_ObjReal_rec( Aig_ObjChild0(pObj) );
pObjNew = Dar_Balance_rec( pNew, Aig_Regular(pDriver), vStore, 0, fUpdateLevel );
pObjNew = Aig_NotCond( pObjNew, Aig_IsComplement(pDriver) );
Aig_ObjCreatePo( pNew, pObjNew );
// save arrival time of the output
arrTime = (float)Aig_Regular(pObjNew)->Level;
Tim_ManSetPoArrival( p->pManTime, Aig_ObjPioNum(pObj), arrTime );
}
else
assert( 0 );
}
Aig_ManCleanPioNumbers( p );
pNew->pManTime = Tim_ManDup( p->pManTime, 0 );
}
else
{
Aig_ManForEachPi( p, pObj, i )
{
pObjNew = Aig_ObjCreatePi(pNew);
pObjNew->Level = pObj->Level;
pObj->pData = pObjNew;
}
Aig_ManForEachPo( p, pObj, i )
{
pDriver = Aig_ObjReal_rec( Aig_ObjChild0(pObj) );
......@@ -73,12 +114,10 @@ Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel )
pObjNew = Aig_NotCond( pObjNew, Aig_IsComplement(pDriver) );
Aig_ObjCreatePo( pNew, pObjNew );
}
}
Vec_VecFree( vStore );
// remove dangling nodes
if ( (i = Aig_ManCleanup( pNew )) )
{
// printf( "Cleanup after balancing removed %d dangling nodes.\n", i );
}
Aig_ManCleanup( pNew );
// check the resulting AIG
if ( !Aig_ManCheck(pNew) )
printf( "Dar_ManBalance(): The check has failed.\n" );
......
......@@ -181,6 +181,14 @@ Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, i
Aig_ManStop( pTemp );
if ( fVerbose ) Aig_ManPrintStats( pAig );
// balance
if ( fBalance )
{
pAig = Dar_ManBalance( pTemp = pAig, fUpdateLevel );
Aig_ManStop( pTemp );
if ( fVerbose ) Aig_ManPrintStats( pAig );
}
return pAig;
}
......@@ -195,7 +203,7 @@ Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, i
SeeAlso []
***********************************************************************/
Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fVerbose )
Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fFanout, int fVerbose )
//alias compress2 "b -l; rw -l; rf -l; b -l; rw -l; rwz -l; b -l; rfz -l; rwz -l; b -l"
{
Aig_Man_t * pTemp;
......@@ -208,6 +216,7 @@ Aig_Man_t * Dar_ManCompress2( Aig_Man_t * pAig, int fBalance, int fUpdateLevel,
pParsRwr->fUpdateLevel = fUpdateLevel;
pParsRef->fUpdateLevel = fUpdateLevel;
pParsRwr->fFanout = fFanout;
pParsRwr->fVerbose = 0;//fVerbose;
pParsRef->fVerbose = 0;//fVerbose;
......@@ -310,7 +319,7 @@ Vec_Ptr_t * Dar_ManChoiceSynthesis( Aig_Man_t * pAig, int fBalance, int fUpdateL
Vec_PtrPush( vAigs, pAig );
pAig = Dar_ManCompress (pAig, 0, fUpdateLevel, fVerbose);
Vec_PtrPush( vAigs, pAig );
pAig = Dar_ManCompress2(pAig, fBalance, fUpdateLevel, fVerbose);
pAig = Dar_ManCompress2(pAig, fBalance, fUpdateLevel, 1, fVerbose);
Vec_PtrPush( vAigs, pAig );
return vAigs;
}
......
/**CFile****************************************************************
FileName [ntkDfs.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [DFS traversals.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkDfs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManDfs_rec( Ntk_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
Ntk_Obj_t * pNext;
int i;
if ( Ntk_ObjIsTravIdCurrent( pNode ) )
return;
Ntk_ObjSetTravIdCurrent( pNode );
Ntk_ObjForEachFanin( pNode, pNext, i )
Ntk_ManDfs_rec( pNext, vNodes );
Vec_PtrPush( vNodes, pNode );
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of all objects except latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Ntk_ManDfs( Ntk_Man_t * pNtk )
{
Vec_Ptr_t * vNodes;
Ntk_Obj_t * pObj;
int i;
Ntk_ManIncrementTravId( pNtk );
vNodes = Vec_PtrAlloc( 100 );
Ntk_ManForEachPo( pNtk, pObj, i )
Ntk_ManDfs_rec( pObj, vNodes );
return vNodes;
}
/**Function*************************************************************
Synopsis [Performs DFS for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManDfsReverse_rec( Ntk_Obj_t * pNode, Vec_Ptr_t * vNodes )
{
Ntk_Obj_t * pNext;
int i;
if ( Ntk_ObjIsTravIdCurrent( pNode ) )
return;
Ntk_ObjSetTravIdCurrent( pNode );
Ntk_ObjForEachFanout( pNode, pNext, i )
Ntk_ManDfsReverse_rec( pNext, vNodes );
Vec_PtrPush( vNodes, pNode );
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of all objects except latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Ntk_ManDfsReverse( Ntk_Man_t * pNtk )
{
Vec_Ptr_t * vNodes;
Ntk_Obj_t * pObj;
int i;
Ntk_ManIncrementTravId( pNtk );
vNodes = Vec_PtrAlloc( 100 );
Ntk_ManForEachPi( pNtk, pObj, i )
Ntk_ManDfsReverse_rec( pObj, vNodes );
return vNodes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntkMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Network manager.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates the netlist manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntk_Man_t * Ntk_ManAlloc()
{
Ntk_Man_t * p;
p = ALLOC( Ntk_Man_t, 1 );
memset( p, 0, sizeof(Ntk_Man_t) );
p->vCis = Vec_PtrAlloc( 1000 );
p->vCos = Vec_PtrAlloc( 1000 );
p->vObjs = Vec_PtrAlloc( 1000 );
p->vTemp = Vec_PtrAlloc( 1000 );
p->nFanioPlus = 4;
p->pMemObjs = Aig_MmFlexStart();
return p;
}
/**Function*************************************************************
Synopsis [Deallocates the netlist manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManFree( Ntk_Man_t * p )
{
if ( p->pName ) free( p->pName );
if ( p->pSpec ) free( p->pSpec );
if ( p->vCis ) Vec_PtrFree( p->vCis );
if ( p->vCos ) Vec_PtrFree( p->vCos );
if ( p->vObjs ) Vec_PtrFree( p->vObjs );
if ( p->vTemp ) Vec_PtrFree( p->vTemp );
if ( p->pAig ) Aig_ManStop( p->pAig );
if ( p->pManTime ) Tim_ManStop( p->pManTime );
if ( p->pMemObjs ) Aig_MmFlexStop( p->pMemObjs, 0 );
free( p );
}
/**Function*************************************************************
Synopsis [Deallocates the netlist manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManPrintStats( Ntk_Man_t * p )
{
printf( "%-15s : ", p->pName );
printf( "pi = %5d ", Ntk_ManPiNum(p) );
printf( "po = %5d ", Ntk_ManPoNum(p) );
printf( "ci = %5d ", Ntk_ManCiNum(p) );
printf( "co = %5d ", Ntk_ManCoNum(p) );
printf( "lat = %5d ", Ntk_ManLatchNum(p) );
printf( "box = %5d ", Ntk_ManBoxNum(p) );
printf( "node = %5d ", Ntk_ManNodeNum(p) );
printf( "aig = %6d ", Aig_ManNodeNum(p->pAig) );
printf( "\n" );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntkMap.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Interface to technology mapping.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkMap.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntkObj.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Manipulation of objects.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkObj.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates an object.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreateObj( Ntk_Man_t * p, int nFanins, int nFanouts )
{
Ntk_Obj_t * pObj;
pObj = (Ntk_Obj_t *)Aig_MmFlexEntryFetch( p->pMemObjs, sizeof(Ntk_Obj_t) + (nFanins + nFanouts + p->nFanioPlus) * sizeof(Ntk_Obj_t *) );
memset( pObj, 0, sizeof(Ntk_Obj_t) );
pObj->Id = Vec_PtrSize( p->vObjs );
Vec_PtrPush( p->vObjs, pObj );
pObj->pMan = p;
pObj->nFanioAlloc = nFanins + nFanouts + p->nFanioPlus;
return pObj;
}
/**Function*************************************************************
Synopsis [Creates a primary input.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreatePi( Ntk_Man_t * p )
{
Ntk_Obj_t * pObj;
pObj = Ntk_ManCreateObj( p, 1, 1 );
Vec_PtrPush( p->vCis, pObj );
pObj->Type = NTK_OBJ_CI;
p->nObjs[NTK_OBJ_CI]++;
return pObj;
}
/**Function*************************************************************
Synopsis [Creates a primary output.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreatePo( Ntk_Man_t * p )
{
Ntk_Obj_t * pObj;
pObj = Ntk_ManCreateObj( p, 1, 1 );
Vec_PtrPush( p->vCos, pObj );
pObj->Type = NTK_OBJ_CO;
p->nObjs[NTK_OBJ_CO]++;
return pObj;
}
/**Function*************************************************************
Synopsis [Creates a latch.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreateLatch( Ntk_Man_t * p )
{
Ntk_Obj_t * pObj;
pObj = Ntk_ManCreateObj( p, 1, 1 );
pObj->Type = NTK_OBJ_LATCH;
p->nObjs[NTK_OBJ_LATCH]++;
return pObj;
}
/**Function*************************************************************
Synopsis [Creates a node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreateNode( Ntk_Man_t * p, int nFanins, int nFanouts )
{
Ntk_Obj_t * pObj;
pObj = Ntk_ManCreateObj( p, nFanins, nFanouts );
pObj->Type = NTK_OBJ_NODE;
p->nObjs[NTK_OBJ_NODE]++;
return pObj;
}
/**Function*************************************************************
Synopsis [Creates a box.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ntk_Obj_t * Ntk_ManCreateBox( Ntk_Man_t * p, int nFanins, int nFanouts )
{
Ntk_Obj_t * pObj;
pObj = Ntk_ManCreateObj( p, nFanins, nFanouts );
pObj->Type = NTK_OBJ_BOX;
p->nObjs[NTK_OBJ_BOX]++;
return pObj;
}
/**Function*************************************************************
Synopsis [Deletes the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManDeleteNode( Ntk_Obj_t * pObj )
{
Vec_Ptr_t * vNodes = pObj->pMan->vTemp;
Ntk_Obj_t * pTemp;
int i;
// delete fanins and fanouts
Ntk_ObjCollectFanouts( pObj, vNodes );
Vec_PtrForEachEntry( vNodes, pTemp, i )
Ntk_ObjDeleteFanin( pTemp, pObj );
Ntk_ObjCollectFanins( pObj, vNodes );
Vec_PtrForEachEntry( vNodes, pTemp, i )
Ntk_ObjDeleteFanin( pObj, pTemp );
// remove from the list of objects
Vec_PtrWriteEntry( pObj->pMan->vObjs, pObj->Id, NULL );
pObj->pMan->nObjs[pObj->Type]--;
memset( pObj, 0, sizeof(Ntk_Obj_t) );
pObj->Id = -1;
}
/**Function*************************************************************
Synopsis [Deletes the node and MFFC of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManDeleteNode_rec( Ntk_Obj_t * pObj )
{
Vec_Ptr_t * vNodes;
int i;
assert( !Ntk_ObjIsPi(pObj) );
assert( Ntk_ObjFanoutNum(pObj) == 0 );
vNodes = Vec_PtrAlloc( 100 );
Ntk_ObjCollectFanins( pObj, vNodes );
Ntk_ManDeleteNode( pObj );
Vec_PtrForEachEntry( vNodes, pObj, i )
if ( Ntk_ObjIsNode(pObj) && Ntk_ObjFanoutNum(pObj) == 0 )
Ntk_ManDeleteNode_rec( pObj );
Vec_PtrFree( vNodes );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntkUtil.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Various utilities.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntkUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Increments the current traversal ID of the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ntk_ManIncrementTravId( Ntk_Man_t * pNtk )
{
Ntk_Obj_t * pObj;
int i;
if ( pNtk->nTravIds >= (1<<26)-1 )
{
pNtk->nTravIds = 0;
Ntk_ManForEachObj( pNtk, pObj, i )
pObj->TravId = 0;
}
pNtk->nTravIds++;
}
/**Function*************************************************************
Synopsis [Reads the maximum number of fanins.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntk_ManGetFaninMax( Ntk_Man_t * pNtk )
{
Ntk_Obj_t * pNode;
int i, nFaninsMax = 0;
Ntk_ManForEachNode( pNtk, pNode, i )
{
if ( nFaninsMax < Ntk_ObjFaninNum(pNode) )
nFaninsMax = Ntk_ObjFaninNum(pNode);
}
return nFaninsMax;
}
/**Function*************************************************************
Synopsis [Reads the total number of all fanins.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntk_ManGetTotalFanins( Ntk_Man_t * pNtk )
{
Ntk_Obj_t * pNode;
int i, nFanins = 0;
Ntk_ManForEachNode( pNtk, pNode, i )
nFanins += Ntk_ObjFaninNum(pNode);
return nFanins;
}
/**Function*************************************************************
Synopsis [Computes the number of logic levels not counting PIs/POs.]
Description [Assumes topological ordering of the nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
int Ntk_ManLevel( Ntk_Man_t * pNtk )
{
Ntk_Obj_t * pObj, * pFanin;
int i, k, LevelMax;
Ntk_ManForEachPi( pNtk, pObj, i )
Ntk_ObjSetLevel( pObj, 0 );
Ntk_ManForEachNode( pNtk, pObj, i )
{
LevelMax = 0;
Ntk_ObjForEachFanin( pObj, pFanin, k )
if ( LevelMax < Ntk_ObjLevel(pFanin) )
LevelMax = Ntk_ObjLevel(pFanin);
Ntk_ObjSetLevel( pFanin, LevelMax+1 );
}
LevelMax = 0;
Ntk_ManForEachPo( pNtk, pObj, i )
if ( LevelMax < Ntk_ObjLevel(pObj) )
LevelMax = Ntk_ObjLevel(pObj);
return LevelMax;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntk_ManPiNum( Ntk_Man_t * pNtk )
{
Ntk_Obj_t * pNode;
int i, Counter = 0;
Ntk_ManForEachPi( pNtk, pNode, i )
Counter++;
return Counter;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntk_ManPoNum( Ntk_Man_t * pNtk )
{
Ntk_Obj_t * pNode;
int i, Counter = 0;
Ntk_ManForEachPo( pNtk, pNode, i )
Counter++;
return Counter;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntk_.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntk_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntk.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
SRC += src/aig/ntl/ntlAig.c \
src/aig/ntl/ntlCheck.c \
src/aig/ntl/ntlDfs.c \
SRC += src/aig/ntl/ntlCheck.c \
src/aig/ntl/ntlCore.c \
src/aig/ntl/ntlExtract.c \
src/aig/ntl/ntlInsert.c \
src/aig/ntl/ntlMan.c \
src/aig/ntl/ntlMap.c \
src/aig/ntl/ntlObj.c \
......
......@@ -102,8 +102,8 @@ struct Ntl_Obj_t_
unsigned Id : 27; // object ID
unsigned MarkA : 1; // temporary mark
unsigned MarkB : 1; // temporary mark
short nFanins; // the number of fanins
short nFanouts; // the number of fanouts
int nFanins; // the number of fanins
int nFanouts; // the number of fanouts
union { // functionality
Ntl_Mod_t * pImplem; // model (for boxes)
char * pSop; // SOP (for logic nodes)
......@@ -219,19 +219,18 @@ static inline void Ntl_ObjSetFanout( Ntl_Obj_t * p, Ntl_Net_t * pNet, int
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== ntlAig.c ==========================================================*/
extern Aig_Obj_t * Ntl_ManExtractAigNode( Ntl_Obj_t * pNode );
extern int Ntl_ManExtract( Ntl_Man_t * p );
extern int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping );
extern int Ntl_ManInsertTest( Ntl_Man_t * p );
extern int Ntl_ManInsertTestFpga( Ntl_Man_t * p );
extern int Ntl_ManInsertTestIf( Ntl_Man_t * p );
/*=== ntlCore.c ==========================================================*/
extern int Ntl_ManInsertTest( Ntl_Man_t * p, Aig_Man_t * pAig );
extern int Ntl_ManInsertTestIf( Ntl_Man_t * p, Aig_Man_t * pAig );
/*=== ntlExtract.c ==========================================================*/
extern Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p );
extern char * Ntl_SopFromTruth( Ntl_Man_t * p, unsigned * pTruth, int nVars, Vec_Int_t * vCover );
/*=== ntlInsert.c ==========================================================*/
extern int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig );
/*=== ntlCheck.c ==========================================================*/
extern int Ntl_ManCheck( Ntl_Man_t * pMan );
extern int Ntl_ModelCheck( Ntl_Mod_t * pModel );
extern void Ntl_ModelFixNonDrivenNets( Ntl_Mod_t * pModel );
/*=== ntlDfs.c ==========================================================*/
extern int Ntl_ManDfs( Ntl_Man_t * p );
/*=== ntlMan.c ============================================================*/
extern Ntl_Man_t * Ntl_ManAlloc( char * pFileName );
extern void Ntl_ManFree( Ntl_Man_t * p );
......
/**CFile****************************************************************
FileName [ntlCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [DFS traversal.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntlCore.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntl.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Extracts AIG from the netlist.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ntl_ManPerformSynthesis( Aig_Man_t * pAig )
{
extern Aig_Man_t * Dar_ManBalance( Aig_Man_t * pAig, int fUpdateLevel );
extern Aig_Man_t * Dar_ManCompress( Aig_Man_t * pAig, int fBalance, int fUpdateLevel, int fVerbose );
Aig_Man_t * pTemp;
// perform synthesis
//printf( "Pre-synthesis AIG: " );
//Aig_ManPrintStats( pAig );
// pTemp = Dar_ManBalance( pAig, 1 );
pTemp = Dar_ManCompress( pAig, 1, 1, 0 );
//printf( "Post-synthesis AIG: " );
//Aig_ManPrintStats( pTemp );
return pTemp;
}
/**Function*************************************************************
Synopsis [Testing procedure for insertion of mapping into the netlist.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManInsertTest( Ntl_Man_t * p, Aig_Man_t * pAig )
{
Vec_Ptr_t * vMapping;
int RetValue;
vMapping = Ntl_MappingFromAig( pAig );
RetValue = Ntl_ManInsert( p, vMapping, pAig );
Vec_PtrFree( vMapping );
return RetValue;
}
/**Function*************************************************************
Synopsis [Testing procedure for insertion of mapping into the netlist.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManInsertTestIf( Ntl_Man_t * p, Aig_Man_t * pAig )
{
Vec_Ptr_t * vMapping;
int RetValue;
vMapping = Ntl_MappingIf( p, pAig );
RetValue = Ntl_ManInsert( p, vMapping, pAig );
Vec_PtrFree( vMapping );
return RetValue;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntlDfs.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [DFS traversal.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntlDfs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntl.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Collects the nodes in a topological order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManDfs_rec( Ntl_Man_t * p, Ntl_Net_t * pNet )
{
Ntl_Obj_t * pObj;
Ntl_Net_t * pNetFanin;
int i;
// skip visited
if ( pNet->nVisits == 2 )
return 1;
// if the node is on the path, this is a combinational loop
if ( pNet->nVisits == 1 )
return 0;
// mark the node as the one on the path
pNet->nVisits = 1;
// derive the box
pObj = pNet->pDriver;
assert( Ntl_ObjIsNode(pObj) || Ntl_ObjIsBox(pObj) );
// visit the input nets of the box
Ntl_ObjForEachFanin( pObj, pNetFanin, i )
if ( !Ntl_ManDfs_rec( p, pNetFanin ) )
return 0;
// add box inputs/outputs to COs/CIs
if ( Ntl_ObjIsBox(pObj) )
{
int LevelCur, LevelMax = -AIG_INFINITY;
Vec_IntPush( p->vBox1Cos, Aig_ManPoNum(p->pAig) );
Ntl_ObjForEachFanin( pObj, pNetFanin, i )
{
LevelCur = Aig_ObjLevel( Aig_Regular(pNetFanin->pFunc) );
LevelMax = AIG_MAX( LevelMax, LevelCur );
Vec_PtrPush( p->vCos, pNetFanin );
Aig_ObjCreatePo( p->pAig, pNetFanin->pFunc );
}
Ntl_ObjForEachFanout( pObj, pNetFanin, i )
{
Vec_PtrPush( p->vCis, pNetFanin );
pNetFanin->pFunc = Aig_ObjCreatePi( p->pAig );
Aig_ObjSetLevel( pNetFanin->pFunc, LevelMax + 1 );
}
//printf( "Creating fake PO with ID = %d.\n", Aig_ManPo(p->pAig, Vec_IntEntryLast(p->vBox1Cos))->Id );
}
// store the node
Vec_PtrPush( p->vNodes, pObj );
if ( Ntl_ObjIsNode(pObj) )
pNet->pFunc = Ntl_ManExtractAigNode( pObj );
pNet->nVisits = 2;
return 1;
}
/**Function*************************************************************
Synopsis [Performs DFS.]
Description [Checks for combinational loops. Collects PI/PO nets.
Collects nodes in the topological order.]
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManDfs( Ntl_Man_t * p )
{
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
int i, nUselessObjects;
assert( Vec_PtrSize(p->vCis) == 0 );
assert( Vec_PtrSize(p->vCos) == 0 );
assert( Vec_PtrSize(p->vNodes) == 0 );
assert( Vec_IntSize(p->vBox1Cos) == 0 );
// get the root model
pRoot = Vec_PtrEntry( p->vModels, 0 );
// collect primary inputs
Ntl_ModelForEachPi( pRoot, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
Vec_PtrPush( p->vCis, pNet );
pNet->pFunc = Aig_ObjCreatePi( p->pAig );
if ( pNet->nVisits )
{
printf( "Ntl_ManDfs(): Primary input appears twice in the list.\n" );
return 0;
}
pNet->nVisits = 2;
}
// collect latch outputs
Ntl_ModelForEachLatch( pRoot, pObj, i )
{
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
Vec_PtrPush( p->vCis, pNet );
pNet->pFunc = Aig_ObjCreatePi( p->pAig );
if ( pNet->nVisits )
{
printf( "Ntl_ManDfs(): Latch output is duplicated or defined as a primary input.\n" );
return 0;
}
pNet->nVisits = 2;
}
// visit the nodes starting from primary outputs
Ntl_ModelForEachPo( pRoot, pObj, i )
{
pNet = Ntl_ObjFanin0(pObj);
if ( !Ntl_ManDfs_rec( p, pNet ) )
{
printf( "Ntl_ManDfs(): Error: Combinational loop is detected.\n" );
Vec_PtrClear( p->vCis );
Vec_PtrClear( p->vCos );
Vec_PtrClear( p->vNodes );
return 0;
}
Vec_PtrPush( p->vCos, pNet );
Aig_ObjCreatePo( p->pAig, pNet->pFunc );
}
// visit the nodes starting from latch inputs outputs
Ntl_ModelForEachLatch( pRoot, pObj, i )
{
pNet = Ntl_ObjFanin0(pObj);
if ( !Ntl_ManDfs_rec( p, pNet ) )
{
printf( "Ntl_ManDfs(): Error: Combinational loop is detected.\n" );
Vec_PtrClear( p->vCis );
Vec_PtrClear( p->vCos );
Vec_PtrClear( p->vNodes );
return 0;
}
Vec_PtrPush( p->vCos, pNet );
Aig_ObjCreatePo( p->pAig, pNet->pFunc );
}
// report the number of dangling objects
nUselessObjects = Ntl_ModelNodeNum(pRoot) + Ntl_ModelBoxNum(pRoot) - Vec_PtrSize(p->vNodes);
if ( nUselessObjects )
printf( "The number of nodes that do not feed into POs = %d.\n", nUselessObjects );
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [ntlInsert.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Netlist representation.]
Synopsis [Procedures to insert mapping into a design.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: ntlInsert.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "ntl.h"
#include "kit.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Inserts the given mapping into the netlist.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
{
char Buffer[100];
Vec_Ptr_t * vCopies;
Vec_Int_t * vCover;
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pNode;
Ntl_Net_t * pNet, * pNetCo;
Ntl_Lut_t * pLut;
int i, k, nDigits;
// map the AIG back onto the design
Ntl_ManForEachCiNet( p, pNet, i )
pNet->pFunc = Aig_ManPi( pAig, i );
Ntl_ManForEachCoNet( p, pNet, i )
pNet->pFunc = Aig_ObjChild0( Aig_ManPo( pAig, i ) );
// remove old nodes
pRoot = Vec_PtrEntry( p->vModels, 0 );
Ntl_ModelForEachNode( pRoot, pNode, i )
Vec_PtrWriteEntry( pRoot->vObjs, pNode->Id, NULL );
// start mapping of AIG nodes into their copies
vCopies = Vec_PtrStart( Aig_ManObjNumMax(pAig) );
Ntl_ManForEachCiNet( p, pNet, i )
Vec_PtrWriteEntry( vCopies, pNet->pFunc->Id, pNet );
// create a new node for each LUT
vCover = Vec_IntAlloc( 1 << 16 );
nDigits = Aig_Base10Log( Vec_PtrSize(vMapping) );
Vec_PtrForEachEntry( vMapping, pLut, i )
{
pNode = Ntl_ModelCreateNode( pRoot, pLut->nFanins );
pNode->pSop = Ntl_SopFromTruth( p, pLut->pTruth, pLut->nFanins, vCover );
if ( !Kit_TruthIsConst0(pLut->pTruth, pLut->nFanins) && !Kit_TruthIsConst1(pLut->pTruth, pLut->nFanins) )
{
for ( k = 0; k < pLut->nFanins; k++ )
{
pNet = Vec_PtrEntry( vCopies, pLut->pFanins[k] );
if ( pNet == NULL )
{
printf( "Ntl_ManInsert(): Internal error: Net not found.\n" );
return 0;
}
Ntl_ObjSetFanin( pNode, pNet, k );
}
}
sprintf( Buffer, "lut%0*d", nDigits, i );
if ( (pNet = Ntl_ModelFindNet( pRoot, Buffer )) )
{
printf( "Ntl_ManInsert(): Internal error: Intermediate net name is not unique.\n" );
return 0;
}
pNet = Ntl_ModelFindOrCreateNet( pRoot, Buffer );
if ( !Ntl_ModelSetNetDriver( pNode, pNet ) )
{
printf( "Ntl_ManInsert(): Internal error: Net has more than one fanin.\n" );
return 0;
}
Vec_PtrWriteEntry( vCopies, pLut->Id, pNet );
}
Vec_IntFree( vCover );
// mark CIs and outputs of the registers
Ntl_ManForEachCiNet( p, pNetCo, i )
pNetCo->nVisits = 101;
// update the CO pointers
Ntl_ManForEachCoNet( p, pNetCo, i )
{
if ( pNetCo->nVisits == 101 )
continue;
pNetCo->nVisits = 101;
pNet = Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pFunc)->Id );
pNode = Ntl_ModelCreateNode( pRoot, 1 );
pNode->pSop = Aig_IsComplement(pNetCo->pFunc)? Ntl_ManStoreSop( p, "0 1\n" ) : Ntl_ManStoreSop( p, "1 1\n" );
Ntl_ObjSetFanin( pNode, pNet, 0 );
// update the CO driver net
pNetCo->pDriver = NULL;
if ( !Ntl_ModelSetNetDriver( pNode, pNetCo ) )
{
printf( "Ntl_ManInsert(): Internal error: PO net has more than one fanin.\n" );
return 0;
}
}
Vec_PtrFree( vCopies );
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -87,6 +87,7 @@ void Ntl_ManFree( Ntl_Man_t * p )
if ( p->pMemObjs ) Aig_MmFlexStop( p->pMemObjs, 0 );
if ( p->pMemSops ) Aig_MmFlexStop( p->pMemSops, 0 );
if ( p->pAig ) Aig_ManStop( p->pAig );
if ( p->pManTime ) Tim_ManStop( p->pManTime );
free( p );
}
......
......@@ -20,6 +20,7 @@
#include "ntl.h"
#include "kit.h"
#include "if.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
......@@ -105,247 +106,6 @@ Vec_Ptr_t * Ntl_MappingFromAig( Aig_Man_t * p )
}
#include "fpgaInt.h"
/**Function*************************************************************
Synopsis [Recursively derives the truth table for the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned * Ntl_FpgaComputeTruth_rec( Fpga_Cut_t * pCut, Vec_Ptr_t * vTruthElem, Vec_Ptr_t * vTruthStore, Vec_Ptr_t * vVisited, int nVars, int * pnCounter )
{
unsigned * pTruth, * pTruth0, * pTruth1;
assert( !Fpga_IsComplement(pCut) );
// if the cut is visited, return the result
if ( pCut->pRoot )
return (unsigned *)pCut->pRoot;
// compute the functions of the children
pTruth0 = Ntl_FpgaComputeTruth_rec( Fpga_CutRegular(pCut->pOne), vTruthElem, vTruthStore, vVisited, nVars, pnCounter );
if ( Fpga_CutIsComplement(pCut->pOne) )
Kit_TruthNot( pTruth0, pTruth0, nVars );
pTruth1 = Ntl_FpgaComputeTruth_rec( Fpga_CutRegular(pCut->pTwo), vTruthElem, vTruthStore, vVisited, nVars, pnCounter );
if ( Fpga_CutIsComplement(pCut->pTwo) )
Kit_TruthNot( pTruth1, pTruth1, nVars );
// get the function of the cut
pTruth = Vec_PtrEntry( vTruthStore, (*pnCounter)++ );
Kit_TruthAnd( pTruth, pTruth0, pTruth1, nVars );
if ( pCut->Phase )
Kit_TruthNot( pTruth, pTruth, nVars );
assert( pCut->pRoot == NULL );
pCut->pRoot = (Fpga_Node_t *)pTruth;
// add this cut to the visited list
Vec_PtrPush( vVisited, pCut );
return pTruth;
}
/**Function*************************************************************
Synopsis [Derives the truth table for one cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned * Ntl_FpgaComputeTruth( Fpga_Cut_t * pCut, Vec_Ptr_t * vTruthElem, Vec_Ptr_t * vTruthStore, Vec_Ptr_t * vVisited, int nVars )
{
unsigned * pTruth;
int i, nCounter = 0;
assert( pCut->nLeaves > 1 );
// set the leaf variables
for ( i = 0; i < pCut->nLeaves; i++ )
pCut->ppLeaves[i]->pCuts->pRoot = (Fpga_Node_t *)Vec_PtrEntry( vTruthElem, i );
// recursively compute the function
Vec_PtrClear( vVisited );
pTruth = Ntl_FpgaComputeTruth_rec( pCut, vTruthElem, vTruthStore, vVisited, nVars, &nCounter );
// clean the intermediate BDDs
for ( i = 0; i < pCut->nLeaves; i++ )
pCut->ppLeaves[i]->pCuts->pRoot = NULL;
Vec_PtrForEachEntry( vVisited, pCut, i )
pCut->pRoot = NULL;
return pTruth;
}
/**Function*************************************************************
Synopsis [Load the network into FPGA manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Fpga_Man_t * Ntl_ManToFpga( Aig_Man_t * p )
{
Fpga_Man_t * pMan;
Aig_Obj_t * pNode;//, * pFanin, * pPrev;
float * pfArrivals;
int i;
// start the mapping manager and set its parameters
pMan = Fpga_ManCreate( Aig_ManPiNum(p), Aig_ManPoNum(p), 0 );
if ( pMan == NULL )
return NULL;
// set the arrival times
pfArrivals = ALLOC( float, Aig_ManPiNum(p) );
memset( pfArrivals, 0, sizeof(float) * Aig_ManPiNum(p) );
Fpga_ManSetInputArrivals( pMan, pfArrivals );
// create PIs and remember them in the old nodes
Aig_ManConst1(p)->pData = Fpga_ManReadConst1(pMan);
Aig_ManForEachPi( p, pNode, i )
pNode->pData = Fpga_ManReadInputs(pMan)[i];
// load the AIG into the mapper
Aig_ManForEachNode( p, pNode, i )
{
pNode->pData = Fpga_NodeAnd( pMan,
Fpga_NotCond( Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ),
Fpga_NotCond( Aig_ObjFanin1(pNode)->pData, Aig_ObjFaninC1(pNode) ) );
// set up the choice node
// if ( Aig_AigNodeIsChoice( pNode ) )
// for ( pPrev = pNode, pFanin = pNode->pData; pFanin; pPrev = pFanin, pFanin = pFanin->pData )
// {
// Fpga_NodeSetNextE( (If_Obj_t *)pPrev->pData, (If_Obj_t *)pFanin->pData );
// Fpga_NodeSetRepr( (If_Obj_t *)pFanin->pData, (If_Obj_t *)pNode->pData );
// }
}
// set the primary outputs while copying the phase
Aig_ManForEachPo( p, pNode, i )
Fpga_ManReadOutputs(pMan)[i] = Fpga_NotCond( Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) );
assert( Fpga_NodeVecReadSize(pMan->vAnds) == Aig_ManNodeNum(p) );
return pMan;
}
/**Function*************************************************************
Synopsis [Creates the mapped network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Ntl_ManFromFpga( Aig_Man_t * p, Fpga_Man_t * pMan )
{
Fpga_NodeVec_t * vFpgaMap;
Fpga_Node_t ** ppLeaves, * pNode;
Fpga_Cut_t * pCutBest;
Vec_Ptr_t * vTruthElem, * vTruthStore, * vVisited, * vMapping;
Vec_Int_t * vFpgaToAig;
Aig_Obj_t * pObj;
Ntl_Lut_t * pLut;
unsigned * pTruth;
int i, k, nLuts, nLeaves, nWords, nVarsMax;
// create mapping of FPGA nodes into AIG nodes
vFpgaToAig = Vec_IntStart( Aig_ManObjNumMax(p) );
Vec_IntFill( vFpgaToAig, Aig_ManObjNumMax(p), -1 );
Aig_ManForEachObj( p, pObj, i )
{
if ( Aig_ObjIsPo(pObj) )
continue;
if ( Aig_ObjIsConst1(pObj) && pObj->pData == NULL )
continue;
pNode = pObj->pData;
assert( pNode != NULL );
Vec_IntWriteEntry( vFpgaToAig, Fpga_NodeReadNum(pNode), pObj->Id );
}
// create the mapping
// make sure nodes are in the top order!!!
nVarsMax = Fpga_ManReadVarMax( pMan );
nWords = Aig_TruthWordNum( nVarsMax );
vFpgaMap = Fpga_ManReadMapping( pMan );
vMapping = Ntl_MappingAlloc( vFpgaMap->nSize + (int)(Aig_ManConst1(p)->nRefs > 0), nVarsMax );
nLuts = 0;
if ( Aig_ManConst1(p)->nRefs > 0 )
{
pLut = Vec_PtrEntry( vMapping, nLuts++ );
pLut->Id = 0;
pLut->nFanins = 0;
memset( pLut->pTruth, 0xFF, 4 * nWords );
}
vVisited = Vec_PtrAlloc( 1000 );
vTruthElem = Vec_PtrAllocTruthTables( nVarsMax );
vTruthStore = Vec_PtrAllocSimInfo( 256, nWords );
for ( i = 0; i < vFpgaMap->nSize; i++ )
{
// get the best cut
pNode = vFpgaMap->pArray[i];
pCutBest = Fpga_NodeReadCutBest( pNode );
nLeaves = Fpga_CutReadLeavesNum( pCutBest );
ppLeaves = Fpga_CutReadLeaves( pCutBest );
// fill the LUT
pLut = Vec_PtrEntry( vMapping, nLuts++ );
pLut->Id = Vec_IntEntry( vFpgaToAig, Fpga_NodeReadNum(pNode) );
pLut->nFanins = nLeaves;
for ( k = 0; k < nLeaves; k++ )
pLut->pFanins[k] = Vec_IntEntry( vFpgaToAig, Fpga_NodeReadNum(ppLeaves[k]) );
// compute the truth table
pTruth = Ntl_FpgaComputeTruth( pCutBest, vTruthElem, vTruthStore, vVisited, nVarsMax );
memcpy( pLut->pTruth, pTruth, 4 * nWords );
}
assert( nLuts == Vec_PtrSize(vMapping) );
Vec_IntFree( vFpgaToAig );
Vec_PtrFree( vVisited );
Vec_PtrFree( vTruthElem );
Vec_PtrFree( vTruthStore );
return vMapping;
}
/**Function*************************************************************
Synopsis [Interface with the FPGA mapping package.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Ntl_MappingFpga( Aig_Man_t * p )
{
Vec_Ptr_t * vMapping;
Fpga_Man_t * pMan;
// print a warning about choice nodes
if ( p->pEquivs )
printf( "Ntl_MappingFpga(): Performing FPGA mapping with choices.\n" );
// perform FPGA mapping
pMan = Ntl_ManToFpga( p );
if ( pMan == NULL )
return NULL;
if ( !Fpga_Mapping( pMan ) )
{
Fpga_ManFree( pMan );
return NULL;
}
// transform the result of mapping into a BDD network
vMapping = Ntl_ManFromFpga( p, pMan );
Fpga_ManFree( pMan );
if ( vMapping == NULL )
return NULL;
return vMapping;
}
#include "if.h"
/**Function*************************************************************
Synopsis [Load the network into FPGA manager.]
......@@ -369,6 +129,7 @@ void Ntk_ManSetIfParsDefault( If_Par_t * pPars )
pPars->nFlowIters = 1;
pPars->nAreaIters = 2;
pPars->DelayTarget = -1;
pPars->Epsilon = (float)0.001;
pPars->fPreprocess = 1;
pPars->fArea = 0;
pPars->fFancy = 0;
......@@ -486,6 +247,8 @@ If_Man_t * Ntk_ManToIf( Aig_Man_t * p, If_Par_t * pPars )
{
pNode->pData = If_ManCreateCi( pIfMan );
((If_Obj_t *)pNode->pData)->Level = pNode->Level;
if ( pIfMan->nLevelMax < (int)pNode->Level )
pIfMan->nLevelMax = (int)pNode->Level;
}
else if ( Aig_ObjIsPo(pNode) )
If_ManCreateCo( pIfMan, If_NotCond( Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) );
......@@ -601,7 +364,7 @@ Vec_Ptr_t * Ntl_MappingIf( Ntl_Man_t * pMan, Aig_Man_t * p )
pIfMan = Ntk_ManToIf( p, pPars );
if ( pIfMan == NULL )
return NULL;
pIfMan->pManTim = Ntl_ManCreateTiming( pMan );
pIfMan->pManTim = Tim_ManDup( pMan->pManTime, 0 );
if ( !If_ManPerformMapping( pIfMan ) )
{
If_ManStop( pIfMan );
......
......@@ -148,6 +148,49 @@ Tim_Man_t * Tim_ManStart( int nPis, int nPos )
/**Function*************************************************************
Synopsis [Duplicates the timing manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Tim_Man_t * Tim_ManDup( Tim_Man_t * p, int fDiscrete )
{
Tim_Man_t * pNew;
Tim_Box_t * pBox;
float * pDelayTableNew;
int i, k;
pNew = Tim_ManStart( p->nPis, p->nPos );
memcpy( pNew->pPis, p->pPis, sizeof(Tim_Obj_t) * p->nPis );
memcpy( pNew->pPos, p->pPos, sizeof(Tim_Obj_t) * p->nPos );
for ( k = 0; k < p->nPis; k++ )
pNew->pPis[k].TravId = 0;
for ( k = 0; k < p->nPos; k++ )
pNew->pPos[k].TravId = 0;
if ( fDiscrete )
for ( k = 0; k < p->nPis; k++ )
pNew->pPis[k].timeArr = 0.0; // modify here
pNew->vDelayTables = Vec_PtrAlloc( 100 );
Tim_ManForEachBox( p, pBox, i )
{
pDelayTableNew = ALLOC( float, pBox->nInputs * pBox->nOutputs );
Vec_PtrPush( pNew->vDelayTables, pDelayTableNew );
if ( fDiscrete )
for ( k = 0; k < pBox->nInputs * pBox->nOutputs; k++ )
pDelayTableNew[k] = 1.0; // modify here
else
memcpy( pDelayTableNew, pBox->pDelayTable, sizeof(float) * pBox->nInputs * pBox->nOutputs );
Tim_ManCreateBoxFirst( pNew, pBox->Inouts[0], pBox->nInputs,
pBox->Inouts[pBox->nInputs], pBox->nOutputs, pDelayTableNew );
}
return pNew;
}
/**Function*************************************************************
Synopsis [Stops the timing manager.]
Description []
......
......@@ -58,6 +58,7 @@ typedef struct Tim_Man_t_ Tim_Man_t;
/*=== time.c ===========================================================*/
extern Tim_Man_t * Tim_ManStart( int nPis, int nPos );
extern Tim_Man_t * Tim_ManDup( Tim_Man_t * p, int fDiscrete );
extern void Tim_ManStop( Tim_Man_t * p );
extern void Tim_ManPrint( Tim_Man_t * p );
extern void Tim_ManSetDelayTables( Tim_Man_t * p, Vec_Ptr_t * vDelayTables );
......
......@@ -736,7 +736,7 @@ clk = clock();
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkDCompress2( Abc_Ntk_t * pNtk, int fBalance, int fUpdateLevel, int fVerbose )
Abc_Ntk_t * Abc_NtkDCompress2( Abc_Ntk_t * pNtk, int fBalance, int fUpdateLevel, int fFanout, int fVerbose )
{
Aig_Man_t * pMan, * pTemp;
Abc_Ntk_t * pNtkAig;
......@@ -748,7 +748,7 @@ Abc_Ntk_t * Abc_NtkDCompress2( Abc_Ntk_t * pNtk, int fBalance, int fUpdateLevel,
// Aig_ManPrintStats( pMan );
clk = clock();
pMan = Dar_ManCompress2( pTemp = pMan, fBalance, fUpdateLevel, fVerbose );
pMan = Dar_ManCompress2( pTemp = pMan, fBalance, fUpdateLevel, fFanout, fVerbose );
Aig_ManStop( pTemp );
//PRT( "time", clock() - clk );
......@@ -1744,6 +1744,7 @@ void Abc_NtkPrintSccs( Abc_Ntk_t * pNtk, int fVerbose )
***********************************************************************/
void Abc_NtkDarTestBlif( char * pFileName )
{
/*
char Buffer[1000];
Ntl_Man_t * p;
p = Ioa_ReadBlif( pFileName, 1 );
......@@ -1763,6 +1764,7 @@ void Abc_NtkDarTestBlif( char * pFileName )
sprintf( Buffer, "test_.blif", p->pName );
Ioa_WriteBlif( p, Buffer );
Ntl_ManFree( p );
*/
}
////////////////////////////////////////////////////////////////////////
......
......@@ -795,6 +795,7 @@ void Abc_NtkUpdateLevel( Abc_Obj_t * pObjNew, Vec_Vec_t * vLevels )
{
Abc_Obj_t * pFanout, * pTemp;
int LevelOld, Lev, k, m;
// int Counter = 0, CounterMax = 0;
// check if level has changed
LevelOld = Abc_ObjLevel(pObjNew);
if ( LevelOld == Abc_ObjLevelNew(pObjNew) )
......@@ -808,6 +809,7 @@ void Abc_NtkUpdateLevel( Abc_Obj_t * pObjNew, Vec_Vec_t * vLevels )
// recursively update level
Vec_VecForEachEntryStart( vLevels, pTemp, Lev, k, LevelOld )
{
// Counter--;
pTemp->fMarkA = 0;
assert( Abc_ObjLevel(pTemp) == Lev );
Abc_ObjSetLevel( pTemp, Abc_ObjLevelNew(pTemp) );
......@@ -821,10 +823,13 @@ void Abc_NtkUpdateLevel( Abc_Obj_t * pObjNew, Vec_Vec_t * vLevels )
{
assert( Abc_ObjLevel(pFanout) >= Lev );
Vec_VecPush( vLevels, Abc_ObjLevel(pFanout), pFanout );
// Counter++;
// CounterMax = ABC_MAX( CounterMax, Counter );
pFanout->fMarkA = 1;
}
}
}
// printf( "%d ", CounterMax );
}
/**Function*************************************************************
......
......@@ -73,6 +73,11 @@ struct Abc_Frame_t_
void * pLibGen; // the current genlib
void * pLibSuper; // the current supergate library
void * pLibVer; // the current Verilog library
// new code
void * pAbc8Ntl; // the current design
void * pAbc8Ntk; // the current mapped network
void * pAbc8Aig; // the current AIG
};
////////////////////////////////////////////////////////////////////////
......
......@@ -220,7 +220,7 @@ void Extra_StopManager( DdManager * dd )
int RetValue;
// check for remaining references in the package
RetValue = Cudd_CheckZeroRef( dd );
if ( RetValue > 0 )
if ( RetValue > 10 )
printf( "\nThe number of referenced nodes = %d\n\n", RetValue );
// Cudd_PrintInfo( dd, stdout );
Cudd_Quit( dd );
......
......@@ -246,8 +246,8 @@ int Abc_NtkMfs( Abc_Ntk_t * pNtk, Mfs_Par_t * pPars )
if ( !pPars->fResub )
{
extern void Abc_NtkBidecResyn( Abc_Ntk_t * pNtk, int fVerbose );
Abc_NtkSweep( pNtk, 0 );
Abc_NtkBidecResyn( pNtk, 0 );
// Abc_NtkSweep( pNtk, 0 );
// Abc_NtkBidecResyn( pNtk, 0 );
}
p->nTotalNodesEnd = Abc_NtkNodeNum(pNtk);
......
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