/**Function************************************************************* Synopsis [Computes the l-value of the node.] Description [The node can be internal or a PO.] SideEffects [] SeeAlso [] ***********************************************************************/ int Seq_FpgaNodeUpdateLValue( Abc_Obj_t * pObj, int Fi ) { Cut_Cut_t * pCut, * pList; int lValueNew, lValueOld, lValueCut; assert( !Abc_ObjIsPi(pObj) ); assert( Abc_ObjFaninNum(pObj) > 0 ); if ( Abc_ObjIsPo(pObj) ) { lValueNew = Seq_NodeGetLValue(Abc_ObjFanin0(pObj)) - Fi * Seq_ObjFaninL0(pObj); return (lValueNew > Fi)? SEQ_UPDATE_FAIL : SEQ_UPDATE_NO; } // get the arrival time of the best non-trivial cut pList = Abc_NodeReadCuts( Seq_NodeCutMan(pObj), pObj ); // skip the choice nodes if ( pList == NULL ) return SEQ_UPDATE_NO; lValueNew = ABC_INFINITY; for ( pCut = pList->pNext; pCut; pCut = pCut->pNext ) { lValueCut = Seq_FpgaCutUpdateLValue( pCut, pObj, Fi ); if ( lValueNew > lValueCut ) lValueNew = lValueCut; } // compare the arrival time with the previous arrival time lValueOld = Seq_NodeGetLValue(pObj); // if ( lValueNew == lValueOld ) if ( lValueNew <= lValueOld ) return SEQ_UPDATE_NO; Seq_NodeSetLValue( pObj, lValueNew ); //printf( "%d -> %d ", lValueOld, lValueNew ); return SEQ_UPDATE_YES; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_Ntk4VarObjPrint_rec( Abc_Obj_t * pObj ) { if ( pObj == Abc_AigConst1(pObj->pNtk) ) { printf( "1" ); return; } if ( Abc_ObjIsPi(pObj) ) { printf( "%c", pObj->Id - 1 + 'a' ); return; } printf( "(" ); Abc_Ntk4VarObjPrint_rec( Abc_ObjFanin0(pObj) ); if ( Abc_ObjFaninC0(pObj) ) printf( "\'" ); Abc_Ntk4VarObjPrint_rec( Abc_ObjFanin1(pObj) ); if ( Abc_ObjFaninC1(pObj) ) printf( "\'" ); printf( ")" ); }
/**Function************************************************************* Synopsis [Selects the best cut to represent the node in the mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Cut_Cut_t * Seq_FpgaMappingSelectCut( Abc_Obj_t * pAnd ) { Abc_Obj_t * pFanin; Cut_Cut_t * pCut, * pCutBest, * pList; float CostCur, CostMin = ABC_INFINITY; int ArrivalCut, ArrivalMin, i; // get the arrival time of the best non-trivial cut ArrivalMin = Seq_NodeGetLValue( pAnd ); // iterate through the cuts and select the one with the minimum cost pList = Abc_NodeReadCuts( Seq_NodeCutMan(pAnd), pAnd ); CostMin = ABC_INFINITY; pCutBest = NULL; for ( pCut = pList->pNext; pCut; pCut = pCut->pNext ) { ArrivalCut = *((int *)&pCut->uSign); // assert( ArrivalCut >= ArrivalMin ); if ( ArrivalCut > ArrivalMin ) continue; CostCur = 0.0; for ( i = 0; i < (int)pCut->nLeaves; i++ ) { pFanin = Abc_NtkObj( pAnd->pNtk, pCut->pLeaves[i] >> 8 ); if ( Abc_ObjIsPi(pFanin) ) continue; if ( Abc_NodeIsTravIdCurrent(pFanin) ) continue; CostCur += (float)(1.0 / Abc_ObjFanoutNum(pFanin)); // CostCur += Seq_NodeGetFlow( pFanin ); } if ( CostMin > CostCur ) { CostMin = CostCur; pCutBest = pCut; } } assert( pCutBest != NULL ); return pCutBest; }
/**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 = NULL, * pActual; int i, Length, Start = -1; // get the model for this box pNames = (Vec_Ptr_t *)pBox->pData; if ( !stmm_lookup( tName2Model, (char *)Vec_PtrEntry(pNames, 0), (char **)&pNtkModel ) ) { p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; sprintf( p->sError, "Cannot find the model for subcircuit %s.", (char*)Vec_PtrEntry(pNames, 0) ); Io_ReadBlifPrintErrorMessage( p ); return 1; } // create the fanins of the box Abc_NtkForEachPi( pNtkModel, pObj, i ) pObj->pCopy = NULL; if ( Abc_NtkPiNum(pNtkModel) == 0 ) Start = 1; else { Vec_PtrForEachEntryStart( char *, pNames, pName, i, 1 ) { pActual = Io_ReadBlifCleanName(pName); if ( pActual == NULL ) { p->LineCur = (int)(ABC_PTRINT_T)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)(ABC_PTRINT_T)pBox->pCopy; sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, (char*)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)(ABC_PTRINT_T)pBox->pCopy; sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName ); Io_ReadBlifPrintErrorMessage( p ); return 1; } pObj->pCopy = (Abc_Obj_t *)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 = (char *)pObj->pCopy; if ( pActual == NULL ) { p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy; sprintf( p->sError, "Formal input \"%s\" of model %s is not driven.", pName, (char*)Vec_PtrEntry(pNames, 0) ); Io_ReadBlifPrintErrorMessage( p ); return 1; } pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual ); Abc_ObjAddFanin( pBox, pNet ); }