Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int fPhase )
{
    Abc_Obj_t * pNodeNew, * pNodeInv;

    // check the case of constant node
    if ( Map_NodeIsConst(pNodeMap) )
    {
        pNodeNew = fPhase? Abc_NtkCreateNodeConst1(pNtkNew) : Abc_NtkCreateNodeConst0(pNtkNew);
        if ( pNodeNew->pData == NULL )
            printf( "Error creating mapped network: Library does not have a constant %d gate.\n", fPhase );
        return pNodeNew;
    }

    // check if the phase is already implemented
    pNodeNew = (Abc_Obj_t *)Map_NodeReadData( pNodeMap, fPhase );
    if ( pNodeNew )
        return pNodeNew;

    // implement the node if the best cut is assigned
    if ( Map_NodeReadCutBest(pNodeMap, fPhase) != NULL )
        return Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, fPhase );

    // if the cut is not assigned, implement the node
    assert( Map_NodeReadCutBest(pNodeMap, !fPhase) != NULL || Map_NodeIsConst(pNodeMap) );
    pNodeNew = Abc_NodeFromMapPhase_rec( pNtkNew, pNodeMap, !fPhase );

    // add the inverter
    pNodeInv = Abc_NtkCreateNode( pNtkNew );
    Abc_ObjAddFanin( pNodeInv, pNodeNew );
    pNodeInv->pData = Mio_LibraryReadInv((Mio_Library_t *)Abc_FrameReadLibGen());

    // set the inverter
    Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeInv );
    return pNodeInv;
}
Example #2
0
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Str_t * vSop, int fVerbose )
{
    Wlc_Obj_t * pObj;
    int i, k, nNum, nRange, nBits = 0;
    Abc_Ntk_t * pMainNtk = NULL;
    Abc_Obj_t * pMainObj, * pMainTemp;
    char Buffer[5000];
    // start the network
    pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
    // duplicate the name and the spec
    pMainNtk->pName = Extra_UtilStrsav(pNtk->pName);
    // create primary inputs
    Wlc_NtkForEachCi( pNtk, pObj, i )
    {
        if ( pObj->Type != WLC_OBJ_FO )
            continue;
        nRange = Wlc_ObjRange(pObj);
        for ( k = 0; k < nRange; k++ )
        {
            nNum = Vec_IntEntry(vInv, nBits + k);
            if ( nNum )
                break;
        }
        if ( k == nRange )
        {
            nBits += nRange;
            continue;
        }
        //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
        for ( k = 0; k < nRange; k++ )
        {
            nNum = Vec_IntEntry( vInv, nBits + k );
            if ( nNum == 0 )
                continue;
            //printf( "  [%d] -> %d", k, nNum );
            pMainObj = Abc_NtkCreatePi( pMainNtk );
            sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k );
            Abc_ObjAssignName( pMainObj, Buffer, NULL );

        }
        //printf( "\n");
        nBits += nRange;
    }
    //printf( "%d %d\n", Vec_IntSize(vInv), nBits );
    assert( Vec_IntSize(vInv) == nBits );
    // create node
    pMainObj = Abc_NtkCreateNode( pMainNtk );
    Abc_NtkForEachPi( pMainNtk, pMainTemp, i )
        Abc_ObjAddFanin( pMainObj, pMainTemp );
    pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) );
    // create PO
    pMainTemp = Abc_NtkCreatePo( pMainNtk );
    Abc_ObjAddFanin( pMainTemp, pMainObj );
    Abc_ObjAssignName( pMainTemp, "inv", NULL );
    return pMainNtk;
}
Example #3
0
/**Function*************************************************************

  Synopsis    [Constructs the network isomorphic to the given BDD.]

  Description [Assumes that the BDD depends on the variables whose indexes
  correspond to the names in the array (pNamesPi). Otherwise, returns NULL.
  The resulting network comes with one node, whose functionality is
  equal to the given BDD. To decompose this BDD into the network of
  multiplexers use Abc_NtkBddToMuxes(). To decompose this BDD into
  an And-Inverter Graph, use Abc_NtkStrash().]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd0, void * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi )
{
    DdManager * dd = (DdManager *)dd0;
    Abc_Ntk_t * pNtk; 
    Vec_Ptr_t * vNamesPiFake = NULL;
    Abc_Obj_t * pNode, * pNodePi, * pNodePo;
    DdNode * bSupp, * bTemp;
    char * pName;
    int i;

    // supply fake names if real names are not given
    if ( pNamePo == NULL )
        pNamePo = "F";
    if ( vNamesPi == NULL )
    {
        vNamesPiFake = Abc_NodeGetFakeNames( dd->size );
        vNamesPi = vNamesPiFake;
    }

    // make sure BDD depends on the variables whose index 
    // does not exceed the size of the array with PI names
    bSupp = Cudd_Support( dd, (DdNode *)bFunc );   Cudd_Ref( bSupp );
    for ( bTemp = bSupp; bTemp != Cudd_ReadOne(dd); bTemp = cuddT(bTemp) )
        if ( (int)Cudd_NodeReadIndex(bTemp) >= Vec_PtrSize(vNamesPi) )
            break;
    Cudd_RecursiveDeref( dd, bSupp );
    if ( bTemp != Cudd_ReadOne(dd) )
        return NULL;

    // start the network
    pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_BDD, 1 );
    pNtk->pName = Extra_UtilStrsav(pNamePo);
    // make sure the new manager has enough inputs
    Cudd_bddIthVar( (DdManager *)pNtk->pManFunc, Vec_PtrSize(vNamesPi) );
    // add the PIs corresponding to the names
    Vec_PtrForEachEntry( char *, vNamesPi, pName, i )
        Abc_ObjAssignName( Abc_NtkCreatePi(pNtk), pName, NULL );
    // create the node
    pNode = Abc_NtkCreateNode( pNtk );
    pNode->pData = (DdNode *)Cudd_bddTransfer( dd, (DdManager *)pNtk->pManFunc, (DdNode *)bFunc ); Cudd_Ref((DdNode *)pNode->pData);
    Abc_NtkForEachPi( pNtk, pNodePi, i )
        Abc_ObjAddFanin( pNode, pNodePi );
    // create the only PO
    pNodePo = Abc_NtkCreatePo( pNtk );
    Abc_ObjAddFanin( pNodePo, pNode );
    Abc_ObjAssignName( pNodePo, pNamePo, NULL );
    // make the network minimum base
    Abc_NtkMinimumBase( pNtk );
    if ( vNamesPiFake )
        Abc_NodeFreeNames( vNamesPiFake );
    if ( !Abc_NtkCheck( pNtk ) )
        fprintf( stdout, "Abc_NtkDeriveFromBdd(): Network check has failed.\n" );
    return pNtk;
}
Example #4
0
ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [Implements the function.]

  Description [Returns the node implementing this function.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Obj_t * Lpk_ImplementFun( Lpk_Man_t * pMan, Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Lpk_Fun_t * p )
{
    extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
    unsigned * pTruth;
    Abc_Obj_t * pObjNew;
    int i;
    if ( p->fMark )
        pMan->nMuxes++;
    else
        pMan->nDsds++;
    // create the new node
    pObjNew = Abc_NtkCreateNode( pNtk );
    for ( i = 0; i < (int)p->nVars; i++ )
        Abc_ObjAddFanin( pObjNew, Abc_ObjRegular((Abc_Obj_t *)Vec_PtrEntry(vLeaves, p->pFanins[i])) );
    Abc_ObjSetLevel( pObjNew, Abc_ObjLevelNew(pObjNew) );
    // assign the node's function
    pTruth = Lpk_FunTruth(p, 0);
    if ( p->nVars == 0 )
    {
        pObjNew->pData = Hop_NotCond( Hop_ManConst1((Hop_Man_t *)pNtk->pManFunc), !(pTruth[0] & 1) );
        return pObjNew;
    }
    if ( p->nVars == 1 )
    {
        pObjNew->pData = Hop_NotCond( Hop_ManPi((Hop_Man_t *)pNtk->pManFunc, 0), (pTruth[0] & 1) );
        return pObjNew;
    }
    // create the logic function
    pObjNew->pData = Kit_TruthToHop( (Hop_Man_t *)pNtk->pManFunc, pTruth, p->nVars, NULL );
    return pObjNew;
}
Example #5
0
/**Function*************************************************************

  Synopsis    [Create node and the net driven by it.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Obj_t * Io_ReadCreateNode( Abc_Ntk_t * pNtk, char * pNameOut, char * pNamesIn[], int nInputs )
{
    Abc_Obj_t * pNet, * pNode;
    int i;
    // create a new node 
    pNode = Abc_NtkCreateNode( pNtk );
    // add the fanin nets
    for ( i = 0; i < nInputs; i++ )
    {
        pNet = Abc_NtkFindOrCreateNet( pNtk, pNamesIn[i] );
        Abc_ObjAddFanin( pNode, pNet );
    }
    // add the fanout net
    pNet = Abc_NtkFindOrCreateNet( pNtk, pNameOut );
    Abc_ObjAddFanin( pNet, pNode );
    return pNode;
}
/**Function*************************************************************

  Synopsis    [Creates the mapped network.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Obj_t * Abc_NodeFromMapSuper_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, Map_Super_t * pSuper, Abc_Obj_t * pNodePis[], int nNodePis )
{
    Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
    Mio_Gate_t * pRoot;
    Map_Super_t ** ppFanins;
    Abc_Obj_t * pNodeNew, * pNodeFanin;
    int nFanins, Number, i;

    // get the parameters of the supergate
    pRoot = Map_SuperReadRoot(pSuper);
    if ( pRoot == NULL )
    {
        Number = Map_SuperReadNum(pSuper);
        if ( Number < nNodePis )  
        {
            return pNodePis[Number];
        }
        else
        {  
//            assert( 0 );
            /* It might happen that a super gate with 5 inputs is constructed that
             * actually depends only on the first four variables; i.e the fifth is a
             * don't care -- in that case we connect constant node for the fifth
             * (since the cut only has 4 variables). An interesting question is what
             * if the first variable (and not the fifth one is the redundant one;
             * can that happen?) */
            return Abc_NtkCreateNodeConst0(pNtkNew);
        }
    }
    pRoot = Mio_LibraryReadGateByName( pLib, Mio_GateReadName(pRoot), NULL );

    // get information about the fanins of the supergate
    nFanins  = Map_SuperReadFaninNum( pSuper );
    ppFanins = Map_SuperReadFanins( pSuper );
    // create a new node with these fanins
    pNodeNew = Abc_NtkCreateNode( pNtkNew );
    for ( i = 0; i < nFanins; i++ )
    {
        pNodeFanin = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, ppFanins[i], pNodePis, nNodePis );
        Abc_ObjAddFanin( pNodeNew, pNodeFanin );
    }
    pNodeNew->pData = pRoot;
    return pNodeNew;
}
/**Function*************************************************************

  Synopsis    [Transforms the node to take fanout sharing into account.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Seq_NodeShareOne( Abc_Obj_t * pNode, Abc_InitType_t Init, Vec_Ptr_t * vNodes )
{
    Vec_Int_t * vNums  = Seq_ObjLNums( pNode );
    Vec_Ptr_t * vInits = Seq_NodeLats( pNode );
    Abc_Obj_t * pFanout, * pBuffer;
    Abc_InitType_t Type, InitNew;
    int i;
    // collect the fanouts that satisfy the property (have initial value Init or DC)
    InitNew = ABC_INIT_DC;
    Vec_PtrClear( vNodes );
    Abc_ObjForEachFanout( pNode, pFanout, i )
    {
        if ( Seq_ObjFanoutL(pNode, pFanout) == 0 )
            continue;
        Type = Seq_NodeGetInitLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) );
        if ( Type == Init )
            InitNew = Init;
        if ( Type == Init || Type == ABC_INIT_DC )
        {
            Vec_PtrPush( vNodes, pFanout );
            Seq_NodeDeleteLast( pFanout, Abc_ObjFanoutEdgeNum(pNode, pFanout) );
        }
    }
    // create the new buffer
    pBuffer = Abc_NtkCreateNode( pNode->pNtk );
    Abc_ObjAddFanin( pBuffer, pNode );

    // grow storage for initial states
    Vec_PtrGrow( vInits, 2 * pBuffer->Id + 2 );
    for ( i = Vec_PtrSize(vInits); i < 2 * (int)pBuffer->Id + 2; i++ )
        Vec_PtrPush( vInits, NULL );
    // grow storage for numbers of latches
    Vec_IntGrow( vNums, 2 * pBuffer->Id + 2 );
    for ( i = Vec_IntSize(vNums); i < 2 * (int)pBuffer->Id + 2; i++ )
        Vec_IntPush( vNums, 0 );
    // insert the new latch
    Seq_NodeInsertFirst( pBuffer, 0, InitNew );

    // redirect the fanouts
    Vec_PtrForEachEntry( vNodes, pFanout, i )
        Abc_ObjPatchFanin( pFanout, pNode, pBuffer );
}
/**Function*************************************************************

  Synopsis    [Transforms the AIG into nodes.]

  Description [Threhold is the max number of nodes duplicated at a node.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_NtkMultiInt( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
{
    ProgressBar * pProgress;
    Abc_Obj_t * pNode, * pConst1, * pNodeNew;
    int i;

    // set the constant node
    pConst1 = Abc_AigConst1(pNtk);
    if ( Abc_ObjFanoutNum(pConst1) > 0 )
    {
        pNodeNew = Abc_NtkCreateNode( pNtkNew );  
        pNodeNew->pData = Cudd_ReadOne( pNtkNew->pManFunc );   Cudd_Ref( pNodeNew->pData );
        pConst1->pCopy = pNodeNew;
    }

    // perform renoding for POs
    pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCoNum(pNtk) );
    Abc_NtkForEachCo( pNtk, pNode, i )
    {
        Extra_ProgressBarUpdate( pProgress, i, NULL );
        if ( Abc_ObjIsCi(Abc_ObjFanin0(pNode)) )
            continue;
        Abc_NtkMulti_rec( pNtkNew, Abc_ObjFanin0(pNode) );
    }
Example #9
0
/**Function*************************************************************

  Synopsis    [Adds a gate to the circuit.]

  Description [The meaning of the parameters are:
    type: the type of the gate to be added
    name: the name of the gate to be added, name should be unique in a circuit.
    nofi: number of fanins of the gate to be added;
    fanins: the name array of fanins of the gate to be added.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int ABC_AddGate( ABC_Manager mng, enum GateType type, char * name, int nofi, char ** fanins, int dc_attr )
{
    Abc_Obj_t * pObj = NULL; // Suppress "might be used uninitialized"
    Abc_Obj_t * pFanin;
    char * pSop = NULL; // Suppress "might be used uninitialized"
    char * pNewName;
    int i;

    // save the name in the local memory manager
    pNewName = Mem_FlexEntryFetch( mng->pMmNames, strlen(name) + 1 );
    strcpy( pNewName, name );
    name = pNewName;

    // consider different cases, create the node, and map the node into the name
    switch( type )
    {
    case CSAT_BPI:
    case CSAT_BPPI:
        if ( nofi != 0 )
            { printf( "ABC_AddGate: The PI/PPI gate \"%s\" has fanins.\n", name ); return 0; }
        // create the PI
        pObj = Abc_NtkCreatePi( mng->pNtk );
        stmm_insert( mng->tNode2Name, (char *)pObj, name );
        break;
    case CSAT_CONST:
    case CSAT_BAND:
    case CSAT_BNAND:
    case CSAT_BOR:
    case CSAT_BNOR:
    case CSAT_BXOR:
    case CSAT_BXNOR:
    case CSAT_BINV:
    case CSAT_BBUF:
        // create the node
        pObj = Abc_NtkCreateNode( mng->pNtk );
        // create the fanins
        for ( i = 0; i < nofi; i++ )
        {
            if ( !stmm_lookup( mng->tName2Node, fanins[i], (char **)&pFanin ) )
                { printf( "ABC_AddGate: The fanin gate \"%s\" is not in the network.\n", fanins[i] ); return 0; }
            Abc_ObjAddFanin( pObj, pFanin );
        }
        // create the node function
        switch( type )
        {
            case CSAT_CONST:
                if ( nofi != 0 )
                    { printf( "ABC_AddGate: The constant gate \"%s\" has fanins.\n", name ); return 0; }
                pSop = Abc_SopCreateConst1( (Mem_Flex_t *)mng->pNtk->pManFunc );
                break;
            case CSAT_BAND:
                if ( nofi < 1 )
                    { printf( "ABC_AddGate: The AND gate \"%s\" no fanins.\n", name ); return 0; }
                pSop = Abc_SopCreateAnd( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi, NULL );
                break;
            case CSAT_BNAND:
                if ( nofi < 1 )
                    { printf( "ABC_AddGate: The NAND gate \"%s\" no fanins.\n", name ); return 0; }
                pSop = Abc_SopCreateNand( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi );
                break;
            case CSAT_BOR:
                if ( nofi < 1 )
                    { printf( "ABC_AddGate: The OR gate \"%s\" no fanins.\n", name ); return 0; }
                pSop = Abc_SopCreateOr( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi, NULL );
                break;
            case CSAT_BNOR:
                if ( nofi < 1 )
                    { printf( "ABC_AddGate: The NOR gate \"%s\" no fanins.\n", name ); return 0; }
                pSop = Abc_SopCreateNor( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi );
                break;
            case CSAT_BXOR:
                if ( nofi < 1 )
                    { printf( "ABC_AddGate: The XOR gate \"%s\" no fanins.\n", name ); return 0; }
                if ( nofi > 2 )
                    { printf( "ABC_AddGate: The XOR gate \"%s\" has more than two fanins.\n", name ); return 0; }
                pSop = Abc_SopCreateXor( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi );
                break;
            case CSAT_BXNOR:
                if ( nofi < 1 )
                    { printf( "ABC_AddGate: The XNOR gate \"%s\" no fanins.\n", name ); return 0; }
                if ( nofi > 2 )
                    { printf( "ABC_AddGate: The XNOR gate \"%s\" has more than two fanins.\n", name ); return 0; }
                pSop = Abc_SopCreateNxor( (Mem_Flex_t *)mng->pNtk->pManFunc, nofi );
                break;
            case CSAT_BINV:
                if ( nofi != 1 )
                    { printf( "ABC_AddGate: The inverter gate \"%s\" does not have exactly one fanin.\n", name ); return 0; }
                pSop = Abc_SopCreateInv( (Mem_Flex_t *)mng->pNtk->pManFunc );
                break;
            case CSAT_BBUF:
                if ( nofi != 1 )
                    { printf( "ABC_AddGate: The buffer gate \"%s\" does not have exactly one fanin.\n", name ); return 0; }
                pSop = Abc_SopCreateBuf( (Mem_Flex_t *)mng->pNtk->pManFunc );
                break;
            default :
                break;
        }
        Abc_ObjSetData( pObj, pSop );
        break;
    case CSAT_BPPO:
    case CSAT_BPO:
        if ( nofi != 1 )
            { printf( "ABC_AddGate: The PO/PPO gate \"%s\" does not have exactly one fanin.\n", name ); return 0; }
        // create the PO
        pObj = Abc_NtkCreatePo( mng->pNtk );
        stmm_insert( mng->tNode2Name, (char *)pObj, name );
        // connect to the PO fanin
        if ( !stmm_lookup( mng->tName2Node, fanins[0], (char **)&pFanin ) )
            { printf( "ABC_AddGate: The fanin gate \"%s\" is not in the network.\n", fanins[0] ); return 0; }
        Abc_ObjAddFanin( pObj, pFanin );
        break;
    default:
        printf( "ABC_AddGate: Unknown gate type.\n" );
        break;
    }

    // map the name into the node
    if ( stmm_insert( mng->tName2Node, name, (char *)pObj ) )
        { printf( "ABC_AddGate: The same gate \"%s\" is added twice.\n", name ); return 0; }
    return 1;
}
        }
        // clean the label
        Abc_ObjForEachFanout( pObj, pFanout, i )
            pFanout->fMarkC = 0;
        // update the fanin edges
        Abc_ObjRetimeBackwardUpdateEdge( pObj, 0, tTable );
        Abc_ObjRetimeBackwardUpdateEdge( pObj, 1, tTable );
        Seq_NodeInsertFirst( pObj, 0, ABC_INIT_DC );
        Seq_NodeInsertFirst( pObj, 1, ABC_INIT_DC );
        return 0;
    }
    // the initial values on the fanout edges contain 0, 1, or unknown
    // the new values on the fanin edges will be unknown

    // add new AND-gate to the network
    pNodeNew = Abc_NtkCreateNode( pNtkNew );
    pNodeNew->pData = Abc_SopCreateAnd2( pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );

    // add PO fanouts if any
    if ( fMet0 )
    {
        Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew );
        Vec_IntPush( vValues, 0 );
    }
    if ( fMet1 )
    {
        Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNodeNew );
        Vec_IntPush( vValues, 1 );
    }

    // make sure the label is clean
Example #11
0
ABC_NAMESPACE_IMPL_START


// For description of Binary BLIF format, refer to "abc/src/aig/bbl/bblif.h"

////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Fnction*************************************************************

  Synopsis    [Constructs ABC network from the manager.]

  Description [The ABC network is started, as well as the array vCopy,
  which will map the new ID of each object in the BBLIF manager into
  the ponter ot the corresponding object in the ABC. For each internal
  node, determined by Bbl_ObjIsLut(), the SOP representation is created
  by retrieving the SOP representation of the BBLIF object. Finally,
  the objects are connected using fanin/fanout creation, and the dummy
  names are assigned because ABC requires each CI/CO to have a name.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Bbl_ManToAbc( Bbl_Man_t * p )
{
    Abc_Ntk_t * pNtk;
    Abc_Obj_t * pObjNew;
    Bbl_Obj_t * pObj, * pFanin;
    Vec_Ptr_t * vCopy;
    // start the network
    pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
    pNtk->pName = Extra_UtilStrsav( Bbl_ManName(p) );
    // create objects
    vCopy = Vec_PtrStart( 1000 );
    Bbl_ManForEachObj( p, pObj )
    {
        if ( Bbl_ObjIsInput(pObj) )
            pObjNew = Abc_NtkCreatePi( pNtk );
        else if ( Bbl_ObjIsOutput(pObj) )
            pObjNew = Abc_NtkCreatePo( pNtk );
        else if ( Bbl_ObjIsLut(pObj) )
            pObjNew = Abc_NtkCreateNode( pNtk );
        else assert( 0 );
        if ( Bbl_ObjIsLut(pObj) )
            pObjNew->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, Bbl_ObjSop(p, pObj) );
        Vec_PtrSetEntry( vCopy, Bbl_ObjId(pObj), pObjNew );
    }
    // connect objects
    Bbl_ManForEachObj( p, pObj )
        Bbl_ObjForEachFanin( pObj, pFanin )
            Abc_ObjAddFanin( (Abc_Obj_t *)Vec_PtrEntry(vCopy, Bbl_ObjId(pObj)), (Abc_Obj_t *)Vec_PtrEntry(vCopy, Bbl_ObjId(pFanin)) );
    // finalize
    Vec_PtrFree( vCopy );
    Abc_NtkAddDummyPiNames( pNtk );
    Abc_NtkAddDummyPoNames( pNtk );
    if ( !Abc_NtkCheck( pNtk ) )
        printf( "Bbl_ManToAbc(): Network check has failed.\n" );
    return pNtk;
}
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Io_ReadPlaNetwork( Extra_FileReader_t * p )
{
    ProgressBar * pProgress;
    Vec_Ptr_t * vTokens;
    Abc_Ntk_t * pNtk;
    Abc_Obj_t * pTermPi, * pTermPo, * pNode;
    Vec_Str_t ** ppSops;
    char Buffer[100];
    int nInputs = -1, nOutputs = -1, nProducts = -1;
    char * pCubeIn, * pCubeOut;
    int i, k, iLine, nDigits, nCubes;
 
    // allocate the empty network
    pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) );

    // go through the lines of the file
    nCubes = 0;
    pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p) );
    for ( iLine = 0; vTokens = Extra_FileReaderGetTokens(p); iLine++ )
    {
        Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p), NULL );

        // if it is the end of file, quit the loop
        if ( strcmp( vTokens->pArray[0], ".e" ) == 0 )
            break;

        if ( vTokens->nSize == 1 )
        {
            printf( "%s (line %d): Wrong number of token.\n", 
                Extra_FileReaderGetFileName(p), iLine+1 );
            Abc_NtkDelete( pNtk );
            return NULL;
        }

        if ( strcmp( vTokens->pArray[0], ".i" ) == 0 )
            nInputs = atoi(vTokens->pArray[1]);
        else if ( strcmp( vTokens->pArray[0], ".o" ) == 0 )
            nOutputs = atoi(vTokens->pArray[1]);
        else if ( strcmp( vTokens->pArray[0], ".p" ) == 0 )
            nProducts = atoi(vTokens->pArray[1]);
        else if ( strcmp( vTokens->pArray[0], ".ilb" ) == 0 )
        {
            if ( vTokens->nSize - 1 != nInputs )
                printf( "Warning: Mismatch between the number of PIs on the .i line (%d) and the number of PIs on the .ilb line (%d).\n", nInputs, vTokens->nSize - 1 );
            for ( i = 1; i < vTokens->nSize; i++ )
                Io_ReadCreatePi( pNtk, vTokens->pArray[i] );
        }
        else if ( strcmp( vTokens->pArray[0], ".ob" ) == 0 )
        {
            if ( vTokens->nSize - 1 != nOutputs )
                printf( "Warning: Mismatch between the number of POs on the .o line (%d) and the number of POs on the .ob line (%d).\n", nOutputs, vTokens->nSize - 1 );
            for ( i = 1; i < vTokens->nSize; i++ )
                Io_ReadCreatePo( pNtk, vTokens->pArray[i] );
        }
        else 
        {
            // check if the input/output names are given
            if ( Abc_NtkPiNum(pNtk) == 0 )
            {
                if ( nInputs == -1 )
                {
                    printf( "%s: The number of inputs is not specified.\n", Extra_FileReaderGetFileName(p) );
                    Abc_NtkDelete( pNtk );
                    return NULL;
                }
                nDigits = Extra_Base10Log( nInputs );
                for ( i = 0; i < nInputs; i++ )
                {
                    sprintf( Buffer, "x%0*d", nDigits, i );
                    Io_ReadCreatePi( pNtk, Buffer );
                }
            }
            if ( Abc_NtkPoNum(pNtk) == 0 )
            {
                if ( nOutputs == -1 )
                {
                    printf( "%s: The number of outputs is not specified.\n", Extra_FileReaderGetFileName(p) );
                    Abc_NtkDelete( pNtk );
                    return NULL;
                }
                nDigits = Extra_Base10Log( nOutputs );
                for ( i = 0; i < nOutputs; i++ )
                {
                    sprintf( Buffer, "z%0*d", nDigits, i );
                    Io_ReadCreatePo( pNtk, Buffer );
                }
            }
            if ( Abc_NtkNodeNum(pNtk) == 0 )
            { // first time here
                // create the PO drivers and add them
                // start the SOP covers
                ppSops = ALLOC( Vec_Str_t *, nOutputs );
                Abc_NtkForEachPo( pNtk, pTermPo, i )
                {
                    ppSops[i] = Vec_StrAlloc( 100 );
                    // create the node
                    pNode = Abc_NtkCreateNode(pNtk);
                    // connect the node to the PO net
                    Abc_ObjAddFanin( Abc_ObjFanin0Ntk(pTermPo), pNode );
                    // connect the node to the PI nets
                    Abc_NtkForEachPi( pNtk, pTermPi, k )
                        Abc_ObjAddFanin( pNode, Abc_ObjFanout0Ntk(pTermPi) );
                }
            }
            // read the cubes
            if ( vTokens->nSize != 2 )
            {
                printf( "%s (line %d): Input and output cubes are not specified.\n", 
                    Extra_FileReaderGetFileName(p), iLine+1 );
                Abc_NtkDelete( pNtk );
                return NULL;
            }
            pCubeIn  = vTokens->pArray[0];
            pCubeOut = vTokens->pArray[1];
            if ( strlen(pCubeIn) != (unsigned)nInputs )
            {
                printf( "%s (line %d): Input cube length (%d) differs from the number of inputs (%d).\n", 
                    Extra_FileReaderGetFileName(p), iLine+1, strlen(pCubeIn), nInputs );
                Abc_NtkDelete( pNtk );
                return NULL;
            }
            if ( strlen(pCubeOut) != (unsigned)nOutputs )
            {
                printf( "%s (line %d): Output cube length (%d) differs from the number of outputs (%d).\n", 
                    Extra_FileReaderGetFileName(p), iLine+1, strlen(pCubeOut), nOutputs );
                Abc_NtkDelete( pNtk );
                return NULL;
            }
            for ( i = 0; i < nOutputs; i++ )
            {
                if ( pCubeOut[i] == '1' )
                {
                    Vec_StrAppend( ppSops[i], pCubeIn );
                    Vec_StrAppend( ppSops[i], " 1\n" );
                }
            }
            nCubes++;
        }
Example #13
0
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Io_ReadEdifNetwork( Extra_FileReader_t * p )
{
    ProgressBar * pProgress;
    Vec_Ptr_t * vTokens;
    Abc_Ntk_t * pNtk;
    Abc_Obj_t * pNet, * pObj, * pFanout;
    char * pGateName, * pNetName;
    int fTokensReady, iLine, i;

    // read the first line
    vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
    if ( strcmp( (char *)vTokens->pArray[0], "edif" ) != 0 )
    {
        printf( "%s: Wrong input file format.\n", Extra_FileReaderGetFileName(p) );
        return NULL;
    }
    
    // allocate the empty network
    pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) );

    // go through the lines of the file
    fTokensReady = 0;
    pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p) );
    for ( iLine = 1; fTokensReady || (vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p)); iLine++ )
    {
        Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p), NULL );

        // get the type of the line
        fTokensReady = 0;
        if ( strcmp( (char *)vTokens->pArray[0], "instance" ) == 0 )
        { 
            pNetName = (char *)vTokens->pArray[1];
            pNet = Abc_NtkFindOrCreateNet( pNtk, pNetName );
            vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            pGateName = (char *)vTokens->pArray[1];
            if ( strncmp( pGateName, "Flip", 4 ) == 0 )
            {
                pObj = Abc_NtkCreateLatch( pNtk );
                Abc_LatchSetInit0( pObj );
            }
            else
            {
                pObj = Abc_NtkCreateNode( pNtk );
//                pObj->pData = Abc_NtkRegisterName( pNtk, pGateName );
                pObj->pData = Extra_UtilStrsav( pGateName ); // memory leak!!!
            }
            Abc_ObjAddFanin( pNet, pObj );
        }
        else if ( strcmp( (char *)vTokens->pArray[0], "net" ) == 0 )
        {
            pNetName = (char *)vTokens->pArray[1];
            if ( strcmp( pNetName, "CK" ) == 0 || strcmp( pNetName, "RESET" ) == 0 )
                continue;
            if ( strcmp( pNetName + strlen(pNetName) - 4, "_out" ) == 0 )
                pNetName[strlen(pNetName) - 4] = 0;
            pNet = Abc_NtkFindNet( pNtk, pNetName );
            assert( pNet );
            vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            while ( strcmp( (char *)vTokens->pArray[0], "portRef" ) == 0 )
            {
                if ( strcmp( pNetName, (char *)vTokens->pArray[3] ) != 0 )
                {
                    pFanout = Abc_NtkFindNet( pNtk, (char *)vTokens->pArray[3] );
                    Abc_ObjAddFanin( Abc_ObjFanin0(pFanout), pNet );
                }
                vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            }
            fTokensReady = 1;
        }
        else if ( strcmp( (char *)vTokens->pArray[0], "library" ) == 0 )
        {
            vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            while ( strcmp( (char *)vTokens->pArray[0], "port" ) == 0 )
            {
                pNetName = (char *)vTokens->pArray[1];
                if ( strcmp( pNetName, "CK" ) == 0 || strcmp( pNetName, "RESET" ) == 0 )
                {
                    vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
                    continue;
                }
                if ( strcmp( pNetName + strlen(pNetName) - 3, "_PO" ) == 0 )
                    pNetName[strlen(pNetName) - 3] = 0;
                if ( strcmp( (char *)vTokens->pArray[3], "INPUT" ) == 0 )
                    Io_ReadCreatePi( pNtk, (char *)vTokens->pArray[1] );
                else if ( strcmp( (char *)vTokens->pArray[3], "OUTPUT" ) == 0 )
                    Io_ReadCreatePo( pNtk, (char *)vTokens->pArray[1] );
                else
                {
                    printf( "%s (line %d): Wrong interface specification.\n", Extra_FileReaderGetFileName(p), iLine );
                    Abc_NtkDelete( pNtk );
                    return NULL;
                }
                vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p);
            }
        }
        else if ( strcmp( (char *)vTokens->pArray[0], "design" ) == 0 )
        {
            ABC_FREE( pNtk->pName ); 
            pNtk->pName = (char *)Extra_UtilStrsav( (char *)vTokens->pArray[3] );
            break;
        }
    }
    Extra_ProgressBarStop( pProgress );

    // assign logic functions
    Abc_NtkForEachNode( pNtk, pObj, i )
    {
        if ( strncmp( (char *)pObj->pData, "And", 3 ) == 0 )
            Abc_ObjSetData( pObj, Abc_SopCreateAnd((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) );
        else if ( strncmp( (char *)pObj->pData, "Or", 2 ) == 0 )
            Abc_ObjSetData( pObj, Abc_SopCreateOr((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj), NULL) );
        else if ( strncmp( (char *)pObj->pData, "Nand", 4 ) == 0 )
            Abc_ObjSetData( pObj, Abc_SopCreateNand((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) );
        else if ( strncmp( (char *)pObj->pData, "Nor", 3 ) == 0 )
            Abc_ObjSetData( pObj, Abc_SopCreateNor((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) );
        else if ( strncmp( (char *)pObj->pData, "Exor", 4 ) == 0 )
            Abc_ObjSetData( pObj, Abc_SopCreateXor((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) );
        else if ( strncmp( (char *)pObj->pData, "Exnor", 5 ) == 0 )
            Abc_ObjSetData( pObj, Abc_SopCreateNxor((Mem_Flex_t *)pNtk->pManFunc, Abc_ObjFaninNum(pObj)) );
        else if ( strncmp( (char *)pObj->pData, "Inv", 3 ) == 0 )
            Abc_ObjSetData( pObj, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) );
        else if ( strncmp( (char *)pObj->pData, "Buf", 3 ) == 0 )
            Abc_ObjSetData( pObj, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) );
        else
        {
            printf( "%s: Unknown gate type \"%s\".\n", Extra_FileReaderGetFileName(p), (char*)pObj->pData );
            Abc_NtkDelete( pNtk );
            return NULL;
        }
    }
    // check if constants have been added
//    if ( pNet = Abc_NtkFindNet( pNtk, "VDD" ) )
//        Io_ReadCreateConst( pNtk, "VDD", 1 );
//    if ( pNet = Abc_NtkFindNet( pNtk, "GND" ) )
//        Io_ReadCreateConst( pNtk, "GND", 0 );

    Abc_NtkFinalizeRead( pNtk );
    return pNtk;
}