summaryrefslogtreecommitdiffstats
path: root/src/aig/ntl
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2008-04-06 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2008-04-06 08:01:00 -0700
commit661abab094143930f58633dfad415468a90cef6f (patch)
treefa142590b1b9730282e34901d07398be8b34de95 /src/aig/ntl
parent0c4d314ef0460b94c3ccc4f8ddeedc8e49e35e96 (diff)
downloadabc-661abab094143930f58633dfad415468a90cef6f.tar.gz
abc-661abab094143930f58633dfad415468a90cef6f.tar.bz2
abc-661abab094143930f58633dfad415468a90cef6f.zip
Version abc80406
Diffstat (limited to 'src/aig/ntl')
-rw-r--r--src/aig/ntl/module.make2
-rw-r--r--src/aig/ntl/ntl.h12
-rw-r--r--src/aig/ntl/ntlExtract.c209
-rw-r--r--src/aig/ntl/ntlFraig.c156
-rw-r--r--src/aig/ntl/ntlInsert.c118
-rw-r--r--src/aig/ntl/ntlMan.c3
-rw-r--r--src/aig/ntl/ntlReadBlif.c9
-rw-r--r--src/aig/ntl/ntlTable.c29
-rw-r--r--src/aig/ntl/ntlUtil.c165
-rw-r--r--src/aig/ntl/ntlWriteBlif.c46
10 files changed, 744 insertions, 5 deletions
diff --git a/src/aig/ntl/module.make b/src/aig/ntl/module.make
index aba4fbf2..d3f2cfdd 100644
--- a/src/aig/ntl/module.make
+++ b/src/aig/ntl/module.make
@@ -1,6 +1,7 @@
SRC += src/aig/ntl/ntlCheck.c \
src/aig/ntl/ntlCore.c \
src/aig/ntl/ntlExtract.c \
+ src/aig/ntl/ntlFraig.c \
src/aig/ntl/ntlInsert.c \
src/aig/ntl/ntlMan.c \
src/aig/ntl/ntlMap.c \
@@ -8,5 +9,6 @@ SRC += src/aig/ntl/ntlCheck.c \
src/aig/ntl/ntlReadBlif.c \
src/aig/ntl/ntlTable.c \
src/aig/ntl/ntlTime.c \
+ src/aig/ntl/ntlUtil.c \
src/aig/ntl/ntlWriteBlif.c
diff --git a/src/aig/ntl/ntl.h b/src/aig/ntl/ntl.h
index 6d4f5c29..2e109f05 100644
--- a/src/aig/ntl/ntl.h
+++ b/src/aig/ntl/ntl.h
@@ -103,9 +103,8 @@ struct Ntl_Obj_t_
Ntl_Mod_t * pModel; // the model
void * pCopy; // the copy of this object
unsigned Type : 3; // object type
- unsigned Id : 27; // object ID
- unsigned MarkA : 1; // temporary mark
- unsigned MarkB : 1; // temporary mark
+ unsigned fMark : 1; // temporary mark
+ unsigned Id : 28; // object ID
int nFanins; // the number of fanins
int nFanouts; // the number of fanouts
union { // functionality
@@ -123,6 +122,7 @@ struct Ntl_Net_t_
Ntl_Obj_t * pDriver; // driver of the net
char nVisits; // the number of times the net is visited
char fMark; // temporary mark
+ char fCompl; // complemented attribue
char pName[0]; // the name of this net
};
@@ -234,6 +234,7 @@ extern Aig_Man_t * Ntl_ManCollapse( 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 );
+extern int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig );
extern int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk );
/*=== ntlCheck.c ==========================================================*/
extern int Ntl_ManCheck( Ntl_Man_t * pMan );
@@ -270,12 +271,17 @@ 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 int Ntl_ModelFindPioNumber( Ntl_Mod_t * p, char * pName, int * pNumber );
extern int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet );
+extern void Ntl_ModelDeleteNet( Ntl_Mod_t * p, Ntl_Net_t * pNet );
/*=== ntlTime.c ==========================================================*/
extern Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p );
/*=== ntlReadBlif.c ==========================================================*/
extern Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck );
/*=== ntlWriteBlif.c ==========================================================*/
extern void Ioa_WriteBlif( Ntl_Man_t * p, char * pFileName );
+/*=== ntlUtil.c ==========================================================*/
+extern int Ntl_ManTransformCoDrivers( Ntl_Man_t * p );
+extern Vec_Ptr_t * Ntl_ManCollectCiNames( Ntl_Man_t * p );
+extern Vec_Ptr_t * Ntl_ManCollectCoNames( Ntl_Man_t * p );
#ifdef __cplusplus
}
diff --git a/src/aig/ntl/ntlExtract.c b/src/aig/ntl/ntlExtract.c
index cd21c95f..848f113a 100644
--- a/src/aig/ntl/ntlExtract.c
+++ b/src/aig/ntl/ntlExtract.c
@@ -213,6 +213,41 @@ char * Ntl_SopCreateFromIsop( Aig_MmFlex_t * pMan, int nVars, Vec_Int_t * vCover
/**Function*************************************************************
+ Synopsis [Creates the cover from the ISOP computed from TT.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ntl_SopToIsop( char * pSop, Vec_Int_t * vCover )
+{
+ char * pCube;
+ int k, nVars, Entry;
+ nVars = Ntl_SopGetVarNum( pSop );
+ assert( nVars > 0 );
+ // create cubes
+ Vec_IntClear( vCover );
+ for ( pCube = pSop; *pCube; pCube += nVars + 3 )
+ {
+ Entry = 0;
+ for ( k = nVars - 1; k >= 0; k-- )
+ if ( pCube[k] == '0' )
+ Entry = (Entry << 2) | 1;
+ else if ( pCube[k] == '1' )
+ Entry = (Entry << 2) | 2;
+ else if ( pCube[k] == '-' )
+ Entry = (Entry << 2);
+ else
+ assert( 0 );
+ Vec_IntPush( vCover, Entry );
+ }
+}
+
+/**Function*************************************************************
+
Synopsis [Transforms truth table into the SOP.]
Description []
@@ -404,10 +439,11 @@ int Ntl_ManExtract_rec( Ntl_Man_t * p, Ntl_Net_t * pNet )
}
//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->pCopy = Ntl_ManBuildNodeAig( pObj );
+ if ( pNet->fCompl )
+ pNet->pCopy = Aig_Not(pNet->pCopy);
pNet->nVisits = 2;
return 1;
}
@@ -602,9 +638,10 @@ int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet )
if ( !Ntl_ManBuildModelAig( p, pObj ) )
return 0;
}
- // store the node
if ( Ntl_ObjIsNode(pObj) )
pNet->pCopy = Ntl_ManBuildNodeAig( pObj );
+ if ( pNet->fCompl )
+ pNet->pCopy = Aig_Not(pNet->pCopy);
pNet->nVisits = 2;
return 1;
}
@@ -692,6 +729,174 @@ Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p )
return pAig;
}
+/**Function*************************************************************
+
+ Synopsis [Increments reference counter of the net.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Ntl_NetIncrementRefs( Ntl_Net_t * pNet )
+{
+ int nRefs = (int)pNet->pCopy;
+ pNet->pCopy = (void *)(nRefs + 1);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Extracts logic newtork out of the netlist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Nwk_Obj_t * Ntl_ManExtractNwk_rec( Ntl_Man_t * p, Ntl_Net_t * pNet, Nwk_Man_t * pNtk, Vec_Int_t * vCover, Vec_Int_t * vMemory )
+{
+ extern Hop_Obj_t * Kit_CoverToHop( Hop_Man_t * pMan, Vec_Int_t * vCover, int nVars, Vec_Int_t * vMemory );
+ Ntl_Net_t * pFaninNet;
+ Nwk_Obj_t * pNode;
+ int i;
+ if ( pNet->fMark )
+ return pNet->pCopy;
+ pNet->fMark = 1;
+ pNode = Nwk_ManCreateNode( pNtk, Ntl_ObjFaninNum(pNet->pDriver), (int)pNet->pCopy );
+ Ntl_ObjForEachFanin( pNet->pDriver, pFaninNet, i )
+ {
+ Ntl_ManExtractNwk_rec( p, pFaninNet, pNtk, vCover, vMemory );
+ Nwk_ObjAddFanin( pNode, pFaninNet->pCopy );
+ }
+ if ( Ntl_ObjFaninNum(pNet->pDriver) == 0 )
+ pNode->pFunc = Hop_NotCond( Hop_ManConst1(pNtk->pManHop), Ntl_SopIsConst0(pNet->pDriver->pSop) );
+ else
+ {
+ Ntl_SopToIsop( pNet->pDriver->pSop, vCover );
+ pNode->pFunc = Kit_CoverToHop( pNtk->pManHop, vCover, Ntl_ObjFaninNum(pNet->pDriver), vMemory );
+ }
+ return pNet->pCopy = pNode;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Extracts logic newtork out of the netlist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Nwk_Man_t * Ntl_ManExtractNwk( Ntl_Man_t * p, Aig_Man_t * pAig )
+{
+ Nwk_Man_t * pNtk;
+ Nwk_Obj_t * pNode;
+ Ntl_Mod_t * pRoot;
+ Ntl_Net_t * pNet;
+ Ntl_Obj_t * pObj;
+ Aig_Obj_t * pAnd;
+ Vec_Int_t * vCover, * vMemory;
+ int i, k;
+ pRoot = Ntl_ManRootModel( p );
+ assert( Ntl_ModelBoxNum(pRoot) == 0 );
+ assert( Ntl_ModelLatchNum(pRoot) == 0 );
+ assert( Ntl_ModelPiNum(pRoot) == Aig_ManPiNum(pAig) );
+ assert( Ntl_ModelPoNum(pRoot) == Aig_ManPoNum(pAig) );
+ vCover = Vec_IntAlloc( 100 );
+ vMemory = Vec_IntAlloc( 1 << 16 );
+ // count the number of fanouts of each net
+ Ntl_ModelForEachNet( pRoot, pNet, i )
+ {
+ pNet->pCopy = NULL;
+ pNet->fMark = 0;
+ }
+ Ntl_ModelForEachObj( pRoot, pObj, i )
+ Ntl_ObjForEachFanin( pObj, pNet, k )
+ Ntl_NetIncrementRefs( pNet );
+ // construct the network
+ pNtk = Nwk_ManAlloc();
+ pNtk->pName = Aig_UtilStrsav( pAig->pName );
+ pNtk->pSpec = Aig_UtilStrsav( pAig->pSpec );
+ Aig_ManSetPioNumbers( pAig );
+ Aig_ManForEachObj( pAig, pAnd, i )
+ {
+ if ( Aig_ObjIsPi(pAnd) )
+ {
+ pObj = Ntl_ModelPi( pRoot, Aig_ObjPioNum(pAnd) );
+ pNet = Ntl_ObjFanout0(pObj);
+ pNet->fMark = 1;
+ pNet->pCopy = Nwk_ManCreateCi( pNtk, (int)pNet->pCopy );
+ }
+ else if ( Aig_ObjIsPo(pAnd) )
+ {
+ pObj = Ntl_ModelPo( pRoot, Aig_ObjPioNum(pAnd) );
+ pNet = Ntl_ObjFanin0(pObj);
+ pNet->pCopy = Ntl_ManExtractNwk_rec( p, pNet, pNtk, vCover, vMemory );
+ pNode = Nwk_ManCreateCo( pNtk );
+ pNode->fCompl = pNet->fCompl;
+ Nwk_ObjAddFanin( pNode, pNet->pCopy );
+ }
+ }
+ Aig_ManCleanPioNumbers( pAig );
+ Ntl_ModelForEachNet( pRoot, pNet, i )
+ {
+ pNet->pCopy = NULL;
+ pNet->fMark = 0;
+ }
+ Vec_IntFree( vCover );
+ Vec_IntFree( vMemory );
+ // create timing manager from the current design
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Extracts logic newtork out of the netlist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Nwk_Man_t * Ntl_ManReadNwk( char * pFileName, Aig_Man_t * pAig, Tim_Man_t * pManTime )
+{
+ Nwk_Man_t * pNtk;
+ Ntl_Man_t * pNtl;
+ Ntl_Mod_t * pRoot;
+ pNtl = Ioa_ReadBlif( pFileName, 1 );
+ if ( pNtl == NULL )
+ {
+ printf( "Ntl_ManReadNwk(): Reading BLIF has failed.\n" );
+ return NULL;
+ }
+ pRoot = Ntl_ManRootModel( pNtl );
+ if ( Ntl_ModelPiNum(pRoot) != Aig_ManPiNum(pAig) )
+ {
+ printf( "Ntl_ManReadNwk(): The number of primary inputs does not match (%d and %d).\n",
+ Ntl_ModelPiNum(pRoot), Aig_ManPiNum(pAig) );
+ return NULL;
+ }
+ if ( Ntl_ModelPoNum(pRoot) != Aig_ManPoNum(pAig) )
+ {
+ printf( "Ntl_ManReadNwk(): The number of primary outputs does not match (%d and %d).\n",
+ Ntl_ModelPoNum(pRoot), Aig_ManPoNum(pAig) );
+ return NULL;
+ }
+ pNtk = Ntl_ManExtractNwk( pNtl, pAig );
+ Ntl_ManFree( pNtl );
+ if ( pManTime )
+ pNtk->pManTime = Tim_ManDup( pManTime, 0 );
+ return pNtk;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/aig/ntl/ntlFraig.c b/src/aig/ntl/ntlFraig.c
new file mode 100644
index 00000000..7153f081
--- /dev/null
+++ b/src/aig/ntl/ntlFraig.c
@@ -0,0 +1,156 @@
+/**CFile****************************************************************
+
+ FileName [ntlFraig.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Netlist representation.]
+
+ Synopsis [Performing fraiging with white-boxes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: ntlFraig.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ntl.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Returns AIG with WB after fraiging.]
+
+ Description [pAig points to the nodes of pNew derived using it.
+ pNew points to the nodes of pAigCol derived using it.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t ** Ntl_ManFraigDeriveClasses( Aig_Man_t * pAig, Ntl_Man_t * pNew, Aig_Man_t * pAigCol )
+{
+ Ntl_Net_t * pNet;
+ Aig_Obj_t ** pReprs = NULL, ** pMapBack = NULL;
+ Aig_Obj_t * pObj, * pObjCol, * pObjColRepr, * pCorresp;
+ int i;
+
+ // map the AIG managers
+ Aig_ManForEachObj( pAig, pObj, i )
+ if ( Aig_ObjIsConst1(pObj) )
+ pObj->pData = Aig_ManConst1(pAigCol);
+ else if ( !Aig_ObjIsPo(pObj) )
+ {
+ pNet = pObj->pData;
+ pObjCol = Aig_Regular(pNet->pCopy);
+ pObj->pData = pObjCol;
+ }
+
+ // create mapping from the collapsed manager into the original manager
+ pMapBack = ALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAigCol) );
+ memset( pMapBack, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(pAigCol) );
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ if ( Aig_ObjIsPo(pObj) )
+ continue;
+ pObjCol = pObj->pData;
+ if ( pMapBack[pObjCol->Id] == NULL )
+ pMapBack[pObjCol->Id] = pObj;
+ }
+
+ // create the equivalence classes for the original manager
+ pReprs = ALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) );
+ memset( pReprs, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(pAig) );
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ if ( Aig_ObjIsPo(pObj) )
+ continue;
+ // get the collapsed node
+ pObjCol = pObj->pData;
+ // get the representative of the collapsed node
+ pObjColRepr = pAigCol->pReprs[pObjCol->Id];
+ if ( pObjColRepr == NULL )
+ pObjColRepr = pObjCol;
+ // get the corresponding original node
+ pCorresp = pMapBack[pObjColRepr->Id];
+ if ( pCorresp == NULL || pCorresp == pObj )
+ continue;
+ // set the representative
+ if ( pCorresp->Id < pObj->Id )
+ pReprs[pObj->Id] = pCorresp;
+ else
+ pReprs[pCorresp->Id] = pObj;
+ }
+ free( pMapBack );
+ return pReprs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns AIG with WB after fraiging.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ntl_ManFraig( Ntl_Man_t * p, Aig_Man_t * pAig, int nPartSize, int nConfLimit, int nLevelMax, 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_ManDup( p );
+ if ( !Ntl_ManInsertAig( pNew, pAig ) )
+ {
+ Ntl_ManFree( pNew );
+ printf( "Ntk_ManFraig(): Inserting AIG has failed.\n" );
+ return NULL;
+ }
+
+ // collapse the AIG
+ pAigCol = Ntl_ManCollapse( pNew );
+ // perform fraiging for the given design
+ if ( nPartSize == 0 )
+ nPartSize = Aig_ManPoNum(pAigCol);
+ pTemp = Aig_ManFraigPartitioned( pAigCol, nPartSize, nConfLimit, nLevelMax, 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;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ntl/ntlInsert.c b/src/aig/ntl/ntlInsert.c
index f02b4716..10b83660 100644
--- a/src/aig/ntl/ntlInsert.c
+++ b/src/aig/ntl/ntlInsert.c
@@ -59,6 +59,7 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
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
vCopies = Vec_PtrStart( Aig_ManObjNumMax(pAig) );
Ntl_ManForEachCiNet( p, pNet, i )
@@ -134,6 +135,122 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
SeeAlso []
***********************************************************************/
+int Ntl_ManInsertAig( Ntl_Man_t * p, Aig_Man_t * pAig )
+{
+ char Buffer[100];
+ Ntl_Mod_t * pRoot;
+ Ntl_Obj_t * pNode;
+ Ntl_Net_t * pNet, * pNetCo;
+ Aig_Obj_t * pObj, * pFanin;
+ int i, nDigits, Counter;
+ assert( Vec_PtrSize(p->vCis) == Aig_ManPiNum(pAig) );
+ assert( Vec_PtrSize(p->vCos) == Aig_ManPoNum(pAig) );
+ // set the correspondence between the PI/PO nodes
+ Aig_ManCleanData( pAig );
+ Ntl_ManForEachCiNet( p, pNet, i )
+ 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
+ if ( Aig_ManConst1(pAig)->nRefs > 0 )
+ {
+ pNode = Ntl_ModelCreateNode( pRoot, 0 );
+ pNode->pSop = Ntl_ManStoreSop( p, " 1\n" );
+ if ( (pNet = Ntl_ModelFindNet( pRoot, "Const1" )) )
+ {
+ printf( "Ntl_ManInsertAig(): Internal error: Intermediate net name is not unique.\n" );
+ return 0;
+ }
+ pNet = Ntl_ModelFindOrCreateNet( pRoot, "Const1" );
+ if ( !Ntl_ModelSetNetDriver( pNode, pNet ) )
+ {
+ printf( "Ntl_ManInsertAig(): Internal error: Net has more than one fanin.\n" );
+ return 0;
+ }
+ Aig_ManConst1(pAig)->pData = pNet;
+ }
+ // create a new node for each LUT
+ Counter = 0;
+ nDigits = Aig_Base10Log( Aig_ManNodeNum(pAig) );
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ if ( !Aig_ObjIsNode(pObj) )
+ continue;
+ if ( Aig_ObjFanin0(pObj)->pData == NULL || Aig_ObjFanin1(pObj)->pData == NULL )
+ {
+ printf( "Ntl_ManInsertAig(): Internal error: Net not found.\n" );
+ return 0;
+ }
+ pNode = Ntl_ModelCreateNode( pRoot, 2 );
+ Ntl_ObjSetFanin( pNode, Aig_ObjFanin0(pObj)->pData, 0 );
+ Ntl_ObjSetFanin( pNode, Aig_ObjFanin1(pObj)->pData, 1 );
+ if ( Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) )
+ pNode->pSop = Ntl_ManStoreSop( p, "00 1\n" );
+ else if ( Aig_ObjFaninC0(pObj) && !Aig_ObjFaninC1(pObj) )
+ pNode->pSop = Ntl_ManStoreSop( p, "01 1\n" );
+ else if ( !Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) )
+ pNode->pSop = Ntl_ManStoreSop( p, "10 1\n" );
+ else // if ( Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj) )
+ pNode->pSop = Ntl_ManStoreSop( p, "11 1\n" );
+ sprintf( Buffer, "and%0*d", nDigits, Counter++ );
+ if ( (pNet = Ntl_ModelFindNet( pRoot, Buffer )) )
+ {
+ printf( "Ntl_ManInsertAig(): Internal error: Intermediate net name is not unique.\n" );
+ return 0;
+ }
+ pNet = Ntl_ModelFindOrCreateNet( pRoot, Buffer );
+ if ( !Ntl_ModelSetNetDriver( pNode, pNet ) )
+ {
+ printf( "Ntl_ManInsertAig(): Internal error: Net has more than one fanin.\n" );
+ return 0;
+ }
+ pObj->pData = pNet;
+ }
+ // 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;
+ // get the corresponding PO and its driver
+ pObj = Aig_ManPo( pAig, i );
+ pFanin = Aig_ObjFanin0( pObj );
+ // get the net driving the driver
+ pNet = pFanin->pData;
+ pNode = Ntl_ModelCreateNode( pRoot, 1 );
+ pNode->pSop = Aig_ObjFaninC0(pObj)? 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;
+ }
+ }
+ return 1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Inserts the given mapping into the netlist.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
{
char Buffer[100];
@@ -157,6 +274,7 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
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
vTruth = Vec_IntAlloc( 1 << 16 );
vCover = Vec_IntAlloc( 1 << 16 );
diff --git a/src/aig/ntl/ntlMan.c b/src/aig/ntl/ntlMan.c
index 82660263..83219df7 100644
--- a/src/aig/ntl/ntlMan.c
+++ b/src/aig/ntl/ntlMan.c
@@ -267,6 +267,9 @@ Ntl_Mod_t * Ntl_ModelDup( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld )
if ( Ntl_ObjIsNode(pObj) )
((Ntl_Obj_t *)pObj->pCopy)->pSop = Ntl_ManStoreSop( pManNew, pObj->pSop );
}
+ 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;
}
diff --git a/src/aig/ntl/ntlReadBlif.c b/src/aig/ntl/ntlReadBlif.c
index 2cf3caaa..ce3a2051 100644
--- a/src/aig/ntl/ntlReadBlif.c
+++ b/src/aig/ntl/ntlReadBlif.c
@@ -109,6 +109,7 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck )
FILE * pFile;
Ioa_ReadMan_t * p;
Ntl_Man_t * pDesign;
+ int nNodes;
// check that the file is available
pFile = fopen( pFileName, "rb" );
@@ -164,6 +165,9 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck )
}
}
+ // transform the design by removing the CO drivers
+ if ( (nNodes = Ntl_ManTransformCoDrivers(pDesign)) )
+ printf( "The design was transformed by removing %d buf/inv CO drivers.\n", nNodes );
//Ioa_WriteBlif( pDesign, "_temp_.blif" );
return pDesign;
}
@@ -614,6 +618,11 @@ static Ntl_Man_t * Ioa_ReadParse( Ioa_ReadMan_t * p )
// finalize the network
Ntl_ModelFixNonDrivenNets( pMod->pNtk );
}
+ if ( i == 0 )
+ return NULL;
+ // update the design name
+ pMod = Vec_PtrEntry( p->vModels, 0 );
+ p->pDesign->pName = Ntl_ManStoreName( p->pDesign, pMod->pNtk->pName );
// return the network
pDesign = p->pDesign;
p->pDesign = NULL;
diff --git a/src/aig/ntl/ntlTable.c b/src/aig/ntl/ntlTable.c
index 909a64fd..df982481 100644
--- a/src/aig/ntl/ntlTable.c
+++ b/src/aig/ntl/ntlTable.c
@@ -134,6 +134,35 @@ Ntl_Net_t * Ntl_ModelFindNet( Ntl_Mod_t * p, char * pName )
SeeAlso []
***********************************************************************/
+void Ntl_ModelDeleteNet( Ntl_Mod_t * p, Ntl_Net_t * pNet )
+{
+ Ntl_Net_t * pEnt, * pPrev;
+ unsigned Key = Ntl_HashString( pNet->pName, p->nTableSize );
+ for ( pPrev = NULL, pEnt = p->pTable[Key]; pEnt; pPrev = pEnt, pEnt = pEnt->pNext )
+ if ( pEnt == pNet )
+ break;
+ if ( pEnt == NULL )
+ {
+ printf( "Ntl_ModelDeleteNet(): Net to be deleted is not found in the hash table.\n" );
+ return;
+ }
+ if ( pPrev == NULL )
+ p->pTable[Key] = pEnt->pNext;
+ else
+ pPrev->pNext = pEnt->pNext;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds or creates the net.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
Ntl_Net_t * Ntl_ModelFindOrCreateNet( Ntl_Mod_t * p, char * pName )
{
Ntl_Net_t * pEnt;
diff --git a/src/aig/ntl/ntlUtil.c b/src/aig/ntl/ntlUtil.c
new file mode 100644
index 00000000..b13dd3a7
--- /dev/null
+++ b/src/aig/ntl/ntlUtil.c
@@ -0,0 +1,165 @@
+/**CFile****************************************************************
+
+ FileName [ntlUtil.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: ntlUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "ntl.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if netlist was written by ABC with added bufs/invs.]
+
+ Description [Should be called immediately after reading from file.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntl_ManTransformCoDrivers( Ntl_Man_t * p )
+{
+ Vec_Ptr_t * vCoNets;
+ Ntl_Net_t * pNetCo, * pNetFanin;
+ Ntl_Obj_t * pObj;
+ Ntl_Mod_t * pRoot;
+ int i, k, Counter;
+ pRoot = Ntl_ManRootModel( p );
+ // collect the nets of the root model
+ vCoNets = Vec_PtrAlloc( 1000 );
+ Ntl_ModelForEachPo( pRoot, pObj, i )
+ if ( !Ntl_ObjFanin0(pObj)->fMark )
+ {
+ Ntl_ObjFanin0(pObj)->fMark = 1;
+ Vec_PtrPush( vCoNets, Ntl_ObjFanin0(pObj) );
+ }
+ Ntl_ModelForEachLatch( pRoot, pObj, i )
+ if ( !Ntl_ObjFanin0(pObj)->fMark )
+ {
+ Ntl_ObjFanin0(pObj)->fMark = 1;
+ Vec_PtrPush( vCoNets, Ntl_ObjFanin0(pObj) );
+ }
+ Ntl_ModelForEachBox( pRoot, pObj, k )
+ Ntl_ObjForEachFanin( pObj, pNetCo, i )
+ if ( !pNetCo->fMark )
+ {
+ pNetCo->fMark = 1;
+ Vec_PtrPush( vCoNets, pNetCo );
+ }
+ // check the nets
+ Vec_PtrForEachEntry( vCoNets, pNetCo, i )
+ {
+ if ( !Ntl_ObjIsNode(pNetCo->pDriver) )
+ continue;
+ if ( Ntl_ObjFaninNum(pNetCo->pDriver) != 1 )
+ break;
+ pNetFanin = Ntl_ObjFanin0(pNetCo->pDriver);
+ if ( !Ntl_ObjIsNode(pNetFanin->pDriver) )
+ break;
+ }
+ if ( i < Vec_PtrSize(vCoNets) )
+ {
+ Vec_PtrFree( vCoNets );
+ return 0;
+ }
+
+
+ // remove the buffers/inverters
+ Counter = 0;
+ Vec_PtrForEachEntry( vCoNets, pNetCo, i )
+ {
+ pNetCo->fMark = 0;
+ if ( !Ntl_ObjIsNode(pNetCo->pDriver) )
+ continue;
+ // if this net is driven by an interver
+ // set the complemented attribute of the CO
+ assert( Ntl_ObjFaninNum(pNetCo->pDriver) == 1 );
+ pNetCo->fCompl = (int)(pNetCo->pDriver->pSop[0] == '0');
+ // remove the driver
+ Vec_PtrWriteEntry( pRoot->vObjs, pNetCo->pDriver->Id, NULL );
+ // remove the net
+ pNetFanin = Ntl_ObjFanin0(pNetCo->pDriver);
+ Ntl_ModelDeleteNet( pRoot, pNetFanin );
+ // make the CO net point to the new driver
+ assert( Ntl_ObjIsNode(pNetFanin->pDriver) );
+ pNetCo->pDriver = NULL;
+ pNetFanin->pDriver->pFanio[pNetFanin->pDriver->nFanins] = NULL;
+ Ntl_ModelSetNetDriver( pNetFanin->pDriver, pNetCo );
+ Counter++;
+ }
+ Vec_PtrFree( vCoNets );
+ pRoot->nObjs[NTL_OBJ_NODE] -= Counter;
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the array of CI names.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Ntl_ManCollectCiNames( Ntl_Man_t * p )
+{
+ Vec_Ptr_t * vNames;
+ Ntl_Net_t * pNet;
+ int i;
+ vNames = Vec_PtrAlloc( 1000 );
+ Ntl_ManForEachCiNet( p, pNet, i )
+ Vec_PtrPush( vNames, pNet->pName );
+ return vNames;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives the array of CI names.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Ntl_ManCollectCoNames( Ntl_Man_t * p )
+{
+ Vec_Ptr_t * vNames;
+ Ntl_Net_t * pNet;
+ int i;
+ vNames = Vec_PtrAlloc( 1000 );
+ Ntl_ManForEachCoNet( p, pNet, i )
+ Vec_PtrPush( vNames, pNet->pName );
+ return vNames;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ntl/ntlWriteBlif.c b/src/aig/ntl/ntlWriteBlif.c
index 8bcd2044..fddd4167 100644
--- a/src/aig/ntl/ntlWriteBlif.c
+++ b/src/aig/ntl/ntlWriteBlif.c
@@ -44,6 +44,7 @@ void Ioa_WriteBlifModel( FILE * pFile, Ntl_Mod_t * pModel )
{
Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
+ float Delay;
int i, k;
fprintf( pFile, ".model %s\n", pModel->pName );
fprintf( pFile, ".inputs" );
@@ -54,6 +55,51 @@ void Ioa_WriteBlifModel( FILE * pFile, Ntl_Mod_t * pModel )
Ntl_ModelForEachPo( pModel, pObj, i )
fprintf( pFile, " %s", Ntl_ObjFanin0(pObj)->pName );
fprintf( pFile, "\n" );
+ // write delays
+ if ( pModel->vDelays )
+ {
+ for ( i = 0; i < Vec_IntSize(pModel->vDelays); i += 3 )
+ {
+ fprintf( pFile, ".delay" );
+ fprintf( pFile, " %s", Ntl_ObjFanout0(Ntl_ModelPi(pModel, Vec_IntEntry(pModel->vDelays,i)))->pName );
+ fprintf( pFile, " %s", Ntl_ObjFanin0(Ntl_ModelPo(pModel, Vec_IntEntry(pModel->vDelays,i+1)))->pName );
+ fprintf( pFile, " %.3f", Aig_Int2Float(Vec_IntEntry(pModel->vDelays,i+2)) );
+ fprintf( pFile, "\n" );
+ }
+ }
+ if ( pModel->vArrivals )
+ {
+ for ( i = 0; i < Vec_IntSize(pModel->vArrivals); i += 2 )
+ {
+ fprintf( pFile, ".input_arrival" );
+ fprintf( pFile, " %s", Ntl_ObjFanout0(Ntl_ModelPi(pModel, Vec_IntEntry(pModel->vArrivals,i)))->pName );
+ Delay = Aig_Int2Float(Vec_IntEntry(pModel->vArrivals,i+1));
+ if ( Delay == -TIM_ETERNITY )
+ fprintf( pFile, " -inf" );
+ else if ( Delay == TIM_ETERNITY )
+ fprintf( pFile, " inf" );
+ else
+ fprintf( pFile, " %.3f", Delay );
+ fprintf( pFile, "\n" );
+ }
+ }
+ if ( pModel->vRequireds )
+ {
+ for ( i = 0; i < Vec_IntSize(pModel->vRequireds); i += 2 )
+ {
+ fprintf( pFile, ".output_required" );
+ fprintf( pFile, " %s", Ntl_ObjFanin0(Ntl_ModelPo(pModel, Vec_IntEntry(pModel->vRequireds,i)))->pName );
+ Delay = Aig_Int2Float(Vec_IntEntry(pModel->vRequireds,i+1));
+ if ( Delay == -TIM_ETERNITY )
+ fprintf( pFile, " -inf" );
+ else if ( Delay == TIM_ETERNITY )
+ fprintf( pFile, " inf" );
+ else
+ fprintf( pFile, " %.3f", Delay );
+ fprintf( pFile, "\n" );
+ }
+ }
+ // write objects
Ntl_ModelForEachObj( pModel, pObj, i )
{
if ( Ntl_ObjIsNode(pObj) )