summaryrefslogtreecommitdiffstats
path: root/src/aig/ntl
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig/ntl')
-rw-r--r--src/aig/ntl/ntl.h32
-rw-r--r--src/aig/ntl/ntlCheck.c77
-rw-r--r--src/aig/ntl/ntlExtract.c198
-rw-r--r--src/aig/ntl/ntlInsert.c52
-rw-r--r--src/aig/ntl/ntlMan.c101
-rw-r--r--src/aig/ntl/ntlMap.c2
-rw-r--r--src/aig/ntl/ntlObj.c27
-rw-r--r--src/aig/ntl/ntlReadBlif.c15
-rw-r--r--src/aig/ntl/ntlTable.c44
-rw-r--r--src/aig/ntl/ntlTime.c2
10 files changed, 431 insertions, 119 deletions
diff --git a/src/aig/ntl/ntl.h b/src/aig/ntl/ntl.h
index 72a5674b..6d4f5c29 100644
--- a/src/aig/ntl/ntl.h
+++ b/src/aig/ntl/ntl.h
@@ -31,7 +31,7 @@ extern "C" {
#include "aig.h"
#include "tim.h"
-#include "ntk.h"
+#include "nwk.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
@@ -94,11 +94,14 @@ struct Ntl_Mod_t_
Vec_Int_t * vArrivals;
Vec_Int_t * vRequireds;
float * pDelayTable;
+ // other data members
+ void * pCopy;
};
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
@@ -115,9 +118,9 @@ struct Ntl_Obj_t_
struct Ntl_Net_t_
{
- Ntl_Obj_t * pDriver; // driver of the net
Ntl_Net_t * pNext; // next net in the hash table
- Aig_Obj_t * pFunc; // the AIG representation
+ void * pCopy; // the copy of this object
+ Ntl_Obj_t * pDriver; // driver of the net
char nVisits; // the number of times the net is visited
char fMark; // temporary mark
char pName[0]; // the name of this net
@@ -140,6 +143,8 @@ struct Ntl_Lut_t_
/// INLINED FUNCTIONS ///
////////////////////////////////////////////////////////////////////////
+static inline Ntl_Mod_t * Ntl_ManRootModel( Ntl_Man_t * p ) { return Vec_PtrEntry( p->vModels, 0 ); }
+
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_ModelNodeNum( Ntl_Mod_t * p ) { return p->nObjs[NTL_OBJ_NODE]; }
@@ -169,7 +174,7 @@ static inline Ntl_Net_t * Ntl_ObjFanin0( Ntl_Obj_t * p ) { return p->pF
static inline Ntl_Net_t * Ntl_ObjFanout0( Ntl_Obj_t * p ) { return p->pFanio[p->nFanins]; }
static inline Ntl_Net_t * Ntl_ObjFanin( Ntl_Obj_t * p, int i ) { return p->pFanio[i]; }
-static inline Ntl_Net_t * Ntl_ObjFanout( Ntl_Obj_t * p, int i ) { return p->pFanio[p->nFanins+1]; }
+static inline Ntl_Net_t * Ntl_ObjFanout( Ntl_Obj_t * p, int i ) { return p->pFanio[p->nFanins+i]; }
static inline void Ntl_ObjSetFanin( Ntl_Obj_t * p, Ntl_Net_t * pNet, int i ) { p->pFanio[i] = pNet; }
static inline void Ntl_ObjSetFanout( Ntl_Obj_t * p, Ntl_Net_t * pNet, int i ) { p->pFanio[p->nFanins+i] = pNet; pNet->pDriver = p; }
@@ -186,10 +191,10 @@ static inline void Ntl_ObjSetFanout( Ntl_Obj_t * p, Ntl_Net_t * pNet, int
Vec_PtrForEachEntry( p->vCos, pNtl, i )
#define Ntl_ManForEachNode( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vNodes)) && (((pObj) = Vec_PtrEntry(p->vNodes, i)), 1); i++ ) \
- if ( !Ntl_ObjIsNode(pObj) ) {} else
+ if ( (pObj) == NULL || !Ntl_ObjIsNode(pObj) ) {} else
#define Ntl_ManForEachBox( p, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(p->vNodes)) && (((pObj) = Vec_PtrEntry(p->vNodes, i)), 1); i++ ) \
- if ( !Ntl_ObjIsBox(pObj) ) {} else
+ if ( (pObj) == NULL || !Ntl_ObjIsBox(pObj) ) {} else
#define Ntl_ModelForEachPi( pNtl, pObj, i ) \
Vec_PtrForEachEntry( pNtl->vPis, pObj, i )
@@ -200,13 +205,13 @@ static inline void Ntl_ObjSetFanout( Ntl_Obj_t * p, Ntl_Net_t * pNet, int
if ( pObj == NULL ) {} else
#define Ntl_ModelForEachLatch( pNtl, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(pNtl->vObjs)) && (((pObj) = Vec_PtrEntry(pNtl->vObjs, i)), 1); i++ ) \
- if ( !Ntl_ObjIsLatch(pObj) ) {} else
+ if ( (pObj) == NULL || !Ntl_ObjIsLatch(pObj) ) {} else
#define Ntl_ModelForEachNode( pNtl, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(pNtl->vObjs)) && (((pObj) = Vec_PtrEntry(pNtl->vObjs, i)), 1); i++ ) \
- if ( !Ntl_ObjIsNode(pObj) ) {} else
+ if ( (pObj) == NULL || !Ntl_ObjIsNode(pObj) ) {} else
#define Ntl_ModelForEachBox( pNtl, pObj, i ) \
for ( i = 0; (i < Vec_PtrSize(pNtl->vObjs)) && (((pObj) = Vec_PtrEntry(pNtl->vObjs, i)), 1); i++ ) \
- if ( !Ntl_ObjIsBox(pObj) ) {} else
+ if ( (pObj) == NULL || !Ntl_ObjIsBox(pObj) ) {} else
#define Ntl_ModelForEachNet( pNtl, pNet, i ) \
for ( i = 0; i < pNtl->nTableSize; i++ ) \
for ( pNet = pNtl->pTable[i]; pNet; pNet = pNet->pNext )
@@ -225,21 +230,25 @@ 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 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_ManInsertNtk( Ntl_Man_t * p, Ntk_Man_t * pNtk );
+extern int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk );
/*=== 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 );
/*=== ntlMan.c ============================================================*/
extern Ntl_Man_t * Ntl_ManAlloc( char * pFileName );
+extern Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * p );
+extern Ntl_Man_t * Ntl_ManDup( Ntl_Man_t * p );
extern void Ntl_ManFree( Ntl_Man_t * p );
extern Ntl_Mod_t * Ntl_ManFindModel( Ntl_Man_t * p, char * pName );
extern void Ntl_ManPrintStats( 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_ModelDup( Ntl_Man_t * pManNew, Ntl_Mod_t * pModelOld );
extern void Ntl_ModelFree( Ntl_Mod_t * p );
/*=== ntlMap.c ============================================================*/
extern Vec_Ptr_t * Ntl_MappingAlloc( int nLuts, int nVars );
@@ -252,14 +261,15 @@ extern Ntl_Obj_t * Ntl_ModelCreatePo( Ntl_Mod_t * pModel, Ntl_Net_t * pNet )
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_ModelCreateBox( Ntl_Mod_t * pModel, int nFanins, int nFanouts );
+extern Ntl_Obj_t * Ntl_ModelDupObj( Ntl_Mod_t * pModel, Ntl_Obj_t * pOld );
extern char * Ntl_ManStoreName( Ntl_Man_t * p, char * pName );
extern char * Ntl_ManStoreSop( Ntl_Man_t * p, char * pSop );
extern char * Ntl_ManStoreFileName( Ntl_Man_t * p, char * pFileName );
/*=== ntlTable.c ==========================================================*/
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_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet );
extern int Ntl_ModelFindPioNumber( Ntl_Mod_t * p, char * pName, int * pNumber );
+extern int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet );
/*=== ntlTime.c ==========================================================*/
extern Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p );
/*=== ntlReadBlif.c ==========================================================*/
diff --git a/src/aig/ntl/ntlCheck.c b/src/aig/ntl/ntlCheck.c
index d01c7d5e..5973e967 100644
--- a/src/aig/ntl/ntlCheck.c
+++ b/src/aig/ntl/ntlCheck.c
@@ -40,11 +40,40 @@
SeeAlso []
***********************************************************************/
-int Ntl_ManCheck( Ntl_Man_t * pMan )
+int Ntl_ModelCheck( Ntl_Mod_t * pModel )
{
- // check that the models have unique names
- // check that the models (except the first one) do not have boxes
- return 1;
+ Ntl_Obj_t * pObj;
+ Ntl_Net_t * pNet;
+ int i, k, fStatus = 1;
+ Ntl_ModelForEachNet( pModel, pNet, i )
+ {
+ if ( pNet->pName == NULL )
+ {
+ printf( "Net %d does not have a name\n", i );
+ fStatus = 0;
+ }
+ if ( pNet->pDriver == NULL )
+ {
+ printf( "Net %d (%s) does not have a driver\n", i, pNet->pName );
+ fStatus = 0;
+ }
+ }
+ Ntl_ModelForEachObj( pModel, pObj, i )
+ {
+ Ntl_ObjForEachFanin( pObj, pNet, k )
+ if ( pNet == NULL )
+ {
+ printf( "Object %d does not have fanin net %d\n", i, k );
+ fStatus = 0;
+ }
+ Ntl_ObjForEachFanout( pObj, pNet, k )
+ if ( pNet == NULL )
+ {
+ printf( "Object %d does not have fanout net %d\n", i, k );
+ fStatus = 0;
+ }
+ }
+ return fStatus;
}
/**Function*************************************************************
@@ -58,9 +87,45 @@ int Ntl_ManCheck( Ntl_Man_t * pMan )
SeeAlso []
***********************************************************************/
-int Ntl_ModelCheck( Ntl_Mod_t * pModel )
+int Ntl_ManCheck( Ntl_Man_t * pMan )
{
- return 1;
+ Ntl_Mod_t * pMod1, * pMod2;
+ int i, k, fStatus = 1;
+ // check that the models have unique names
+ Ntl_ManForEachModel( pMan, pMod1, i )
+ {
+ if ( pMod1->pName == NULL )
+ {
+ printf( "Model %d does not have a name\n", i );
+ fStatus = 0;
+ }
+ Ntl_ManForEachModel( pMan, pMod2, k )
+ {
+ if ( i >= k )
+ continue;
+ if ( strcmp(pMod1->pName, pMod2->pName) == 0 )
+ {
+ printf( "Models %d and %d have the same name (%s).\n", i, k, pMod1->pName );
+ fStatus = 0;
+ }
+ }
+ }
+ // check that the models (except the first one) do not have boxes
+ Ntl_ManForEachModel( pMan, pMod1, i )
+ {
+ if ( i == 0 )
+ continue;
+ if ( Ntl_ModelBoxNum(pMod1) > 0 )
+ {
+ printf( "Non-root model %d (%s) has %d boxes.\n", i, pMod1->pName, Ntl_ModelBoxNum(pMod1) );
+ fStatus = 0;
+ }
+ }
+ // check models
+ Ntl_ManForEachModel( pMan, pMod1, i )
+ if ( !Ntl_ModelCheck( pMod1 ) )
+ fStatus = 0;
+ return fStatus;
}
diff --git a/src/aig/ntl/ntlExtract.c b/src/aig/ntl/ntlExtract.c
index a54618e5..0654bb27 100644
--- a/src/aig/ntl/ntlExtract.c
+++ b/src/aig/ntl/ntlExtract.c
@@ -269,9 +269,9 @@ Aig_Obj_t * Ntl_ConvertSopToAigInternal( Aig_Man_t * pMan, Ntl_Obj_t * pNode, ch
{
pNet = Ntl_ObjFanin( pNode, i );
if ( Value == '1' )
- pAnd = Aig_And( pMan, pAnd, pNet->pFunc );
+ pAnd = Aig_And( pMan, pAnd, pNet->pCopy );
else if ( Value == '0' )
- pAnd = Aig_And( pMan, pAnd, Aig_Not(pNet->pFunc) );
+ pAnd = Aig_And( pMan, pAnd, Aig_Not(pNet->pCopy) );
}
// add to the sum of cubes
pSum = Aig_Or( pMan, pSum, pAnd );
@@ -326,7 +326,7 @@ Aig_Obj_t * Ntl_GraphToNetworkAig( Aig_Man_t * pMan, Dec_Graph_t * pGraph )
SeeAlso []
***********************************************************************/
-Aig_Obj_t * Ntl_ManExtractAigNode( Ntl_Obj_t * pNode )
+Aig_Obj_t * Ntl_ManBuildNodeAig( Ntl_Obj_t * pNode )
{
Aig_Man_t * pMan = pNode->pModel->pMan->pAig;
int fUseFactor = 0;
@@ -344,7 +344,7 @@ Aig_Obj_t * Ntl_ManExtractAigNode( Ntl_Obj_t * pNode )
pFForm = Dec_Factor( pNode->pSop );
// collect the fanins
Dec_GraphForEachLeaf( pFForm, pFFNode, i )
- pFFNode->pFunc = Ntl_ObjFanin(pNode, i)->pFunc;
+ pFFNode->pFunc = Ntl_ObjFanin(pNode, i)->pCopy;
// perform strashing
pFunc = Ntl_GraphToNetworkAig( pMan, pFForm );
Dec_GraphFree( pFForm );
@@ -391,23 +391,23 @@ int Ntl_ManExtract_rec( Ntl_Man_t * p, Ntl_Net_t * pNet )
Vec_IntPush( p->vBox1Cos, Aig_ManPoNum(p->pAig) );
Ntl_ObjForEachFanin( pObj, pNetFanin, i )
{
- LevelCur = Aig_ObjLevel( Aig_Regular(pNetFanin->pFunc) );
+ LevelCur = Aig_ObjLevel( Aig_Regular(pNetFanin->pCopy) );
LevelMax = AIG_MAX( LevelMax, LevelCur );
Vec_PtrPush( p->vCos, pNetFanin );
- Aig_ObjCreatePo( p->pAig, pNetFanin->pFunc );
+ Aig_ObjCreatePo( p->pAig, pNetFanin->pCopy );
}
Ntl_ObjForEachFanout( pObj, pNetFanin, i )
{
Vec_PtrPush( p->vCis, pNetFanin );
- pNetFanin->pFunc = Aig_ObjCreatePi( p->pAig );
- Aig_ObjSetLevel( pNetFanin->pFunc, LevelMax + 1 );
+ pNetFanin->pCopy = Aig_ObjCreatePi( p->pAig );
+ Aig_ObjSetLevel( pNetFanin->pCopy, 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->pCopy = Ntl_ManBuildNodeAig( pObj );
pNet->nVisits = 2;
return 1;
}
@@ -441,14 +441,17 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
p->pAig->pName = Aig_UtilStrsav( p->pName );
p->pAig->pSpec = Aig_UtilStrsav( p->pSpec );
// get the root model
- pRoot = Vec_PtrEntry( p->vModels, 0 );
+ pRoot = Ntl_ManRootModel( p );
+ // clear net visited flags
+ Ntl_ModelForEachNet( pRoot, pNet, i )
+ pNet->nVisits = 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 );
+ pNet->pCopy = Aig_ObjCreatePi( p->pAig );
if ( pNet->nVisits )
{
printf( "Ntl_ManExtract(): Primary input appears twice in the list.\n" );
@@ -462,7 +465,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
assert( Ntl_ObjFanoutNum(pObj) == 1 );
pNet = Ntl_ObjFanout0(pObj);
Vec_PtrPush( p->vCis, pNet );
- pNet->pFunc = Aig_ObjCreatePi( p->pAig );
+ pNet->pCopy = Aig_ObjCreatePi( p->pAig );
if ( pNet->nVisits )
{
printf( "Ntl_ManExtract(): Latch output is duplicated or defined as a primary input.\n" );
@@ -483,7 +486,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
return 0;
}
Vec_PtrPush( p->vCos, pNet );
- Aig_ObjCreatePo( p->pAig, pNet->pFunc );
+ Aig_ObjCreatePo( p->pAig, pNet->pCopy );
}
// visit the nodes starting from latch inputs outputs
Ntl_ModelForEachLatch( pRoot, pObj, i )
@@ -498,7 +501,7 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
return 0;
}
Vec_PtrPush( p->vCos, pNet );
- Aig_ObjCreatePo( p->pAig, pNet->pFunc );
+ Aig_ObjCreatePo( p->pAig, pNet->pCopy );
}
// report the number of dangling objects
nUselessObjects = Ntl_ModelNodeNum(pRoot) + Ntl_ModelBoxNum(pRoot) - Vec_PtrSize(p->vNodes);
@@ -517,12 +520,54 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
+/**Function*************************************************************
+
+ Synopsis [Collects the nodes in a topological order.]
+
+ Description []
+
+ SideEffects []
+ SeeAlso []
+***********************************************************************/
+int Ntl_ManBuildModelAig( Ntl_Man_t * p, Ntl_Obj_t * pBox )
+{
+ extern int Ntl_ManCollapse_rec( Ntl_Man_t * p, Ntl_Net_t * pNet );
+ Ntl_Mod_t * pModel = pBox->pImplem;
+ Ntl_Obj_t * pObj;
+ Ntl_Net_t * pNet, * pNetBox;
+ int i;
+ assert( Ntl_ObjFaninNum(pBox) == Ntl_ModelPiNum(pModel) );
+ assert( Ntl_ObjFanoutNum(pBox) == Ntl_ModelPoNum(pModel) );
+ // clear net visited flags
+ Ntl_ModelForEachNet( pModel, pNet, i )
+ pNet->nVisits = 0;
+ // transfer from the box to the PIs of the model
+ Ntl_ModelForEachPi( pModel, pObj, i )
+ {
+ pNet = Ntl_ObjFanout0(pObj);
+ pNetBox = Ntl_ObjFanin( pBox, i );
+ pNet->pCopy = pNetBox->pCopy;
+ pNet->nVisits = 2;
+ }
+ // compute AIG for the internal nodes
+ Ntl_ModelForEachPo( pModel, pObj, i )
+ if ( !Ntl_ManCollapse_rec( p, Ntl_ObjFanin0(pObj) ) )
+ return 0;
+ // transfer from the POs of the model to the box
+ Ntl_ModelForEachPo( pModel, pObj, i )
+ {
+ pNet = Ntl_ObjFanin0(pObj);
+ pNetBox = Ntl_ObjFanout( pBox, i );
+ pNetBox->pCopy = pNet->pCopy;
+ }
+ return 1;
+}
/**Function*************************************************************
- Synopsis [Extracts AIG from the netlist.]
+ Synopsis [Collects the nodes in a topological order.]
Description []
@@ -531,32 +576,121 @@ Aig_Man_t * Ntl_ManExtract( Ntl_Man_t * p )
SeeAlso []
***********************************************************************/
-/*
-int Ntl_ManExtract_old( Ntl_Man_t * p )
+int Ntl_ManCollapse_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_ManCollapse_rec( p, pNetFanin ) )
+ return 0;
+ // add box inputs/outputs to COs/CIs
+ if ( Ntl_ObjIsBox(pObj) )
+ {
+ if ( !Ntl_ManBuildModelAig( p, pObj ) )
+ return 0;
+ }
+ // store the node
+ if ( Ntl_ObjIsNode(pObj) )
+ pNet->pCopy = Ntl_ManBuildNodeAig( 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 []
+
+***********************************************************************/
+Aig_Man_t * Ntl_ManCollapse( Ntl_Man_t * p )
{
- Ntl_Obj_t * pNode;
+ Aig_Man_t * pAig;
+ Ntl_Mod_t * pRoot;
+ Ntl_Obj_t * pObj;
Ntl_Net_t * pNet;
int i;
- // check the DFS traversal
- if ( !Ntl_ManDfs( p ) )
- return 0;
// start the AIG manager
assert( p->pAig == NULL );
p->pAig = Aig_ManStart( 10000 );
- // create the primary inputs
- Ntl_ManForEachCiNet( p, pNet, i )
- pNet->pFunc = Aig_ObjCreatePi( p->pAig );
- // convert internal nodes to AIGs
- Ntl_ManForEachNode( p, pNode, i )
- Ntl_ObjFanout0(pNode)->pFunc = Ntl_ManExtractAigNode( pNode );
- // create the primary outputs
- Ntl_ManForEachCoNet( p, pNet, i )
- Aig_ObjCreatePo( p->pAig, pNet->pFunc );
+ p->pAig->pName = Aig_UtilStrsav( p->pName );
+ p->pAig->pSpec = Aig_UtilStrsav( p->pSpec );
+ // get the root model
+ pRoot = Ntl_ManRootModel( p );
+ // clear net visited flags
+ Ntl_ModelForEachNet( pRoot, pNet, i )
+ pNet->nVisits = 0;
+ // collect primary inputs
+ Ntl_ModelForEachPi( pRoot, pObj, i )
+ {
+ assert( Ntl_ObjFanoutNum(pObj) == 1 );
+ pNet = Ntl_ObjFanout0(pObj);
+ pNet->pCopy = Aig_ObjCreatePi( p->pAig );
+ if ( pNet->nVisits )
+ {
+ printf( "Ntl_ManCollapse(): 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);
+ pNet->pCopy = Aig_ObjCreatePi( p->pAig );
+ if ( pNet->nVisits )
+ {
+ printf( "Ntl_ManCollapse(): 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_ManCollapse_rec( p, pNet ) )
+ {
+ printf( "Ntl_ManCollapse(): Error: Combinational loop is detected.\n" );
+ return 0;
+ }
+ Aig_ObjCreatePo( p->pAig, pNet->pCopy );
+ }
+ // visit the nodes starting from latch inputs outputs
+ Ntl_ModelForEachLatch( pRoot, pObj, i )
+ {
+ pNet = Ntl_ObjFanin0(pObj);
+ if ( !Ntl_ManCollapse_rec( p, pNet ) )
+ {
+ printf( "Ntl_ManCollapse(): Error: Combinational loop is detected.\n" );
+ return 0;
+ }
+ Aig_ObjCreatePo( p->pAig, pNet->pCopy );
+ }
// cleanup the AIG
Aig_ManCleanup( p->pAig );
- return 1;
+ pAig = p->pAig; p->pAig = NULL;
+ return pAig;
}
-*/
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/ntl/ntlInsert.c b/src/aig/ntl/ntlInsert.c
index 84a7af84..2eb48e84 100644
--- a/src/aig/ntl/ntlInsert.c
+++ b/src/aig/ntl/ntlInsert.c
@@ -52,17 +52,17 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
int i, k, nDigits;
// map the AIG back onto the design
Ntl_ManForEachCiNet( p, pNet, i )
- pNet->pFunc = Aig_ManPi( pAig, i );
+ pNet->pCopy = Aig_ManPi( pAig, i );
Ntl_ManForEachCoNet( p, pNet, i )
- pNet->pFunc = Aig_ObjChild0( Aig_ManPo( pAig, i ) );
+ pNet->pCopy = Aig_ObjChild0( Aig_ManPo( pAig, i ) );
// remove old nodes
- pRoot = Vec_PtrEntry( p->vModels, 0 );
+ pRoot = Ntl_ManRootModel( p );
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 );
+ Vec_PtrWriteEntry( vCopies, ((Aig_Obj_t *)pNet->pCopy)->Id, pNet );
// create a new node for each LUT
vCover = Vec_IntAlloc( 1 << 16 );
nDigits = Aig_Base10Log( Vec_PtrSize(vMapping) );
@@ -100,16 +100,16 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
Vec_IntFree( vCover );
// mark CIs and outputs of the registers
Ntl_ManForEachCiNet( p, pNetCo, i )
- pNetCo->nVisits = 101;
+ pNetCo->nVisits = 101; // using "101" is harmless because nVisits can only be 0, 1 or 2
// 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 );
+ pNet = Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pCopy)->Id );
pNode = Ntl_ModelCreateNode( pRoot, 1 );
- pNode->pSop = Aig_IsComplement(pNetCo->pFunc)? 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 );
// update the CO driver net
pNetCo->pDriver = NULL;
@@ -134,7 +134,7 @@ int Ntl_ManInsert( Ntl_Man_t * p, Vec_Ptr_t * vMapping, Aig_Man_t * pAig )
SeeAlso []
***********************************************************************/
-int Ntl_ManInsertNtk( Ntl_Man_t * p, Ntk_Man_t * pNtk )
+int Ntl_ManInsertNtk( Ntl_Man_t * p, Nwk_Man_t * pNtk )
{
char Buffer[100];
Vec_Int_t * vTruth;
@@ -142,32 +142,34 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Ntk_Man_t * pNtk )
Ntl_Mod_t * pRoot;
Ntl_Obj_t * pNode;
Ntl_Net_t * pNet, * pNetCo;
- Ntk_Obj_t * pObj, * pFanin;
+ Nwk_Obj_t * pObj, * pFanin;
int i, k, nDigits;
unsigned * pTruth;
- assert( Vec_PtrSize(p->vCis) == Ntk_ManCiNum(pNtk) );
- assert( Vec_PtrSize(p->vCos) == Ntk_ManCoNum(pNtk) );
+ assert( Vec_PtrSize(p->vCis) == Nwk_ManCiNum(pNtk) );
+ assert( Vec_PtrSize(p->vCos) == Nwk_ManCoNum(pNtk) );
// set the correspondence between the PI/PO nodes
Ntl_ManForEachCiNet( p, pNet, i )
- Ntk_ManCi( pNtk, i )->pCopy = pNet;
+ Nwk_ManCi( pNtk, i )->pCopy = pNet;
// Ntl_ManForEachCoNet( p, pNet, i )
-// Ntk_ManCo( pNtk, i )->pCopy = pNet;
+// Nwk_ManCo( pNtk, i )->pCopy = pNet;
// remove old nodes
- pRoot = Vec_PtrEntry( p->vModels, 0 );
+ pRoot = Ntl_ManRootModel( p );
Ntl_ModelForEachNode( pRoot, pNode, i )
Vec_PtrWriteEntry( pRoot->vObjs, pNode->Id, NULL );
// create a new node for each LUT
vTruth = Vec_IntAlloc( 1 << 16 );
vCover = Vec_IntAlloc( 1 << 16 );
- nDigits = Aig_Base10Log( Ntk_ManNodeNum(pNtk) );
- Ntk_ManForEachNode( pNtk, pObj, i )
+ nDigits = Aig_Base10Log( Nwk_ManNodeNum(pNtk) );
+ Nwk_ManForEachNode( pNtk, pObj, i )
{
- pNode = Ntl_ModelCreateNode( pRoot, Ntk_ObjFaninNum(pObj) );
- pTruth = Hop_ManConvertAigToTruth( pNtk->pManHop, pObj->pFunc, Ntk_ObjFaninNum(pObj), vTruth, 0 );
- pNode->pSop = Ntl_SopFromTruth( p, pTruth, Ntk_ObjFaninNum(pObj), vCover );
- if ( !Kit_TruthIsConst0(pTruth, Ntk_ObjFaninNum(pObj)) && !Kit_TruthIsConst1(pTruth, Ntk_ObjFaninNum(pObj)) )
+ pNode = Ntl_ModelCreateNode( pRoot, Nwk_ObjFaninNum(pObj) );
+ pTruth = Hop_ManConvertAigToTruth( pNtk->pManHop, Hop_Regular(pObj->pFunc), Nwk_ObjFaninNum(pObj), vTruth, 0 );
+ if ( Hop_IsComplement(pObj->pFunc) )
+ Kit_TruthNot( pTruth, pTruth, Nwk_ObjFaninNum(pObj) );
+ pNode->pSop = Ntl_SopFromTruth( p, pTruth, Nwk_ObjFaninNum(pObj), vCover );
+ if ( !Kit_TruthIsConst0(pTruth, Nwk_ObjFaninNum(pObj)) && !Kit_TruthIsConst1(pTruth, Nwk_ObjFaninNum(pObj)) )
{
- Ntk_ObjForEachFanin( pObj, pFanin, k )
+ Nwk_ObjForEachFanin( pObj, pFanin, k )
{
pNet = pFanin->pCopy;
if ( pNet == NULL )
@@ -204,12 +206,12 @@ int Ntl_ManInsertNtk( Ntl_Man_t * p, Ntk_Man_t * pNtk )
continue;
pNetCo->nVisits = 101;
// get the corresponding PO and its driver
- pObj = Ntk_ManCo( pNtk, i );
- pFanin = Ntk_ObjFanin0( pObj );
+ pObj = Nwk_ManCo( pNtk, i );
+ pFanin = Nwk_ObjFanin0( pObj );
// get the net driving the driver
- pNet = pFanin->pCopy; //Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pFunc)->Id );
+ pNet = pFanin->pCopy; //Vec_PtrEntry( vCopies, Aig_Regular(pNetCo->pCopy)->Id );
pNode = Ntl_ModelCreateNode( pRoot, 1 );
- pNode->pSop = pObj->fCompl /*Aig_IsComplement(pNetCo->pFunc)*/? 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 );
// update the CO driver net
pNetCo->pDriver = NULL;
diff --git a/src/aig/ntl/ntlMan.c b/src/aig/ntl/ntlMan.c
index 9614a423..82660263 100644
--- a/src/aig/ntl/ntlMan.c
+++ b/src/aig/ntl/ntlMan.c
@@ -61,6 +61,57 @@ Ntl_Man_t * Ntl_ManAlloc( char * pFileName )
/**Function*************************************************************
+ Synopsis [Duplicates the interface of the top level model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ntl_Man_t * Ntl_ManStartFrom( Ntl_Man_t * pOld )
+{
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the interface of the top level model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ntl_Man_t * Ntl_ManDup( Ntl_Man_t * pOld )
+{
+ 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 )
+ 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 );
+ if ( !Ntl_ManCheck( pNew ) )
+ printf( "Ntl_ManDup: The check has failed for design %s.\n", pNew->pName );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Deallocates the netlist manager.]
Description []
@@ -126,15 +177,16 @@ Ntl_Mod_t * Ntl_ManFindModel( Ntl_Man_t * p, char * pName )
void Ntl_ManPrintStats( Ntl_Man_t * p )
{
Ntl_Mod_t * pRoot;
- pRoot = Vec_PtrEntry( p->vModels, 0 );
+ pRoot = Ntl_ManRootModel( p );
printf( "%-15s : ", p->pName );
printf( "pi = %5d ", Ntl_ModelPiNum(pRoot) );
printf( "po = %5d ", Ntl_ModelPoNum(pRoot) );
- printf( "latch = %5d ", Ntl_ModelLatchNum(pRoot) );
+ printf( "lat = %5d ", Ntl_ModelLatchNum(pRoot) );
printf( "node = %5d ", Ntl_ModelNodeNum(pRoot) );
printf( "box = %4d ", Ntl_ModelBoxNum(pRoot) );
- printf( "model = %3d", Vec_PtrSize(p->vModels) );
+ printf( "mod = %3d", Vec_PtrSize(p->vModels) );
printf( "\n" );
+ fflush( stdout );
}
/**Function*************************************************************
@@ -173,11 +225,11 @@ Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName )
p->pMan = pMan;
p->pName = Ntl_ManStoreName( p->pMan, pName );
Vec_PtrPush( pMan->vModels, p );
- p->vObjs = Vec_PtrAlloc( 10000 );
- p->vPis = Vec_PtrAlloc( 1000 );
- p->vPos = Vec_PtrAlloc( 1000 );
+ p->vObjs = Vec_PtrAlloc( 1000 );
+ p->vPis = Vec_PtrAlloc( 100 );
+ p->vPos = Vec_PtrAlloc( 100 );
// start the table
- p->nTableSize = Aig_PrimeCudd( 10000 );
+ p->nTableSize = Aig_PrimeCudd( 1000 );
p->pTable = ALLOC( Ntl_Net_t *, p->nTableSize );
memset( p->pTable, 0, sizeof(Ntl_Net_t *) * p->nTableSize );
return p;
@@ -185,6 +237,41 @@ Ntl_Mod_t * Ntl_ModelAlloc( Ntl_Man_t * pMan, char * pName )
/**Function*************************************************************
+ Synopsis [Duplicates the model.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ntl_Mod_t * Ntl_ModelDup( 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 )
+ pNet->pCopy = Ntl_ModelFindOrCreateNet( pModelNew, pNet->pName );
+ Ntl_ModelForEachObj( pModelOld, pObj, i )
+ {
+ pObj->pCopy = Ntl_ModelDupObj( pModelNew, pObj );
+ Ntl_ObjForEachFanin( pObj, pNet, k )
+ Ntl_ObjSetFanin( pObj->pCopy, pNet->pCopy, k );
+ Ntl_ObjForEachFanout( pObj, pNet, k )
+ Ntl_ObjSetFanout( pObj->pCopy, pNet->pCopy, k );
+ if ( Ntl_ObjIsLatch(pObj) )
+ ((Ntl_Obj_t *)pObj->pCopy)->LatchId = pObj->LatchId;
+ if ( Ntl_ObjIsNode(pObj) )
+ ((Ntl_Obj_t *)pObj->pCopy)->pSop = Ntl_ManStoreSop( pManNew, pObj->pSop );
+ }
+ return pModelNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Deallocates the model.]
Description []
diff --git a/src/aig/ntl/ntlMap.c b/src/aig/ntl/ntlMap.c
index 20bc79cf..faae32d2 100644
--- a/src/aig/ntl/ntlMap.c
+++ b/src/aig/ntl/ntlMap.c
@@ -136,7 +136,7 @@ void Ntl_ManSetIfParsDefault( If_Par_t * pPars )
pPars->fExpRed = 0;
pPars->fLatchPaths = 0;
pPars->fEdge = 1;
- pPars->fCutMin = 1;
+ pPars->fCutMin = 0;
pPars->fSeqMap = 0;
pPars->fVerbose = 1;
// internal parameters
diff --git a/src/aig/ntl/ntlObj.c b/src/aig/ntl/ntlObj.c
index 2e39fbbf..ad43623a 100644
--- a/src/aig/ntl/ntlObj.c
+++ b/src/aig/ntl/ntlObj.c
@@ -163,6 +163,33 @@ Ntl_Obj_t * Ntl_ModelCreateBox( Ntl_Mod_t * pModel, int nFanins, int nFanouts )
/**Function*************************************************************
+ Synopsis [Create the latch.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ntl_Obj_t * Ntl_ModelDupObj( Ntl_Mod_t * pModel, Ntl_Obj_t * pOld )
+{
+ Ntl_Obj_t * pNew;
+ if ( Ntl_ObjIsPi( pOld ) )
+ pNew = Ntl_ModelCreatePi( pModel );
+ else if ( Ntl_ObjIsPo( pOld ) )
+ pNew = Ntl_ModelCreatePo( pModel, NULL );
+ else if ( Ntl_ObjIsLatch( pOld ) )
+ pNew = Ntl_ModelCreateLatch( pModel );
+ else if ( Ntl_ObjIsNode( pOld ) )
+ pNew = Ntl_ModelCreateNode( pModel, Ntl_ObjFaninNum(pOld) );
+ else if ( Ntl_ObjIsBox( pOld ) )
+ pNew = Ntl_ModelCreateBox( pModel, Ntl_ObjFaninNum(pOld), Ntl_ObjFanoutNum(pOld) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Allocates memory and copies the name into it.]
Description []
diff --git a/src/aig/ntl/ntlReadBlif.c b/src/aig/ntl/ntlReadBlif.c
index d085b5e6..e5a94610 100644
--- a/src/aig/ntl/ntlReadBlif.c
+++ b/src/aig/ntl/ntlReadBlif.c
@@ -108,9 +108,7 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck )
{
FILE * pFile;
Ioa_ReadMan_t * p;
- Ntl_Mod_t * pNtk;
Ntl_Man_t * pDesign;
- int i;
// check that the file is available
pFile = fopen( pFileName, "rb" );
@@ -158,20 +156,9 @@ Ntl_Man_t * Ioa_ReadBlif( char * pFileName, int fCheck )
// make sure that everything is okay with the network structure
if ( fCheck )
{
- // check individual models
- Vec_PtrForEachEntry( pDesign->vModels, pNtk, i )
- {
- if ( !Ntl_ModelCheck( pNtk ) )
- {
- printf( "Ioa_ReadBlif: The network check has failed for network %s.\n", pNtk->pName );
- Ntl_ManFree( pDesign );
- return NULL;
- }
- }
- // check the hierarchy
if ( !Ntl_ManCheck( pDesign ) )
{
- printf( "Ioa_ReadBlif: The hierarchy check has failed for design %s.\n", pDesign->pName );
+ printf( "Ioa_ReadBlif: The check has failed for design %s.\n", pDesign->pName );
Ntl_ManFree( pDesign );
return NULL;
}
diff --git a/src/aig/ntl/ntlTable.c b/src/aig/ntl/ntlTable.c
index b84ac1a5..909a64fd 100644
--- a/src/aig/ntl/ntlTable.c
+++ b/src/aig/ntl/ntlTable.c
@@ -151,28 +151,6 @@ Ntl_Net_t * Ntl_ModelFindOrCreateNet( Ntl_Mod_t * p, char * pName )
/**Function*************************************************************
- Synopsis [Finds or creates the net.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet )
-{
- if ( pObj->pFanio[pObj->nFanins] != NULL )
- return 0;
- if ( pNet->pDriver != NULL )
- return 0;
- pObj->pFanio[pObj->nFanins] = pNet;
- pNet->pDriver = pObj;
- return 1;
-}
-
-/**Function*************************************************************
-
Synopsis [Returns -1, 0, +1 (when it is PI, not found, or PO).]
Description []
@@ -210,6 +188,28 @@ int Ntl_ModelFindPioNumber( Ntl_Mod_t * p, char * pName, int * pNumber )
return 0;
}
+/**Function*************************************************************
+
+ Synopsis [Finds or creates the net.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ntl_ModelSetNetDriver( Ntl_Obj_t * pObj, Ntl_Net_t * pNet )
+{
+ if ( pObj->pFanio[pObj->nFanins] != NULL )
+ return 0;
+ if ( pNet->pDriver != NULL )
+ return 0;
+ pObj->pFanio[pObj->nFanins] = pNet;
+ pNet->pDriver = pObj;
+ return 1;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/ntl/ntlTime.c b/src/aig/ntl/ntlTime.c
index 50f3d290..cf2ec0f1 100644
--- a/src/aig/ntl/ntlTime.c
+++ b/src/aig/ntl/ntlTime.c
@@ -84,7 +84,7 @@ Tim_Man_t * Ntl_ManCreateTiming( Ntl_Man_t * p )
Ntl_Obj_t * pObj;
int i, curPi, iBox, Entry;
assert( p->pAig != NULL );
- pRoot = Vec_PtrEntry( p->vModels, 0 );
+ pRoot = Ntl_ManRootModel( p );
// start the timing manager
pMan = Tim_ManStart( Aig_ManPiNum(p->pAig), Aig_ManPoNum(p->pAig) );
// unpack the data in the arrival times