diff options
| author | Alan Mishchenko <alanmi@berkeley.edu> | 2006-04-12 08:01:00 -0700 | 
|---|---|---|
| committer | Alan Mishchenko <alanmi@berkeley.edu> | 2006-04-12 08:01:00 -0700 | 
| commit | c1710767b298a8acae16421a660a0874255636a5 (patch) | |
| tree | 308ec887b66bcd608a1d7f448d45c27b3b2e93fb /src | |
| parent | 3f4fc5e4507f7fb9df431fc116529b4c209ab97c (diff) | |
| download | abc-c1710767b298a8acae16421a660a0874255636a5.tar.gz abc-c1710767b298a8acae16421a660a0874255636a5.tar.bz2 abc-c1710767b298a8acae16421a660a0874255636a5.zip | |
Version abc60412
Diffstat (limited to 'src')
| -rw-r--r-- | src/base/abc/abc.h | 21 | ||||
| -rw-r--r-- | src/base/abc/abcCheck.c | 85 | ||||
| -rw-r--r-- | src/base/abc/abcDfs.c | 8 | ||||
| -rw-r--r-- | src/base/abc/abcNetlist.c | 158 | ||||
| -rw-r--r-- | src/base/abc/abcNtk.c | 23 | ||||
| -rw-r--r-- | src/base/abc/abcObj.c | 23 | ||||
| -rw-r--r-- | src/base/abc/abcUtil.c | 20 | ||||
| -rw-r--r-- | src/base/abci/abc.c | 100 | ||||
| -rw-r--r-- | src/base/abci/abcMiter.c | 55 | ||||
| -rw-r--r-- | src/base/abci/abcPrint.c | 9 | ||||
| -rw-r--r-- | src/base/abci/abcStrash.c | 68 | ||||
| -rw-r--r-- | src/base/cmd/cmd.c | 6 | ||||
| -rw-r--r-- | src/base/io/io.c | 2 | ||||
| -rw-r--r-- | src/base/io/io.h | 2 | ||||
| -rw-r--r-- | src/base/io/ioReadBlif.c | 686 | ||||
| -rw-r--r-- | src/base/io/ioWriteBlif.c | 48 | 
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 ); | 
