summaryrefslogtreecommitdiffstats
path: root/src/base
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2006-04-12 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2006-04-12 08:01:00 -0700
commitc1710767b298a8acae16421a660a0874255636a5 (patch)
tree308ec887b66bcd608a1d7f448d45c27b3b2e93fb /src/base
parent3f4fc5e4507f7fb9df431fc116529b4c209ab97c (diff)
downloadabc-c1710767b298a8acae16421a660a0874255636a5.tar.gz
abc-c1710767b298a8acae16421a660a0874255636a5.tar.bz2
abc-c1710767b298a8acae16421a660a0874255636a5.zip
Version abc60412
Diffstat (limited to 'src/base')
-rw-r--r--src/base/abc/abc.h21
-rw-r--r--src/base/abc/abcCheck.c85
-rw-r--r--src/base/abc/abcDfs.c8
-rw-r--r--src/base/abc/abcNetlist.c158
-rw-r--r--src/base/abc/abcNtk.c23
-rw-r--r--src/base/abc/abcObj.c23
-rw-r--r--src/base/abc/abcUtil.c20
-rw-r--r--src/base/abci/abc.c100
-rw-r--r--src/base/abci/abcMiter.c55
-rw-r--r--src/base/abci/abcPrint.c9
-rw-r--r--src/base/abci/abcStrash.c68
-rw-r--r--src/base/cmd/cmd.c6
-rw-r--r--src/base/io/io.c2
-rw-r--r--src/base/io/io.h2
-rw-r--r--src/base/io/ioReadBlif.c686
-rw-r--r--src/base/io/ioWriteBlif.c48
16 files changed, 1099 insertions, 215 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index e0f0df99..32365b81 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -52,7 +52,8 @@ typedef enum {
ABC_NTK_LOGIC, // 2: network with PIs/POs, latches, and nodes
ABC_NTK_STRASH, // 3: structurally hashed AIG (two input AND gates with c-attributes on edges)
ABC_NTK_SEQ, // 4: sequential AIG (two input AND gates with c- and latch-attributes on edges)
- ABC_NTK_OTHER // 5: unused
+ ABC_NTK_BLACKBOX, // 5: black box about which nothing is known
+ ABC_NTK_OTHER // 6: unused
} Abc_NtkType_t;
// network functionality
@@ -62,7 +63,8 @@ typedef enum {
ABC_FUNC_BDD, // 2: binary decision diagrams
ABC_FUNC_AIG, // 3: and-inverter graphs
ABC_FUNC_MAP, // 4: standard cell library
- ABC_FUNC_OTHER // 5: unused
+ ABC_FUNC_BLACKBOX, // 5: black box about which nothing is known
+ ABC_FUNC_OTHER // 6: unused
} Abc_NtkFunc_t;
// Supported type/functionality combinations:
@@ -168,6 +170,7 @@ struct Abc_Ntk_t_
int nObjs; // the number of live objs
int nNets; // the number of live nets
int nNodes; // the number of live nodes
+ int nBoxes; // the number of live nodes
int nLatches; // the number of live latches
int nPis; // the number of primary inputs
int nPos; // the number of primary outputs
@@ -198,6 +201,11 @@ struct Abc_Ntk_t_
// the backup network and the step number
Abc_Ntk_t * pNetBackup; // the pointer to the previous backup network
int iStep; // the generation number for the given network
+ // hierarchical design
+ stmm_table * tName2Model; // the table hashing names into network pointers (or NULL if no hierarchy)
+ Vec_Int_t * pBlackBoxes; // stores pairs (PI num, PO num) for each model, including the base model (or NULL if no hierarchy)
+ short fHieVisited; // flag to mark the visited network
+ short fHiePath; // flag to mark the network on the path
// memory management
Extra_MmFlex_t * pMmNames; // memory manager for net names
Extra_MmFixed_t* pMmObj; // memory manager for objects
@@ -223,11 +231,13 @@ static inline bool Abc_NtkIsNetlist( Abc_Ntk_t * pNtk ) { return pN
static inline bool Abc_NtkIsLogic( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_LOGIC; }
static inline bool Abc_NtkIsStrash( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_STRASH; }
static inline bool Abc_NtkIsSeq( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_SEQ; }
+static inline bool Abc_NtkIsBlackbox( Abc_Ntk_t * pNtk ) { return pNtk->ntkType == ABC_NTK_BLACKBOX;}
static inline bool Abc_NtkHasSop( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP; }
static inline bool Abc_NtkHasBdd( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BDD; }
static inline bool Abc_NtkHasAig( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_AIG; }
static inline bool Abc_NtkHasMapping( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP; }
+static inline bool Abc_NtkHasBlackbox( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BLACKBOX; }
static inline bool Abc_NtkIsSopNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP && pNtk->ntkType == ABC_NTK_NETLIST; }
static inline bool Abc_NtkIsMappedNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_NTK_NETLIST; }
@@ -294,6 +304,7 @@ static inline Abc_Obj_t * Abc_ObjNotCond( Abc_Obj_t * p, int c ) { return (A
// checking the object type
static inline bool Abc_ObjIsNode( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NODE; }
+static inline bool Abc_ObjIsBox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BOX; }
static inline bool Abc_ObjIsNet( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_NET; }
static inline bool Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH; }
static inline bool Abc_ObjIsPi( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_PI; }
@@ -376,6 +387,9 @@ static inline int Abc_LatchInit( Abc_Obj_t * pLatch ) { assert(Ab
#define Abc_NtkForEachNode( pNtk, pNode, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNode) == NULL || !Abc_ObjIsNode(pNode) ) {} else
+#define Abc_NtkForEachBox( pNtk, pNode, i ) \
+ for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
+ if ( (pNode) == NULL || !Abc_ObjIsBox(pNode) ) {} else
#define Abc_AigForEachAnd( pNtk, pNode, i ) \
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNode) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
if ( (pNode) == NULL || !Abc_NodeIsAigAnd(pNode) ) {} else
@@ -510,6 +524,7 @@ extern Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName );
extern Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk );
+extern Abc_Obj_t * Abc_NtkCreateBox( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreatePo( Abc_Ntk_t * pNtk );
extern Abc_Obj_t * Abc_NtkCreateLatch( Abc_Ntk_t * pNtk );
@@ -651,6 +666,7 @@ extern char * Abc_SopFromTruthHex( char * pTruth );
extern Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, bool fAllNodes, bool fCleanup );
extern Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode );
extern int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
+extern Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels );
/*=== abcSweep.c ==========================================================*/
extern int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose );
extern int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose );
@@ -698,6 +714,7 @@ extern int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetClauseNum( Abc_Ntk_t * pNtk );
extern double Abc_NtkGetMappedArea( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetExorNum( Abc_Ntk_t * pNtk );
+extern int Abc_NtkGetMuxNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetChoiceNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetFaninMax( Abc_Ntk_t * pNtk );
extern void Abc_NtkCleanCopy( Abc_Ntk_t * pNtk );
diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c
index 080164bd..5c152409 100644
--- a/src/base/abc/abcCheck.c
+++ b/src/base/abc/abcCheck.c
@@ -38,6 +38,8 @@ static bool Abc_NtkComparePis( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
static bool Abc_NtkComparePos( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
static bool Abc_NtkCompareLatches( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
+static int Abc_NtkIsAcyclicHierarchy( Abc_Ntk_t * pNtk );
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -90,12 +92,12 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj, * pNet, * pNode;
int i;
- if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsSeq(pNtk) )
+ if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsSeq(pNtk) && !Abc_NtkIsBlackbox(pNtk) )
{
fprintf( stdout, "NetworkCheck: Unknown network type.\n" );
return 0;
}
- if ( !Abc_NtkHasSop(pNtk) && !Abc_NtkHasBdd(pNtk) && !Abc_NtkHasAig(pNtk) && !Abc_NtkHasMapping(pNtk) )
+ if ( !Abc_NtkHasSop(pNtk) && !Abc_NtkHasBdd(pNtk) && !Abc_NtkHasAig(pNtk) && !Abc_NtkHasMapping(pNtk) && !Abc_NtkHasBlackbox(pNtk) )
{
fprintf( stdout, "NetworkCheck: Unknown functionality type.\n" );
return 0;
@@ -187,6 +189,27 @@ bool Abc_NtkDoCheck( Abc_Ntk_t * pNtk )
// }
return Abc_NtkCheck( pNtk->pExdc );
}
+
+ // check the hierarchy
+ if ( Abc_NtkIsNetlist(pNtk) && pNtk->tName2Model )
+ {
+ stmm_generator * gen;
+ Abc_Ntk_t * pNtkTemp;
+ char * pName;
+ // check other networks
+ stmm_foreach_item( pNtk->tName2Model, gen, &pName, (char **)&pNtkTemp )
+ {
+ pNtkTemp->fHiePath = pNtkTemp->fHieVisited = 0;
+ if ( !Abc_NtkCheck( pNtkTemp ) )
+ return 0;
+ }
+ // check acyclic dependency of the models
+ if ( !Abc_NtkIsAcyclicHierarchy( pNtk ) )
+ {
+ fprintf( stdout, "NetworkCheck: Network hierarchical dependences contains a cycle.\n" );
+ return 0;
+ }
+ }
return 1;
}
@@ -711,6 +734,64 @@ bool Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
return 1;
}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 0 if the network hierachy contains a cycle.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkIsAcyclicHierarchy_rec( Abc_Ntk_t * pNtk )
+{
+ Abc_Ntk_t * pNtkNext;
+ Abc_Obj_t * pObj;
+ int i;
+ // return if visited
+ if ( pNtk->fHieVisited )
+ return 1;
+ pNtk->fHieVisited = 1;
+ // return if black box
+ if ( Abc_NtkIsBlackbox(pNtk) )
+ return 1;
+ assert( Abc_NtkIsNetlist(pNtk) );
+ // go through all the children networks
+ Abc_NtkForEachBox( pNtk, pObj, i )
+ {
+ pNtkNext = pObj->pData;
+ assert( pNtkNext != NULL );
+ if ( pNtkNext->fHiePath )
+ return 0;
+ pNtk->fHiePath = 1;
+ if ( !Abc_NtkIsAcyclicHierarchy_rec( pNtkNext ) )
+ return 0;
+ pNtk->fHiePath = 0;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 0 if the network hierachy contains a cycle.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkIsAcyclicHierarchy( Abc_Ntk_t * pNtk )
+{
+ assert( Abc_NtkIsNetlist(pNtk) && pNtk->tName2Model );
+ pNtk->fHiePath = 1;
+ return Abc_NtkIsAcyclicHierarchy_rec( pNtk );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abc/abcDfs.c b/src/base/abc/abcDfs.c
index 9701c0e2..bd707c25 100644
--- a/src/base/abc/abcDfs.c
+++ b/src/base/abc/abcDfs.c
@@ -129,7 +129,7 @@ void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
// skip the CI
if ( Abc_ObjIsCi(pNode) )
return;
- assert( Abc_ObjIsNode( pNode ) );
+ assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
// visit the transitive fanin of the node
Abc_ObjForEachFanin( pNode, pFanin, i )
Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(pFanin), vNodes );
@@ -581,15 +581,15 @@ bool Abc_NtkIsAcyclic_rec( Abc_Obj_t * pNode )
assert( !Abc_ObjIsNet(pNode) );
if ( Abc_ObjIsCi(pNode) )
return 1;
- assert( Abc_ObjIsNode( pNode ) );
+ assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
// make sure the node is not visited
assert( !Abc_NodeIsTravIdPrevious(pNode) );
// check if the node is part of the combinational loop
if ( Abc_NodeIsTravIdCurrent(pNode) )
{
- fprintf( stdout, "Network \"%s\" contains combinational loop!\n", pNtk->pName );
+ fprintf( stdout, "Network \"%s\" contains combinational loop!\n", Abc_NtkName(pNtk) );
fprintf( stdout, "Node \"%s\" is encountered twice on the following path:\n", Abc_ObjName(pNode) );
- fprintf( stdout, " %s", Abc_ObjName(pNode) );
+ fprintf( stdout, " %s", Abc_ObjIsNode(pNode)? Abc_ObjName(pNode) : Abc_NtkName(pNode->pData) );
return 0;
}
// mark this node as a node on the current path
diff --git a/src/base/abc/abcNetlist.c b/src/base/abc/abcNetlist.c
index 737d63c2..75f3ed33 100644
--- a/src/base/abc/abcNetlist.c
+++ b/src/base/abc/abcNetlist.c
@@ -24,7 +24,9 @@
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-
+
+static Abc_Ntk_t * Abc_NtkNetlistToLogicHie( Abc_Ntk_t * pNtk );
+static void Abc_NtkNetlistToLogicHie_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtkOld, int * pCounter );
static void Abc_NtkAddPoBuffers( Abc_Ntk_t * pNtk );
////////////////////////////////////////////////////////////////////////
@@ -48,6 +50,9 @@ Abc_Ntk_t * Abc_NtkNetlistToLogic( Abc_Ntk_t * pNtk )
Abc_Obj_t * pObj, * pFanin;
int i, k;
assert( Abc_NtkIsNetlist(pNtk) );
+ // consider simple case when there is hierarchy
+ if ( pNtk->tName2Model )
+ return Abc_NtkNetlistToLogicHie( pNtk );
// start the network
if ( !Abc_NtkHasMapping(pNtk) )
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
@@ -74,6 +79,157 @@ Abc_Ntk_t * Abc_NtkNetlistToLogic( Abc_Ntk_t * pNtk )
/**Function*************************************************************
+ Synopsis [Transform the netlist into a logic network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkNetlistToLogicHie( Abc_Ntk_t * pNtk )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObj;
+ int i, Counter = 0;
+ assert( Abc_NtkIsNetlist(pNtk) );
+ // start the network
+// pNtkNew = Abc_NtkAlloc( Type, Func );
+ if ( !Abc_NtkHasMapping(pNtk) )
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ else
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_MAP );
+ // duplicate the name and the spec
+ pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
+ pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
+ // clean the node copy fields
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ pObj->pCopy = NULL;
+ // map the constant nodes
+ if ( Abc_NtkConst1(pNtk) )
+ Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
+ // clone PIs/POs and make old nets point to new terminals; create PI/PO names
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ {
+ Abc_ObjFanout0(pObj)->pCopy = Abc_NtkDupObj(pNtkNew, pObj);
+ Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
+ }
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ Abc_NtkDupObj(pNtkNew, pObj);
+ Abc_NtkLogicStoreName( pObj->pCopy, Abc_ObjName(pObj) );
+ }
+ // recursively flatten hierarchy, create internal logic, add new PI/PO names if there are black boxes
+ Abc_NtkNetlistToLogicHie_rec( pNtkNew, pNtk, &Counter );
+ if ( Counter )
+ printf( "Warning: The total of %d block boxes are transformed into PI/PO pairs.\n", Counter );
+ // add latches
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ Abc_ObjFanout0(pObj)->pCopy = Abc_NtkDupObj(pNtkNew, pObj);
+ Vec_PtrPush( pNtkNew->vCis, pObj->pCopy );
+ Vec_PtrPush( pNtkNew->vCos, pObj->pCopy );
+ Abc_NtkLogicStoreName( Abc_NtkLatch(pNtkNew,i), Abc_ObjName(pObj) );
+ }
+ // collect the CO nodes
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy );
+ // copy the timing information
+ Abc_ManTimeDup( pNtk, pNtkNew );
+ // fix the problem with CO pointing directly to CIs
+ Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
+ // duplicate EXDC
+ if ( pNtk->pExdc )
+ pNtkNew->pExdc = Abc_NtkNetlistToLogic( pNtk->pExdc );
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ fprintf( stdout, "Abc_NtkNetlistToLogic(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform the netlist into a logic network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkNetlistToLogicHie_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtkOld, int * pCounter )
+{
+ char Prefix[1000];
+ Vec_Ptr_t * vNodes;
+ Abc_Ntk_t * pNtkModel;
+ Abc_Obj_t * pNode, * pObj, * pFanin;
+ int i, k;
+ // collect nodes and boxes in topological order
+ vNodes = Abc_NtkDfs( pNtkOld, 0 );
+ // create logic for nodes and boxes
+ Vec_PtrForEachEntry( vNodes, pNode, i )
+ {
+ if ( Abc_ObjFaninNum(pNode) == 0 )
+ continue;
+ if ( Abc_ObjIsNode(pNode) )
+ {
+ // duplicate the node and save it in the fanout net
+ Abc_NtkDupObj( pNtkNew, pNode );
+ Abc_ObjForEachFanin( pNode, pFanin, k )
+ Abc_ObjAddFanin( pNode->pCopy, pFanin->pCopy );
+ Abc_ObjFanout0(pNode)->pCopy = pNode->pCopy;
+ continue;
+ }
+ assert( Abc_ObjIsBox(pNode) );
+ pNtkModel = pNode->pData;
+ // consider the case of the black box
+ if ( Abc_NtkIsBlackbox(pNtkModel) )
+ {
+ if ( pNtkNew->pBlackBoxes == NULL )
+ {
+ pNtkNew->pBlackBoxes = Vec_IntAlloc( 10 );
+ Vec_IntPush( pNtkNew->pBlackBoxes, (Abc_NtkPiNum(pNtkNew) << 16) | Abc_NtkPoNum(pNtkNew) );
+ }
+ sprintf( Prefix, "%s_%d_", Abc_NtkName(pNtkModel), *pCounter );
+ // create new PIs from the POs of the box
+ Abc_NtkForEachPo( pNtkModel, pObj, k )
+ {
+ pObj->pCopy = Abc_NtkCreatePi( pNtkNew );
+ Abc_ObjFanout(pNode, k)->pCopy = pObj->pCopy;
+ Abc_NtkLogicStoreNamePlus( pObj->pCopy, Prefix, Abc_ObjName(pObj) );
+ }
+ // create new POs from the PIs of the box
+ Abc_NtkForEachPi( pNtkModel, pObj, k )
+ {
+ pObj->pCopy = Abc_NtkCreatePo( pNtkNew );
+ Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin(pNode, k)->pCopy );
+ Abc_NtkLogicStoreNamePlus( pObj->pCopy, Prefix, Abc_ObjName(pObj) );
+ }
+ (*pCounter)++;
+ Vec_IntPush( pNtkNew->pBlackBoxes, (Abc_NtkPiNum(pNtkNew) << 16) | Abc_NtkPoNum(pNtkNew) );
+ }
+ else
+ {
+ // map the constant nodes
+ if ( Abc_NtkConst1(pNtkModel) )
+ Abc_NtkConst1(pNtkModel)->pCopy = Abc_NtkConst1(pNtkNew);
+ // transfer the nodes to the box inputs
+ Abc_NtkForEachPi( pNtkModel, pObj, k )
+ Abc_ObjFanout0(pObj)->pCopy = Abc_ObjFanin(pNode, k)->pCopy;
+ // construct recursively
+ Abc_NtkNetlistToLogicHie_rec( pNtkNew, pNtkModel, pCounter );
+ // transfer the results back
+ Abc_NtkForEachPo( pNtkModel, pObj, k )
+ Abc_ObjFanout(pNode, k)->pCopy = Abc_ObjFanin0(pObj)->pCopy;
+ }
+ }
+ Vec_PtrFree( vNodes );
+}
+
+
+/**Function*************************************************************
+
Synopsis [Transform the logic network into a netlist.]
Description []
diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c
index 60ad2412..0640d661 100644
--- a/src/base/abc/abcNtk.c
+++ b/src/base/abc/abcNtk.c
@@ -320,8 +320,17 @@ Abc_Ntk_t * Abc_NtkStartRead( char * pName )
***********************************************************************/
void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk )
{
- Abc_Obj_t * pLatch;
+ Abc_Obj_t * pLatch, * pBox, * pObj;
int i;
+ if ( pNtk->ntkType == ABC_NTK_BLACKBOX )
+ {
+ pBox = Abc_NtkCreateBox(pNtk);
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ Abc_ObjAddFanin( pBox, Abc_ObjFanout0(pObj) );
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ Abc_ObjAddFanin( Abc_ObjFanin0(pObj), pBox );
+ return;
+ }
assert( Abc_NtkIsNetlist(pNtk) );
// fix the net drivers
Abc_NtkFixNonDrivenNets( pNtk );
@@ -788,6 +797,18 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
}
else if ( !Abc_NtkHasMapping(pNtk) )
assert( 0 );
+ // free the hierarchy
+ if ( Abc_NtkIsNetlist(pNtk) && pNtk->tName2Model )
+ {
+ stmm_generator * gen;
+ Abc_Ntk_t * pNtkTemp;
+ char * pName;
+ stmm_foreach_item( pNtk->tName2Model, gen, &pName, (char **)&pNtkTemp )
+ Abc_NtkDelete( pNtkTemp );
+ stmm_free_table( pNtk->tName2Model );
+ if ( pNtk->pBlackBoxes )
+ Vec_IntFree( pNtk->pBlackBoxes );
+ }
free( pNtk );
}
diff --git a/src/base/abc/abcObj.c b/src/base/abc/abcObj.c
index 0ffe3298..68518ef0 100644
--- a/src/base/abc/abcObj.c
+++ b/src/base/abc/abcObj.c
@@ -128,6 +128,10 @@ void Abc_ObjAdd( Abc_Obj_t * pObj )
Vec_PtrPush( pNtk->vCos, pObj );
pNtk->nPos++;
}
+ else if ( Abc_ObjIsBox(pObj) )
+ {
+ pNtk->nBoxes++;
+ }
else
{
assert( 0 );
@@ -415,6 +419,25 @@ Abc_Obj_t * Abc_NtkCreateNode( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
+Abc_Obj_t * Abc_NtkCreateBox( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ pObj = Abc_ObjAlloc( pNtk, ABC_OBJ_BOX );
+ Abc_ObjAdd( pObj );
+ return pObj;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create the new node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
Abc_Obj_t * Abc_NtkCreatePi( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj;
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c
index 122cf589..8449c91d 100644
--- a/src/base/abc/abcUtil.c
+++ b/src/base/abc/abcUtil.c
@@ -249,6 +249,26 @@ int Abc_NtkGetExorNum( Abc_Ntk_t * pNtk )
/**Function*************************************************************
+ Synopsis [Counts the number of exors.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkGetMuxNum( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode;
+ int i, Counter = 0;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ Counter += Abc_NodeIsMuxType(pNode);
+ return Counter;
+}
+
+/**Function*************************************************************
+
Synopsis [Returns 1 if it is an AIG with choice nodes.]
Description []
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 26ef2b66..697c3b32 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -68,6 +68,7 @@ static int Abc_CommandRr ( Abc_Frame_t * pAbc, int argc, char ** argv
static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMiter ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandDemiter ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandFrames ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSop ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandBdd ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -176,6 +177,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
// Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 );
Cmd_CommandAdd( pAbc, "Various", "miter", Abc_CommandMiter, 1 );
+ Cmd_CommandAdd( pAbc, "Various", "demiter", Abc_CommandDemiter, 1 );
Cmd_CommandAdd( pAbc, "Various", "frames", Abc_CommandFrames, 1 );
Cmd_CommandAdd( pAbc, "Various", "sop", Abc_CommandSop, 0 );
Cmd_CommandAdd( pAbc, "Various", "bdd", Abc_CommandBdd, 0 );
@@ -3022,6 +3024,80 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pOut, * pErr;
+ Abc_Ntk_t * pNtk, * pNtkRes;
+ int fComb;
+ int c;
+ extern Abc_Ntk_t * Abc_NtkDemiter( Abc_Ntk_t * pNtk );
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+ pOut = Abc_FrameReadOut(pAbc);
+ pErr = Abc_FrameReadErr(pAbc);
+
+ // set defaults
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'c':
+ fComb ^= 1;
+ break;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( !Abc_NtkIsStrash(pNtk) )
+ {
+ fprintf( pErr, "The network is not strashed.\n" );
+ return 1;
+ }
+
+ if ( Abc_NtkPoNum(pNtk) != 1 )
+ {
+ fprintf( pErr, "The network is not a miter.\n" );
+ return 1;
+ }
+
+ if ( !Abc_ObjFanin0(Abc_NtkPo(pNtk,0))->fExor )
+ {
+ fprintf( pErr, "The miter's PO is not an EXOR.\n" );
+ return 1;
+ }
+
+ // get the new network
+ pNtkRes = Abc_NtkDemiter( pNtk );
+ if ( pNtkRes == NULL )
+ {
+ fprintf( pErr, "Miter computation has failed.\n" );
+ return 1;
+ }
+ // replace the current network
+// Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pErr, "usage: demiter [-h]\n" );
+ fprintf( pErr, "\t removes topmost EXOR from the miter to create two POs\n" );
+// fprintf( pErr, "\t-c : computes combinational miter (latches as POs) [default = %s]\n", fComb? "yes": "no" );
+ fprintf( pErr, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandFrames( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
@@ -4398,6 +4474,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;//, * pNtkRes;
int c;
+ int nLevels;
// extern Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk );
pNtk = Abc_FrameReadNtk(pAbc);
@@ -4405,11 +4482,23 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc);
// set defaults
+ nLevels = 15;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF )
{
switch ( c )
{
+ case 'N':
+ if ( globalUtilOptind >= argc )
+ {
+ fprintf( pErr, "Command line switch \"-N\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ nLevels = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nLevels < 0 )
+ goto usage;
+ break;
case 'h':
goto usage;
default:
@@ -4451,7 +4540,14 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
// Cut_CellDumpToFile();
// else
// Cut_CellPrecompute();
- Cut_CellLoad();
+// Cut_CellLoad();
+
+ {
+ Abc_Ntk_t * pNtkRes;
+ extern Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels );
+ pNtkRes = Abc_NtkTopmost( pNtk, nLevels );
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ }
return 0;
diff --git a/src/base/abci/abcMiter.c b/src/base/abci/abcMiter.c
index 87ea57f3..76ec8a7e 100644
--- a/src/base/abci/abcMiter.c
+++ b/src/base/abci/abcMiter.c
@@ -953,6 +953,61 @@ void Abc_NtkAddFrame2( Abc_Ntk_t * pNtkFrames, Abc_Ntk_t * pNtk, int iFrame, Vec
}
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives the timeframes of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkDemiter( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNodeC, * pNodeA, * pNodeB, * pNode;
+ Abc_Obj_t * pPoNew;
+ Vec_Ptr_t * vNodes1, * vNodes2;
+ int nCommon, i;
+
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( Abc_NtkPoNum(pNtk) == 1 );
+ assert( Abc_ObjFanin0(Abc_NtkPo(pNtk,0))->fExor );
+ pNodeC = Abc_NodeRecognizeMux( Abc_ObjFanin0(Abc_NtkPo(pNtk,0)), &pNodeA, &pNodeB );
+ assert( Abc_ObjRegular(pNodeA) == Abc_ObjRegular(pNodeB) );
+
+ pPoNew = Abc_NtkCreatePo( pNtk );
+ Abc_ObjAddFanin( pPoNew, pNodeC );
+ Abc_NtkLogicStoreName( pPoNew, "addOut1" );
+
+ pPoNew = Abc_NtkCreatePo( pNtk );
+ Abc_ObjAddFanin( pPoNew, Abc_ObjRegular(pNodeA) );
+ Abc_NtkLogicStoreName( pPoNew, "addOut2" );
+
+ // mark the nodes in the first cone
+ pNodeA = Abc_ObjRegular(pNodeA);
+ vNodes1 = Abc_NtkDfsNodes( pNtk, &pNodeC, 1 );
+ vNodes2 = Abc_NtkDfsNodes( pNtk, &pNodeA, 1 );
+
+ Vec_PtrForEachEntry( vNodes1, pNode, i )
+ pNode->fMarkA = 1;
+ nCommon = 0;
+ Vec_PtrForEachEntry( vNodes2, pNode, i )
+ nCommon += pNode->fMarkA;
+ Vec_PtrForEachEntry( vNodes1, pNode, i )
+ pNode->fMarkA = 0;
+
+ printf( "First cone = %6d. Second cone = %6d. Common = %6d.\n", vNodes1->nSize, vNodes2->nSize, nCommon );
+ Vec_PtrFree( vNodes1 );
+ Vec_PtrFree( vNodes2 );
+
+
+ return pNtk;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abcPrint.c b/src/base/abci/abcPrint.c
index 56b70c5b..eec9e305 100644
--- a/src/base/abci/abcPrint.c
+++ b/src/base/abci/abcPrint.c
@@ -48,7 +48,7 @@
***********************************************************************/
void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
{
- int Num;
+ int Num, Num2;
fprintf( pFile, "%-13s:", pNtk->pName );
fprintf( pFile, " i/o = %4d/%4d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk) );
@@ -64,18 +64,23 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) );
}
else if ( Abc_NtkHasAig(pNtk) )
- {
+ {
fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) );
if ( Num = Abc_NtkGetChoiceNum(pNtk) )
fprintf( pFile, " (choice = %d)", Num );
if ( Num = Abc_NtkGetExorNum(pNtk) )
fprintf( pFile, " (exor = %d)", Num );
+ if ( Num2 = Abc_NtkGetMuxNum(pNtk) )
+ fprintf( pFile, " (mux = %d)", Num2-Num );
+ if ( Num2 )
+ fprintf( pFile, " (other = %d)", Abc_NtkNodeNum(pNtk)-3*Num2 );
}
else
fprintf( pFile, " nd = %5d", Abc_NtkNodeNum(pNtk) );
if ( Abc_NtkHasSop(pNtk) )
{
+
fprintf( pFile, " cube = %5d", Abc_NtkGetCubeNum(pNtk) );
// fprintf( pFile, " lit(sop) = %5d", Abc_NtkGetLitNum(pNtk) );
if ( fFactored )
diff --git a/src/base/abci/abcStrash.c b/src/base/abci/abcStrash.c
index cfbd4694..b546d8be 100644
--- a/src/base/abci/abcStrash.c
+++ b/src/base/abci/abcStrash.c
@@ -332,6 +332,74 @@ Abc_Obj_t * Abc_NodeStrashFactor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pRoot, char *
return pAnd;
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Copies the topmost levels of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Abc_NtkTopmost_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int LevelCut )
+{
+ assert( Abc_ObjIsComplement(pNode) );
+ if ( pNode->pCopy )
+ return pNode->pCopy;
+ if ( pNode->Level <= (unsigned)LevelCut )
+ return pNode->pCopy = Abc_NtkCreatePi( pNtkNew );
+ Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(pNode), LevelCut );
+ Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin1(pNode), LevelCut );
+ return pNode->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Copies the topmost levels of the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels )
+{
+ Abc_Ntk_t * pNtkNew;
+ Abc_Obj_t * pObjNew, * pPoNew;
+ int LevelCut;
+ assert( Abc_NtkIsStrash(pNtk) );
+ assert( Abc_NtkCoNum(pNtk) == 1 );
+ // get the cutoff level
+ LevelCut = ABC_MAX( 0, Abc_AigGetLevelNum(pNtk) - nLevels );
+ // start the network
+ pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG );
+ pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
+ Abc_NtkConst1(pNtk)->pCopy = Abc_NtkConst1(pNtkNew);
+ // create PIs below the cut and nodes above the cut
+ Abc_NtkCleanCopy( pNtk );
+ pObjNew = Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(Abc_NtkPo(pNtk, 0)), LevelCut );
+ // add the PO node and name
+ pPoNew = Abc_NtkCreatePo(pNtkNew);
+ Abc_ObjAddFanin( pPoNew, pObjNew );
+ Abc_NtkAddDummyPiNames( pNtkNew );
+ Abc_NtkLogicStoreName( pPoNew, Abc_ObjName(Abc_NtkPo(pNtk, 0)) );
+ // make sure everything is okay
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkTopmost: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c
index 0d90679d..93fe2b90 100644
--- a/src/base/cmd/cmd.c
+++ b/src/base/cmd/cmd.c
@@ -1264,7 +1264,7 @@ int CmdCommandSis( Abc_Frame_t * pAbc, int argc, char **argv )
fprintf( pErr, "Cannot produce the intermediate network.\n" );
goto usage;
}
- Io_WriteBlif( pNetlist, "_sis_in.blif", 1 );
+ Io_WriteBlifNetlist( pNetlist, "_sis_in.blif", 1 );
Abc_NtkDelete( pNetlist );
// create the file for sis
@@ -1405,7 +1405,7 @@ int CmdCommandMvsis( Abc_Frame_t * pAbc, int argc, char **argv )
fprintf( pErr, "Cannot produce the intermediate network.\n" );
goto usage;
}
- Io_WriteBlif( pNetlist, "_mvsis_in.blif", 1 );
+ Io_WriteBlifNetlist( pNetlist, "_mvsis_in.blif", 1 );
Abc_NtkDelete( pNetlist );
// create the file for MVSIS
@@ -1551,7 +1551,7 @@ int CmdCommandCapo( Abc_Frame_t * pAbc, int argc, char **argv )
fprintf( pErr, "Cannot produce the intermediate network.\n" );
goto usage;
}
- Io_WriteBlif( pNetlist, "_capo_in.blif", 1 );
+ Io_WriteBlifNetlist( pNetlist, "_capo_in.blif", 1 );
Abc_NtkDelete( pNetlist );
// create the file for Capo
diff --git a/src/base/io/io.c b/src/base/io/io.c
index 0aa5e415..614fa812 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -912,7 +912,7 @@ int IoCommandWriteBlif( Abc_Frame_t * pAbc, int argc, char **argv )
return 0;
}
Io_WriteBlifLogic( pNtk, FileName, fWriteLatches );
-// Io_WriteBlif( pNtk, FileName, fWriteLatches );
+// Io_WriteBlifNetlist( pNtk, FileName, fWriteLatches );
return 0;
usage:
diff --git a/src/base/io/io.h b/src/base/io/io.h
index a9a61040..b408293e 100644
--- a/src/base/io/io.h
+++ b/src/base/io/io.h
@@ -77,8 +77,8 @@ extern FILE * Io_FileOpen( const char * FileName, const char * PathV
/*=== abcWriteBaf.c ==========================================================*/
extern void Io_WriteBaf( Abc_Ntk_t * pNtk, char * pFileName );
/*=== abcWriteBlif.c ==========================================================*/
-extern void Io_WriteBlif( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
+extern void Io_WriteBlifNetlist( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches );
extern void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk );
/*=== abcWriteBench.c ==========================================================*/
extern int Io_WriteBench( Abc_Ntk_t * pNtk, char * FileName );
diff --git a/src/base/io/ioReadBlif.c b/src/base/io/ioReadBlif.c
index 39b85a10..9d74a782 100644
--- a/src/base/io/ioReadBlif.c
+++ b/src/base/io/ioReadBlif.c
@@ -33,11 +33,10 @@ struct Io_ReadBlif_t_
char * pFileName; // the name of the file
Extra_FileReader_t * pReader; // the input file reader
// current processing info
- Abc_Ntk_t * pNtk; // the primary network
- Abc_Ntk_t * pNtkExdc; // the exdc network
- int fParsingExdc; // this flag is on, when we are parsing EXDC network
+ Abc_Ntk_t * pNtkCur; // the primary network
int LineCur; // the line currently parsed
// temporary storage for tokens
+ Vec_Ptr_t * vTokens; // the current tokens
Vec_Ptr_t * vNewTokens; // the temporary storage for the tokens
Vec_Str_t * vCubes; // the temporary storage for the tokens
// the error message
@@ -49,16 +48,19 @@ static Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName );
static void Io_ReadBlifFree( Io_ReadBlif_t * p );
static void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p );
static Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p );
-static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p );
static char * Io_ReadBlifCleanName( char * pName );
+static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p );
+static Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p );
static int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens );
static int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
+static int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
+static int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -66,9 +68,9 @@ static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t *
/**Function*************************************************************
- Synopsis [Reads the network from a BLIF file.]
+ Synopsis [Reads the (hierarchical) network from the BLIF file.]
- Description [Works only for flat (non-hierarchical) BLIF.]
+ Description []
SideEffects []
@@ -78,34 +80,22 @@ static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t *
Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
{
Io_ReadBlif_t * p;
- Abc_Ntk_t * pNtk, * pNtkExdc;
+ Abc_Ntk_t * pNtk;
// start the file
p = Io_ReadBlifFile( pFileName );
if ( p == NULL )
return NULL;
- // read the network
+ // read the hierarchical network
pNtk = Io_ReadBlifNetwork( p );
if ( pNtk == NULL )
{
Io_ReadBlifFree( p );
return NULL;
}
+ pNtk->pSpec = Extra_UtilStrsav( pFileName );
Abc_NtkTimeInitialize( pNtk );
-
- // read the EXDC network
- if ( p->fParsingExdc )
- {
- pNtkExdc = Io_ReadBlifNetwork( p );
- if ( pNtkExdc == NULL )
- {
- Abc_NtkDelete( pNtk );
- Io_ReadBlifFree( p );
- return NULL;
- }
- pNtk->pExdc = pNtkExdc;
- }
Io_ReadBlifFree( p );
// make sure that everything is okay with the network structure
@@ -120,7 +110,7 @@ Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
/**Function*************************************************************
- Synopsis [Starts the reading data structure.]
+ Synopsis [Iteratively reads several networks in the hierarchical design.]
Description []
@@ -129,141 +119,76 @@ Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
SeeAlso []
***********************************************************************/
-Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName )
+Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
{
- Extra_FileReader_t * pReader;
- Io_ReadBlif_t * p;
-
- // start the reader
- pReader = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t" );
+ Abc_Ntk_t * pNtk, * pNtkMaster;
- if ( pReader == NULL )
+ // read the name of the master network
+ p->vTokens = Io_ReadBlifGetTokens(p);
+ if ( p->vTokens == NULL || strcmp( p->vTokens->pArray[0], ".model" ) )
+ {
+ p->LineCur = 0;
+ sprintf( p->sError, "Wrong input file format." );
+ Io_ReadBlifPrintErrorMessage( p );
return NULL;
+ }
- // start the reading data structure
- p = ALLOC( Io_ReadBlif_t, 1 );
- memset( p, 0, sizeof(Io_ReadBlif_t) );
- p->pFileName = pFileName;
- p->pReader = pReader;
- p->Output = stdout;
- p->vNewTokens = Vec_PtrAlloc( 100 );
- p->vCubes = Vec_StrAlloc( 100 );
- return p;
-}
-
-/**Function*************************************************************
-
- Synopsis [Frees the data structure.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Io_ReadBlifFree( Io_ReadBlif_t * p )
-{
- Extra_FileReaderFree( p->pReader );
- Vec_PtrFree( p->vNewTokens );
- Vec_StrFree( p->vCubes );
- free( p );
-}
-
-/**Function*************************************************************
-
- Synopsis [Prints the error message including the file name and line number.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p )
-{
- if ( p->LineCur == 0 ) // the line number is not given
- fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError );
- else // print the error message with the line number
- fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError );
-}
-
-/**Function*************************************************************
-
- Synopsis [Gets the tokens taking into account the line breaks.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p )
-{
- Vec_Ptr_t * vTokens;
- char * pLastToken;
- int i;
-
- // get rid of the old tokens
- if ( p->vNewTokens->nSize > 0 )
+ // read networks (with EXDC)
+ pNtkMaster = NULL;
+ while ( p->vTokens )
{
- for ( i = 0; i < p->vNewTokens->nSize; i++ )
- free( p->vNewTokens->pArray[i] );
- p->vNewTokens->nSize = 0;
+ // read the network and its EXDC if present
+ pNtk = Io_ReadBlifNetworkOne( p );
+ if ( pNtk == NULL )
+ break;
+ if ( p->vTokens && strcmp(p->vTokens->pArray[0], ".exdc") == 0 )
+ {
+ pNtk->pExdc = Io_ReadBlifNetworkOne( p );
+ Abc_NtkFinalizeRead( pNtk->pExdc );
+ if ( pNtk->pExdc == NULL )
+ break;
+ }
+ // add this network as part of the hierarchy
+ if ( pNtkMaster == NULL ) // no master network so far
+ {
+ pNtkMaster = pNtk;
+ continue;
+ }
+ // make sure hierarchy does not have the network with this name
+ if ( pNtkMaster->tName2Model && stmm_is_member( pNtkMaster->tName2Model, pNtk->pName ) )
+ {
+ p->LineCur = 0;
+ sprintf( p->sError, "Model %s is multiply defined in the file.", pNtk->pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ Abc_NtkDelete( pNtk );
+ Abc_NtkDelete( pNtkMaster );
+ pNtkMaster = NULL;
+ return NULL;
+ }
+ // add the network to the hierarchy
+ if ( pNtkMaster->tName2Model == NULL )
+ pNtkMaster->tName2Model = stmm_init_table(strcmp, stmm_strhash);
+ stmm_insert( pNtkMaster->tName2Model, pNtk->pName, (char *)pNtk );
}
- // get the new tokens
- vTokens = Extra_FileReaderGetTokens(p->pReader);
- if ( vTokens == NULL )
- return vTokens;
-
- // check if there is a transfer to another line
- pLastToken = vTokens->pArray[vTokens->nSize - 1];
- if ( pLastToken[ strlen(pLastToken)-1 ] != '\\' )
- return vTokens;
-
- // remove the slash
- pLastToken[ strlen(pLastToken)-1 ] = 0;
- if ( pLastToken[0] == 0 )
- vTokens->nSize--;
- // load them into the new array
- for ( i = 0; i < vTokens->nSize; i++ )
- Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
-
- // load as long as there is the line break
- while ( 1 )
+ // if there is a hierarchy, connect the boxes
+ if ( pNtkMaster && pNtkMaster->tName2Model )
{
- // get the new tokens
- vTokens = Extra_FileReaderGetTokens(p->pReader);
- if ( vTokens->nSize == 0 )
- return p->vNewTokens;
- // check if there is a transfer to another line
- pLastToken = vTokens->pArray[vTokens->nSize - 1];
- if ( pLastToken[ strlen(pLastToken)-1 ] == '\\' )
+ if ( Io_ReadBlifNetworkConnectBoxes( p, pNtkMaster ) )
{
- // remove the slash
- pLastToken[ strlen(pLastToken)-1 ] = 0;
- if ( pLastToken[0] == 0 )
- vTokens->nSize--;
- // load them into the new array
- for ( i = 0; i < vTokens->nSize; i++ )
- Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
- continue;
+ Abc_NtkDelete( pNtkMaster );
+ return NULL;
}
- // otherwise, load them and break
- for ( i = 0; i < vTokens->nSize; i++ )
- Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
- break;
}
- return p->vNewTokens;
+ else
+ Abc_NtkFinalizeRead( pNtkMaster );
+ // return the master network
+ return pNtkMaster;
}
-
/**Function*************************************************************
- Synopsis [Reads the BLIF file.]
+ Synopsis [Reads one (main or exdc) network from the BLIF file.]
Description []
@@ -272,74 +197,71 @@ Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p )
SeeAlso []
***********************************************************************/
-Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
+Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
{
ProgressBar * pProgress;
- Vec_Ptr_t * vTokens;
- char * pModelName, * pDirective;
+ Abc_Ntk_t * pNtk;
+ char * pDirective;
int iLine, fTokensReady, fStatus;
+ // make sure the tokens are present
+ assert( p->vTokens != NULL );
+
+ // create the new network
+ p->pNtkCur = pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP );
// read the model name
- if ( !p->fParsingExdc )
- {
- // read the model name
- vTokens = Io_ReadBlifGetTokens(p);
- if ( vTokens == NULL || strcmp( vTokens->pArray[0], ".model" ) )
- {
- p->LineCur = 0;
- sprintf( p->sError, "Wrong input file format." );
- Io_ReadBlifPrintErrorMessage( p );
- return NULL;
- }
- pModelName = vTokens->pArray[1];
- // allocate the empty network
- p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP );
- p->pNtk->pName = Extra_UtilStrsav( pModelName );
- p->pNtk->pSpec = Extra_UtilStrsav( p->pFileName );
- }
- else
- p->pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP );
+ if ( strcmp( p->vTokens->pArray[0], ".model" ) == 0 )
+ pNtk->pName = Extra_UtilStrsav( p->vTokens->pArray[1] );
// read the inputs/outputs
pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
fTokensReady = fStatus = 0;
- for ( iLine = 0; fTokensReady || (vTokens = Io_ReadBlifGetTokens(p)); iLine++ )
+ for ( iLine = 0; fTokensReady || (p->vTokens = Io_ReadBlifGetTokens(p)); iLine++ )
{
if ( iLine % 1000 == 0 )
Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL );
// consider different line types
fTokensReady = 0;
- pDirective = vTokens->pArray[0];
+ pDirective = p->vTokens->pArray[0];
if ( !strcmp( pDirective, ".names" ) )
- { fStatus = Io_ReadBlifNetworkNames( p, &vTokens ); fTokensReady = 1; }
+ { fStatus = Io_ReadBlifNetworkNames( p, &p->vTokens ); fTokensReady = 1; }
else if ( !strcmp( pDirective, ".gate" ) )
- fStatus = Io_ReadBlifNetworkGate( p, vTokens );
+ fStatus = Io_ReadBlifNetworkGate( p, p->vTokens );
else if ( !strcmp( pDirective, ".latch" ) )
- fStatus = Io_ReadBlifNetworkLatch( p, vTokens );
+ fStatus = Io_ReadBlifNetworkLatch( p, p->vTokens );
else if ( !strcmp( pDirective, ".inputs" ) )
- fStatus = Io_ReadBlifNetworkInputs( p, vTokens );
+ fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens );
else if ( !strcmp( pDirective, ".outputs" ) )
- fStatus = Io_ReadBlifNetworkOutputs( p, vTokens );
+ fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens );
else if ( !strcmp( pDirective, ".input_arrival" ) )
- fStatus = Io_ReadBlifNetworkInputArrival( p, vTokens );
+ fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens );
else if ( !strcmp( pDirective, ".default_input_arrival" ) )
- fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, vTokens );
+ fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens );
+ else if ( !strcmp( pDirective, ".subckt" ) )
+ fStatus = Io_ReadBlifNetworkSubcircuit( p, p->vTokens );
else if ( !strcmp( pDirective, ".exdc" ) )
- { p->fParsingExdc = 1; break; }
+ break;
else if ( !strcmp( pDirective, ".end" ) )
+ {
+ p->vTokens = Io_ReadBlifGetTokens(p);
break;
+ }
+ else if ( !strcmp( pDirective, ".blackbox" ) )
+ {
+ pNtk->ntkType = ABC_NTK_BLACKBOX;
+ pNtk->ntkFunc = ABC_FUNC_BLACKBOX;
+ }
else
printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName,
Extra_FileReaderGetLineNumber(p->pReader, 0), pDirective );
- if ( vTokens == NULL ) // some files do not have ".end" in the end
+ if ( p->vTokens == NULL ) // some files do not have ".end" in the end
break;
if ( fStatus == 1 )
return NULL;
}
Extra_ProgressBarStop( pProgress );
- Abc_NtkFinalizeRead( p->pNtk );
- return p->pNtk;
+ return pNtk;
}
/**Function*************************************************************
@@ -357,7 +279,7 @@ int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
int i;
for ( i = 1; i < vTokens->nSize; i++ )
- Io_ReadCreatePi( p->pNtk, vTokens->pArray[i] );
+ Io_ReadCreatePi( p->pNtkCur, vTokens->pArray[i] );
return 0;
}
@@ -376,7 +298,7 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
int i;
for ( i = 1; i < vTokens->nSize; i++ )
- Io_ReadCreatePo( p->pNtk, vTokens->pArray[i] );
+ Io_ReadCreatePo( p->pNtkCur, vTokens->pArray[i] );
return 0;
}
@@ -393,7 +315,7 @@ int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
***********************************************************************/
int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
- Abc_Ntk_t * pNtk = p->pNtk;
+ Abc_Ntk_t * pNtk = p->pNtkCur;
Abc_Obj_t * pLatch;
int ResetValue;
if ( vTokens->nSize < 3 )
@@ -442,7 +364,7 @@ int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
{
Vec_Ptr_t * vTokens = *pvTokens;
- Abc_Ntk_t * pNtk = p->pNtk;
+ Abc_Ntk_t * pNtk = p->pNtkCur;
Abc_Obj_t * pNode;
char * pToken, Char, ** ppNames;
int nFanins, nNames;
@@ -584,12 +506,12 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
}
// if this is the first line with gate, update the network type
- if ( Abc_NtkNodeNum(p->pNtk) == 0 )
+ if ( Abc_NtkNodeNum(p->pNtkCur) == 0 )
{
- assert( p->pNtk->ntkFunc == ABC_FUNC_SOP );
- p->pNtk->ntkFunc = ABC_FUNC_MAP;
- Extra_MmFlexStop( p->pNtk->pManFunc, 0 );
- p->pNtk->pManFunc = pGenlib;
+ assert( p->pNtkCur->ntkFunc == ABC_FUNC_SOP );
+ p->pNtkCur->ntkFunc = ABC_FUNC_MAP;
+ Extra_MmFlexStop( p->pNtkCur->pManFunc, 0 );
+ p->pNtkCur->pManFunc = pGenlib;
}
// remove the formal parameter names
@@ -608,13 +530,53 @@ int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
// create the node
ppNames = (char **)vTokens->pArray + 2;
nNames = vTokens->nSize - 3;
- pNode = Io_ReadCreateNode( p->pNtk, ppNames[nNames], ppNames, nNames );
+ pNode = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames], ppNames, nNames );
// set the pointer to the functionality of the node
Abc_ObjSetData( pNode, pGate );
return 0;
}
+/**Function*************************************************************
+
+ Synopsis [Creates a multi-input multi-output box in the hierarchical design.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
+{
+ Abc_Obj_t * pBox;
+ Vec_Ptr_t * vNames;
+ char * pName;
+ int i;
+
+ // create a new node and add it to the network
+ if ( vTokens->nSize < 3 )
+ {
+ p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
+ sprintf( p->sError, "The .subcircuit line has less than three tokens." );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+
+ // store the names of formal/actual inputs/outputs of the box
+ vNames = Vec_PtrAlloc( 10 );
+ Vec_PtrForEachEntryStart( vTokens, pName, i, 1 )
+ Vec_PtrPush( vNames, Abc_NtkRegisterName(p->pNtkCur, pName) );
+
+ // create a new box and add it to the network
+ pBox = Abc_NtkCreateBox( p->pNtkCur );
+ // set the pointer to the node names
+ Abc_ObjSetData( pBox, vNames );
+ // remember the line of the file
+ pBox->pCopy = (void *)Extra_FileReaderGetLineNumber(p->pReader, 0);
+ return 0;
+}
/**Function*************************************************************
@@ -663,7 +625,7 @@ int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
Io_ReadBlifPrintErrorMessage( p );
return 1;
}
- pNet = Abc_NtkFindNet( p->pNtk, vTokens->pArray[1] );
+ pNet = Abc_NtkFindNet( p->pNtkCur, vTokens->pArray[1] );
if ( pNet == NULL )
{
p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
@@ -681,7 +643,7 @@ int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
return 1;
}
// set the arrival time
- Abc_NtkTimeSetArrival( p->pNtk, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall );
+ Abc_NtkTimeSetArrival( p->pNtkCur, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall );
return 0;
}
@@ -720,10 +682,354 @@ int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vToken
return 1;
}
// set the arrival time
- Abc_NtkTimeSetDefaultArrival( p->pNtk, (float)TimeRise, (float)TimeFall );
+ Abc_NtkTimeSetDefaultArrival( p->pNtkCur, (float)TimeRise, (float)TimeFall );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the error message including the file name and line number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p )
+{
+ if ( p->LineCur == 0 ) // the line number is not given
+ fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError );
+ else // print the error message with the line number
+ fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Gets the tokens taking into account the line breaks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p )
+{
+ Vec_Ptr_t * vTokens;
+ char * pLastToken;
+ int i;
+
+ // get rid of the old tokens
+ if ( p->vNewTokens->nSize > 0 )
+ {
+ for ( i = 0; i < p->vNewTokens->nSize; i++ )
+ free( p->vNewTokens->pArray[i] );
+ p->vNewTokens->nSize = 0;
+ }
+
+ // get the new tokens
+ vTokens = Extra_FileReaderGetTokens(p->pReader);
+ if ( vTokens == NULL )
+ return vTokens;
+
+ // check if there is a transfer to another line
+ pLastToken = vTokens->pArray[vTokens->nSize - 1];
+ if ( pLastToken[ strlen(pLastToken)-1 ] != '\\' )
+ return vTokens;
+
+ // remove the slash
+ pLastToken[ strlen(pLastToken)-1 ] = 0;
+ if ( pLastToken[0] == 0 )
+ vTokens->nSize--;
+ // load them into the new array
+ for ( i = 0; i < vTokens->nSize; i++ )
+ Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
+
+ // load as long as there is the line break
+ while ( 1 )
+ {
+ // get the new tokens
+ vTokens = Extra_FileReaderGetTokens(p->pReader);
+ if ( vTokens->nSize == 0 )
+ return p->vNewTokens;
+ // check if there is a transfer to another line
+ pLastToken = vTokens->pArray[vTokens->nSize - 1];
+ if ( pLastToken[ strlen(pLastToken)-1 ] == '\\' )
+ {
+ // remove the slash
+ pLastToken[ strlen(pLastToken)-1 ] = 0;
+ if ( pLastToken[0] == 0 )
+ vTokens->nSize--;
+ // load them into the new array
+ for ( i = 0; i < vTokens->nSize; i++ )
+ Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
+ continue;
+ }
+ // otherwise, load them and break
+ for ( i = 0; i < vTokens->nSize; i++ )
+ Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav(vTokens->pArray[i]) );
+ break;
+ }
+ return p->vNewTokens;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts the reading data structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName )
+{
+ Extra_FileReader_t * pReader;
+ Io_ReadBlif_t * p;
+
+ // start the reader
+ pReader = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t" );
+
+ if ( pReader == NULL )
+ return NULL;
+
+ // start the reading data structure
+ p = ALLOC( Io_ReadBlif_t, 1 );
+ memset( p, 0, sizeof(Io_ReadBlif_t) );
+ p->pFileName = pFileName;
+ p->pReader = pReader;
+ p->Output = stdout;
+ p->vNewTokens = Vec_PtrAlloc( 100 );
+ p->vCubes = Vec_StrAlloc( 100 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the data structure.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadBlifFree( Io_ReadBlif_t * p )
+{
+ Extra_FileReaderFree( p->pReader );
+ Vec_PtrFree( p->vNewTokens );
+ Vec_StrFree( p->vCubes );
+ free( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Connect one box.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, stmm_table * tName2Model )
+{
+ Vec_Ptr_t * pNames;
+ Abc_Ntk_t * pNtkModel;
+ Abc_Obj_t * pObj, * pNet;
+ char * pName, * pActual;
+ int i, Length, Start;
+
+ // get the model for this box
+ pNames = pBox->pData;
+ if ( !stmm_lookup( tName2Model, Vec_PtrEntry(pNames, 0), (char **)&pNtkModel ) )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot find the model for subcircuit %s.", Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+
+ // create the fanins of the box
+ Abc_NtkForEachPi( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+ Vec_PtrForEachEntryStart( pNames, pName, i, 1 )
+ {
+ pActual = Io_ReadBlifCleanName(pName);
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ Length = pActual - pName - 1;
+ pName[Length] = 0;
+ // find the PI net with this name
+ pObj = Abc_NtkFindNet( pNtkModel, pName );
+ if ( pObj == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // get the PI
+ pObj = Abc_ObjFanin0(pObj);
+ // quit if this is not a PI net
+ if ( !Abc_ObjIsPi(pObj) )
+ {
+ pName[Length] = '=';
+ Start = i;
+ break;
+ }
+ // remember the actual name in the net
+ if ( pObj->pCopy != NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pObj->pCopy = (void *)pActual;
+ // quit if we processed all PIs
+ if ( i == Abc_NtkPiNum(pNtkModel) )
+ {
+ Start = i+1;
+ break;
+ }
+ }
+ // create the fanins of the box
+ Abc_NtkForEachPi( pNtkModel, pObj, i )
+ {
+ pActual = (void *)pObj->pCopy;
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal input \"%s\" of model %s is not driven.", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual );
+ Abc_ObjAddFanin( pBox, pNet );
+ }
+ Abc_NtkForEachPi( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+
+ // create the fanouts of the box
+ Abc_NtkForEachPo( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+ Vec_PtrForEachEntryStart( pNames, pName, i, Start )
+ {
+ pActual = Io_ReadBlifCleanName(pName);
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ Length = pActual - pName - 1;
+ pName[Length] = 0;
+ // find the PO net with this name
+ pObj = Abc_NtkFindNet( pNtkModel, pName );
+ if ( pObj == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Cannot find formal output \"%s\" as an PO of model \"%s\".", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ // get the PO
+ pObj = Abc_ObjFanout0(pObj);
+ if ( pObj->pCopy != NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal output \"%s\" is used more than once.", pName );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pObj->pCopy = (void *)pActual;
+ }
+ // create the fanouts of the box
+ Abc_NtkForEachPo( pNtkModel, pObj, i )
+ {
+ pActual = (void *)pObj->pCopy;
+ if ( pActual == NULL )
+ {
+ p->LineCur = (int)pBox->pCopy;
+ sprintf( p->sError, "Formal output \"%s\" of model %s is not driven.", pName, Vec_PtrEntry(pNames, 0) );
+ Io_ReadBlifPrintErrorMessage( p );
+ return 1;
+ }
+ pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual );
+ Abc_ObjAddFanin( pNet, pBox );
+ }
+ Abc_NtkForEachPo( pNtkModel, pObj, i )
+ pObj->pCopy = NULL;
+
+ // remove the array of names, assign the pointer to the model
+ Vec_PtrFree( pBox->pData );
+ pBox->pData = pNtkModel;
return 0;
}
+/**Function*************************************************************
+
+ Synopsis [Connect the boxes in the hierarchy of networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkConnectBoxesOne( Io_ReadBlif_t * p, Abc_Ntk_t * pNtk, stmm_table * tName2Model )
+{
+ Abc_Obj_t * pBox;
+ int i;
+ // go through the boxes
+ Abc_NtkForEachBox( pNtk, pBox, i )
+ if ( Io_ReadBlifNetworkConnectBoxesOneBox( p, pBox, tName2Model ) )
+ return 1;
+ Abc_NtkFinalizeRead( pNtk );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Connect the boxes in the hierarchy of networks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster )
+{
+ stmm_generator * gen;
+ Abc_Ntk_t * pNtk;
+ char * pName;
+ // connect the master network
+ if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtkMaster, pNtkMaster->tName2Model ) )
+ return 1;
+ // connect other networks
+ stmm_foreach_item( pNtkMaster->tName2Model, gen, &pName, (char **)&pNtk )
+ if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtk, pNtkMaster->tName2Model ) )
+ return 1;
+ return 0;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c
index 1b515a1e..1e27498d 100644
--- a/src/base/io/ioWriteBlif.c
+++ b/src/base/io/ioWriteBlif.c
@@ -26,6 +26,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+static void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWritePis( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
static void Io_NtkWritePos( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches );
@@ -59,7 +60,7 @@ void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
fprintf( stdout, "Writing BLIF has failed.\n" );
return;
}
- Io_WriteBlif( pNtkTemp, FileName, fWriteLatches );
+ Io_WriteBlifNetlist( pNtkTemp, FileName, fWriteLatches );
Abc_NtkDelete( pNtkTemp );
}
@@ -74,19 +75,48 @@ void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
SeeAlso []
***********************************************************************/
-void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
+void Io_WriteBlifNetlist( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
{
- Abc_Ntk_t * pExdc;
+ stmm_generator * gen;
+ Abc_Ntk_t * pNtkTemp;
FILE * pFile;
assert( Abc_NtkIsNetlist(pNtk) );
+ // start writing the file
pFile = fopen( FileName, "w" );
if ( pFile == NULL )
{
- fprintf( stdout, "Io_WriteBlif(): Cannot open the output file.\n" );
+ fprintf( stdout, "Io_WriteBlifNetlist(): Cannot open the output file.\n" );
return;
}
- // write the model name
fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() );
+ // write the master network
+ Io_NtkWrite( pFile, pNtk, fWriteLatches );
+ // write the hierarchy if present
+ if ( pNtk->tName2Model )
+ {
+ fprintf( pFile, "\n\n" );
+ stmm_foreach_item( pNtk->tName2Model, gen, NULL, (char **)&pNtkTemp )
+ Io_NtkWrite( pFile, pNtkTemp, fWriteLatches );
+ }
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Write the network into a BLIF file with the given name.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_NtkWrite( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
+{
+ Abc_Ntk_t * pExdc;
+ assert( Abc_NtkIsNetlist(pNtk) || Abc_NtkIsBlackbox(pNtk) );
+ // write the model name
fprintf( pFile, ".model %s\n", Abc_NtkName(pNtk) );
// write the network
Io_NtkWriteOne( pFile, pNtk, fWriteLatches );
@@ -100,7 +130,6 @@ void Io_WriteBlif( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches )
}
// finalize the file
fprintf( pFile, ".end\n" );
- fclose( pFile );
}
/**Function*************************************************************
@@ -130,6 +159,13 @@ void Io_NtkWriteOne( FILE * pFile, Abc_Ntk_t * pNtk, int fWriteLatches )
Io_NtkWritePos( pFile, pNtk, fWriteLatches );
fprintf( pFile, "\n" );
+ // write the blackbox
+ if ( Abc_NtkIsBlackbox( pNtk ) )
+ {
+ fprintf( pFile, ".blackbox\n" );
+ return;
+ }
+
// write the timing info
Io_WriteTimingInfo( pFile, pNtk );