word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp ) { int i, Fanin; assert( Vec_WrdSize(vTemp) == Gia_ManObjNum(p) ); assert( Gia_ObjIsLut(p, iObj) ); Gia_LutForEachFanin( p, iObj, Fanin, i ) Vec_WrdWriteEntry( vTemp, Fanin, s_Truth6[i] ); assert( i <= 6 ); Gia_ObjComputeTruthTable6Lut_rec( p, iObj, vTemp ); return Vec_WrdEntry( vTemp, iObj ); }
word Gia_ObjComputeTruthTable6( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Wrd_t * vTruths ) { Gia_Obj_t * pLeaf; int i; assert( Vec_IntSize(vSupp) <= 6 ); assert( Gia_ObjIsAnd(pObj) ); assert( !pObj->fMark0 ); Vec_WrdClear( vTruths ); Gia_ManIncrementTravId( p ); Gia_ManForEachObjVec( vSupp, p, pLeaf, i ) { assert( pLeaf->fMark0 || Gia_ObjIsRo(p, pLeaf) ); pLeaf->Value = Vec_WrdSize(vTruths); Vec_WrdPush( vTruths, s_Truth6[i] ); Gia_ObjSetTravIdCurrent(p, pLeaf); }
SC_CellForEachPinOut( pCell, pPin, j ) { SC_Timings * pRTime; word uWord; assert(pPin->dir == sc_dir_Output); Vec_StrPutS( vOut, pPin->pName ); Vec_StrPutF( vOut, pPin->max_out_cap ); Vec_StrPutF( vOut, pPin->max_out_slew ); // write function if ( pPin->func_text == NULL ) { // formula is not given - write empty string Vec_StrPutS( vOut, "" ); // write truth table assert( Vec_WrdSize(pPin->vFunc) == Abc_Truth6WordNum(pCell->n_inputs) ); Vec_StrPutI( vOut, pCell->n_inputs ); Vec_WrdForEachEntry( pPin->vFunc, uWord, k ) // -- 'size = 1u << (n_vars - 6)' Vec_StrPutW( vOut, uWord ); // -- 64-bit number, written uncompressed (low-byte first) } else // formula is given Vec_StrPutS( vOut, pPin->func_text ); // Write 'rtiming': (pin-to-pin timing tables for this particular output) assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs ); SC_PinForEachRTiming( pPin, pRTime, k ) { Vec_StrPutS( vOut, pRTime->pName ); Vec_StrPutI( vOut, Vec_PtrSize(pRTime->vTimings) ); // -- NOTE! After post-processing, the size of the 'rtiming[k]' vector is either // 0 or 1 (in static timing, we have merged all tables to get the worst case). // The case with size 0 should only occur for multi-output gates. if ( Vec_PtrSize(pRTime->vTimings) == 1 ) { SC_Timing * pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); // -- NOTE! We don't need to save 'related_pin' string because we have sorted // the elements on input pins. Vec_StrPutI( vOut, (int)pTime->tsense); Abc_SclWriteSurface( vOut, pTime->pCellRise ); Abc_SclWriteSurface( vOut, pTime->pCellFall ); Abc_SclWriteSurface( vOut, pTime->pRiseTrans ); Abc_SclWriteSurface( vOut, pTime->pFallTrans ); } else assert( Vec_PtrSize(pRTime->vTimings) == 0 ); }
/**Function************************************************************* Synopsis [Computes truth table up to 6 inputs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ObjComputeTruthTable6_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Wrd_t * vTruths ) { word uTruth0, uTruth1; if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return; Gia_ObjSetTravIdCurrent(p, pObj); assert( !pObj->fMark0 ); assert( Gia_ObjIsAnd(pObj) ); Gia_ObjComputeTruthTable6_rec( p, Gia_ObjFanin0(pObj), vTruths ); Gia_ObjComputeTruthTable6_rec( p, Gia_ObjFanin1(pObj), vTruths ); uTruth0 = Vec_WrdEntry( vTruths, Gia_ObjFanin0(pObj)->Value ); uTruth0 = Gia_ObjFaninC0(pObj) ? ~uTruth0 : uTruth0; uTruth1 = Vec_WrdEntry( vTruths, Gia_ObjFanin1(pObj)->Value ); uTruth1 = Gia_ObjFaninC1(pObj) ? ~uTruth1 : uTruth1; pObj->Value = Vec_WrdSize(vTruths); Vec_WrdPush( vTruths, uTruth0 & uTruth1 ); }
static inline word * Gla_ObjTruthFree2( Gia_Man_t * p ) { return Vec_WrdArray(p->vTtMemory) + Vec_WrdSize(p->vTtMemory) - p->nTtWords * 2; }
static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) { int i, j, k, n; int version = Vec_StrGetI( vOut, pPos ); assert( version == 5 || version == ABC_SCL_CUR_VERSION ); // wrong version of the file // Read non-composite fields: p->pName = Vec_StrGetS(vOut, pPos); p->default_wire_load = Vec_StrGetS(vOut, pPos); p->default_wire_load_sel = Vec_StrGetS(vOut, pPos); p->default_max_out_slew = Vec_StrGetF(vOut, pPos); p->unit_time = Vec_StrGetI(vOut, pPos); p->unit_cap_fst = Vec_StrGetF(vOut, pPos); p->unit_cap_snd = Vec_StrGetI(vOut, pPos); // Read 'wire_load' vector: for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) { SC_WireLoad * pWL = Abc_SclWireLoadAlloc(); Vec_PtrPush( p->vWireLoads, pWL ); pWL->pName = Vec_StrGetS(vOut, pPos); pWL->res = Vec_StrGetF(vOut, pPos); pWL->cap = Vec_StrGetF(vOut, pPos); for ( j = Vec_StrGetI(vOut, pPos); j != 0; j-- ) { Vec_IntPush( pWL->vFanout, Vec_StrGetI(vOut, pPos) ); Vec_FltPush( pWL->vLen, Vec_StrGetF(vOut, pPos) ); } } // Read 'wire_load_sel' vector: for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) { SC_WireLoadSel * pWLS = Abc_SclWireLoadSelAlloc(); Vec_PtrPush( p->vWireLoadSels, pWLS ); pWLS->pName = Vec_StrGetS(vOut, pPos); for ( j = Vec_StrGetI(vOut, pPos); j != 0; j-- ) { Vec_FltPush( pWLS->vAreaFrom, Vec_StrGetF(vOut, pPos) ); Vec_FltPush( pWLS->vAreaTo, Vec_StrGetF(vOut, pPos) ); Vec_PtrPush( pWLS->vWireLoadModel, Vec_StrGetS(vOut, pPos) ); } } for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) { SC_Cell * pCell = Abc_SclCellAlloc(); pCell->Id = SC_LibCellNum(p); Vec_PtrPush( p->vCells, pCell ); pCell->pName = Vec_StrGetS(vOut, pPos); pCell->area = Vec_StrGetF(vOut, pPos); pCell->drive_strength = Vec_StrGetI(vOut, pPos); pCell->n_inputs = Vec_StrGetI(vOut, pPos); pCell->n_outputs = Vec_StrGetI(vOut, pPos); /* printf( "%s\n", pCell->pName ); if ( !strcmp( "XOR3_X4M_A9TL", pCell->pName ) ) { int s = 0; } */ for ( j = 0; j < pCell->n_inputs; j++ ) { SC_Pin * pPin = Abc_SclPinAlloc(); Vec_PtrPush( pCell->vPins, pPin ); pPin->dir = sc_dir_Input; pPin->pName = Vec_StrGetS(vOut, pPos); pPin->rise_cap = Vec_StrGetF(vOut, pPos); pPin->fall_cap = Vec_StrGetF(vOut, pPos); } for ( j = 0; j < pCell->n_outputs; j++ ) { SC_Pin * pPin = Abc_SclPinAlloc(); Vec_PtrPush( pCell->vPins, pPin ); pPin->dir = sc_dir_Output; pPin->pName = Vec_StrGetS(vOut, pPos); pPin->max_out_cap = Vec_StrGetF(vOut, pPos); pPin->max_out_slew = Vec_StrGetF(vOut, pPos); k = Vec_StrGetI(vOut, pPos); assert( k == pCell->n_inputs ); // read function if ( version == 5 ) { // formula is not given assert( Vec_WrdSize(pPin->vFunc) == 0 ); Vec_WrdGrow( pPin->vFunc, Abc_Truth6WordNum(pCell->n_inputs) ); for ( k = 0; k < Vec_WrdCap(pPin->vFunc); k++ ) Vec_WrdPush( pPin->vFunc, Vec_StrGetW(vOut, pPos) ); } else { // (possibly empty) formula is always given assert( version == ABC_SCL_CUR_VERSION ); assert( pPin->func_text == NULL ); pPin->func_text = Vec_StrGetS(vOut, pPos); if ( pPin->func_text[0] == 0 ) { // formula is not given - read truth table ABC_FREE( pPin->func_text ); assert( Vec_WrdSize(pPin->vFunc) == 0 ); Vec_WrdGrow( pPin->vFunc, Abc_Truth6WordNum(pCell->n_inputs) ); for ( k = 0; k < Vec_WrdCap(pPin->vFunc); k++ ) Vec_WrdPush( pPin->vFunc, Vec_StrGetW(vOut, pPos) ); } else { // formula is given - derive truth table SC_Pin * pPin2; Vec_Ptr_t * vNames; // collect input names vNames = Vec_PtrAlloc( pCell->n_inputs ); SC_CellForEachPinIn( pCell, pPin2, n ) Vec_PtrPush( vNames, pPin2->pName ); // derive truth table assert( Vec_WrdSize(pPin->vFunc) == 0 ); Vec_WrdFree( pPin->vFunc ); pPin->vFunc = Mio_ParseFormulaTruth( pPin->func_text, (char **)Vec_PtrArray(vNames), pCell->n_inputs ); Vec_PtrFree( vNames ); // skip truth table assert( Vec_WrdSize(pPin->vFunc) == Abc_Truth6WordNum(pCell->n_inputs) ); for ( k = 0; k < Vec_WrdSize(pPin->vFunc); k++ ) { word Value = Vec_StrGetW(vOut, pPos); assert( Value == Vec_WrdEntry(pPin->vFunc, k) ); } } } // Read 'rtiming': (pin-to-pin timing tables for this particular output) for ( k = 0; k < pCell->n_inputs; k++ ) { SC_Timings * pRTime = Abc_SclTimingsAlloc(); Vec_PtrPush( pPin->vRTimings, pRTime ); pRTime->pName = Vec_StrGetS(vOut, pPos); n = Vec_StrGetI(vOut, pPos); assert( n <= 1 ); if ( n == 1 ) { SC_Timing * pTime = Abc_SclTimingAlloc(); Vec_PtrPush( pRTime->vTimings, pTime ); pTime->tsense = (SC_TSense)Vec_StrGetI(vOut, pPos); Abc_SclReadSurface( vOut, pPos, pTime->pCellRise ); Abc_SclReadSurface( vOut, pPos, pTime->pCellFall ); Abc_SclReadSurface( vOut, pPos, pTime->pRiseTrans ); Abc_SclReadSurface( vOut, pPos, pTime->pFallTrans ); } else assert( Vec_PtrSize(pRTime->vTimings) == 0 ); } } } }
static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) { int i, j, k, n; int version = Vec_StrGetI( vOut, pPos ); assert( version == ABC_SCL_CUR_VERSION ); // wrong version of the file // Read non-composite fields: p->pName = Vec_StrGetS(vOut, pPos); p->default_wire_load = Vec_StrGetS(vOut, pPos); p->default_wire_load_sel = Vec_StrGetS(vOut, pPos); p->default_max_out_slew = Vec_StrGetF(vOut, pPos); p->unit_time = Vec_StrGetI(vOut, pPos); p->unit_cap_fst = Vec_StrGetF(vOut, pPos); p->unit_cap_snd = Vec_StrGetI(vOut, pPos); // Read 'wire_load' vector: for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) { SC_WireLoad * pWL = Abc_SclWireLoadAlloc(); Vec_PtrPush( p->vWireLoads, pWL ); pWL->pName = Vec_StrGetS(vOut, pPos); pWL->res = Vec_StrGetF(vOut, pPos); pWL->cap = Vec_StrGetF(vOut, pPos); for ( j = Vec_StrGetI(vOut, pPos); j != 0; j-- ) { Vec_IntPush( pWL->vFanout, Vec_StrGetI(vOut, pPos) ); Vec_FltPush( pWL->vLen, Vec_StrGetF(vOut, pPos) ); } } // Read 'wire_load_sel' vector: for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) { SC_WireLoadSel * pWLS = Abc_SclWireLoadSelAlloc(); Vec_PtrPush( p->vWireLoadSels, pWLS ); pWLS->pName = Vec_StrGetS(vOut, pPos); for ( j = Vec_StrGetI(vOut, pPos); j != 0; j-- ) { Vec_FltPush( pWLS->vAreaFrom, Vec_StrGetF(vOut, pPos) ); Vec_FltPush( pWLS->vAreaTo, Vec_StrGetF(vOut, pPos) ); Vec_PtrPush( pWLS->vWireLoadModel, Vec_StrGetS(vOut, pPos) ); } } for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) { SC_Cell * pCell = Abc_SclCellAlloc(); pCell->Id = Vec_PtrSize(p->vCells); Vec_PtrPush( p->vCells, pCell ); pCell->pName = Vec_StrGetS(vOut, pPos); pCell->area = Vec_StrGetF(vOut, pPos); pCell->drive_strength = Vec_StrGetI(vOut, pPos); pCell->n_inputs = Vec_StrGetI(vOut, pPos); pCell->n_outputs = Vec_StrGetI(vOut, pPos); for ( j = 0; j < pCell->n_inputs; j++ ) { SC_Pin * pPin = Abc_SclPinAlloc(); Vec_PtrPush( pCell->vPins, pPin ); pPin->dir = sc_dir_Input; pPin->pName = Vec_StrGetS(vOut, pPos); pPin->rise_cap = Vec_StrGetF(vOut, pPos); pPin->fall_cap = Vec_StrGetF(vOut, pPos); } for ( j = 0; j < pCell->n_outputs; j++ ) { SC_Pin * pPin = Abc_SclPinAlloc(); Vec_PtrPush( pCell->vPins, pPin ); pPin->dir = sc_dir_Output; pPin->pName = Vec_StrGetS(vOut, pPos); pPin->max_out_cap = Vec_StrGetF(vOut, pPos); pPin->max_out_slew = Vec_StrGetF(vOut, pPos); k = Vec_StrGetI(vOut, pPos); assert( k == pCell->n_inputs ); // read functions assert( Vec_WrdSize(pPin->vFunc) == 0 ); Vec_WrdGrow( pPin->vFunc, Abc_Truth6WordNum(pCell->n_inputs) ); for ( k = 0; k < Vec_WrdCap(pPin->vFunc); k++ ) Vec_WrdPush( pPin->vFunc, Vec_StrGetW(vOut, pPos) ); // Read 'rtiming': (pin-to-pin timing tables for this particular output) for ( k = 0; k < pCell->n_inputs; k++ ) { SC_Timings * pRTime = Abc_SclTimingsAlloc(); Vec_PtrPush( pPin->vRTimings, pRTime ); pRTime->pName = Vec_StrGetS(vOut, pPos); n = Vec_StrGetI(vOut, pPos); assert( n <= 1 ); if ( n == 1 ) { SC_Timing * pTime = Abc_SclTimingAlloc(); Vec_PtrPush( pRTime->vTimings, pTime ); pTime->tsense = (SC_TSense)Vec_StrGetI(vOut, pPos); Abc_SclReadSurface( vOut, pPos, pTime->pCellRise ); Abc_SclReadSurface( vOut, pPos, pTime->pCellFall ); Abc_SclReadSurface( vOut, pPos, pTime->pRiseTrans ); Abc_SclReadSurface( vOut, pPos, pTime->pFallTrans ); } else assert( Vec_PtrSize(pPin->vRTimings) == 0 ); } } } }