diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 45f2329cb..098892f85 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -140,6 +140,7 @@ struct Gia_Man_t_ void * pSatlutWinman; // windowing for SAT-based mapping Vec_Int_t * vPacking; // packing information Vec_Int_t * vConfigs; // cell configurations + Vec_Str_t * vConfigs2; // cell configurations char * pCellStr; // cell description Vec_Int_t * vLutConfigs; // LUT configurations Vec_Int_t * vEdgeDelay; // special edge information diff --git a/src/aig/gia/giaAiger.c b/src/aig/gia/giaAiger.c index 107faaceb..a51ddfa43 100644 --- a/src/aig/gia/giaAiger.c +++ b/src/aig/gia/giaAiger.c @@ -22,6 +22,7 @@ #include "gia.h" #include "misc/tim/tim.h" #include "base/main/main.h" +#include "map/if/if.h" ABC_NAMESPACE_IMPL_START @@ -800,6 +801,36 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi assert( pCur == pCurTemp ); if ( fVerbose ) printf( "Finished reading extension \"b\".\n" ); } + // read configuration data for extension "j" + else if ( *pCur == 'j' ) + { + int nSize, Reserved, NumCellTypes, CellId, BytesPerInstance, TotalInstances; + pCur++; + nSize = Gia_AigerReadInt(pCur); + pCurTemp = pCur + nSize + 4; pCur += 4; + // Read reserved value (should be 0) + Reserved = Gia_AigerReadInt(pCur); pCur += 4; + assert( Reserved == 0 ); + // Read number of cell types + NumCellTypes = Gia_AigerReadInt(pCur); pCur += 4; + // Skip cell type definitions (we know them already) + for ( i = 0; i < NumCellTypes; i++ ) + { + CellId = Gia_AigerReadInt(pCur); pCur += 4; + // Skip function description string (null-terminated) + while ( *pCur++ != '\0' ); + BytesPerInstance = Gia_AigerReadInt(pCur); pCur += 4; + } + // Read total number of instances + TotalInstances = Gia_AigerReadInt(pCur); pCur += 4; + // Create byte vector for instance data + pNew->vConfigs2 = Vec_StrAlloc( (int)(pCurTemp - pCur) ); + // Read instance data as bytes + while ( pCur < pCurTemp ) + Vec_StrPush( pNew->vConfigs2, *pCur++ ); + assert( pCur == pCurTemp ); + if ( fVerbose ) printf( "Finished reading extension \"j\".\n" ); + } // read choices else if ( *pCur == 'q' ) { @@ -1514,6 +1545,88 @@ void Gia_AigerWriteS( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, in for ( i = 0; i < Vec_IntSize(p->vConfigs); i++ ) Gia_FileWriteBufferSize( pFile, Vec_IntEntry(p->vConfigs, i) ); } + // write configuration data for extension "j" + if ( p->vConfigs2 ) + { + int nTotalSize, nInstances = 0; + If_LibCell_t * pLibCell = NULL; // (If_LibCell_t *)Abc_FrameReadLibCell(); + char *pCell0, *pCell1, *pCell2; + + // Get formulas from cell library or use defaults + if ( pLibCell && pLibCell->nCellNum == 3 && + pLibCell->pCellNames[0] && pLibCell->pCellNames[1] && pLibCell->pCellNames[2] ) + { + pCell0 = pLibCell->pCellNames[0]; + pCell1 = pLibCell->pCellNames[1]; + pCell2 = pLibCell->pCellNames[2]; + } + else + { + if ( !pLibCell ) + Abc_Print( 0, "Warning: Cell library is not loaded. Using generic formulas.\n" ); + else if ( pLibCell->nCellNum != 3 ) + Abc_Print( 0, "Warning: Cell library has %d cells (expected exactly 3). Using generic formulas.\n", pLibCell->nCellNum ); + else + Abc_Print( 0, "Warning: Cell library does not contain all required cells. Using generic formulas.\n" ); + pCell0 = "Formula1"; + pCell1 = "Formula2"; + pCell2 = "Formula3"; + } + // Count instances by scanning the byte data + for ( i = 0; i < Vec_StrSize(p->vConfigs2); ) + { + unsigned char CellId = (unsigned char)Vec_StrEntry(p->vConfigs2, i); + if ( CellId == 0 ) + i += 4; // 1 byte CellId + 2 bytes truth table + 1 padding + else if ( CellId == 1 ) + i += 12; // 1 byte CellId + 4 bytes mapping + 4 bytes truth tables + 3 padding + else if ( CellId == 2 ) + i += 12; // 1 byte CellId + 5 bytes mapping + 4 bytes truth tables + 2 padding + else + assert( 0 ); // Unknown cell type + nInstances++; + } + fprintf( pFile, "j" ); + // Calculate total size + nTotalSize = 4; // Reserved value + nTotalSize += 4; // Number of cell types + // Cell type 0 + nTotalSize += 4; // CellId + nTotalSize += strlen(pCell0) + 1; // Function description + nTotalSize += 4; // Bytes per instance + // Cell type 1 + nTotalSize += 4; // CellId + nTotalSize += strlen(pCell1) + 1; // Function description + nTotalSize += 4; // Bytes per instance + // Cell type 2 + nTotalSize += 4; // CellId + nTotalSize += strlen(pCell2) + 1; // Function description + nTotalSize += 4; // Bytes per instance + // Instance data + nTotalSize += 4; // Total instances count + nTotalSize += Vec_StrSize(p->vConfigs2); // Actual instance data + Gia_FileWriteBufferSize( pFile, nTotalSize ); + // Write reserved value + Gia_FileWriteBufferSize( pFile, 0 ); + // Write number of cell types + Gia_FileWriteBufferSize( pFile, 3 ); + // Write cell type 0 (LUT4) + Gia_FileWriteBufferSize( pFile, 0 ); // CellId + fwrite( pCell0, 1, strlen(pCell0) + 1, pFile ); + Gia_FileWriteBufferSize( pFile, 4 ); // 1 byte CellId + 2 bytes truth table, rounded to 4 + // Write cell type 1 (S44) + Gia_FileWriteBufferSize( pFile, 1 ); // CellId + fwrite( pCell1, 1, strlen(pCell1) + 1, pFile ); + Gia_FileWriteBufferSize( pFile, 12 ); // 1 byte CellId + 4 bytes mapping + 4 bytes truth tables, rounded to 12 + // Write cell type 2 (9-input) + Gia_FileWriteBufferSize( pFile, 2 ); // CellId + fwrite( pCell2, 1, strlen(pCell2) + 1, pFile ); + Gia_FileWriteBufferSize( pFile, 12 ); // 1 byte CellId + 5 bytes mapping + 4 bytes truth tables (LUT4s only), rounded to 12 + // Write total instances + Gia_FileWriteBufferSize( pFile, nInstances ); + // Write instance data as raw bytes + fwrite( Vec_StrArray(p->vConfigs2), 1, Vec_StrSize(p->vConfigs2), pFile ); + } // write choices if ( Gia_ManHasChoices(p) ) { diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index c72582b05..ea58ba8b2 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -790,6 +790,8 @@ Gia_Man_t * Gia_ManDupWithAttributes( Gia_Man_t * p ) pNew->vRegInits = Vec_IntDup( p->vRegInits ); if ( p->vConfigs ) pNew->vConfigs = Vec_IntDup( p->vConfigs ); + if ( p->vConfigs2 ) + pNew->vConfigs2 = Vec_StrDup( p->vConfigs2 ); if ( p->pCellStr ) pNew->pCellStr = Abc_UtilStrsav( p->pCellStr ); // copy names if present diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 0ce43a351..c386dbcb9 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -1188,11 +1188,13 @@ int Gia_ManFromIfLogicCreateLutSpecial( Gia_Man_t * pNew, word * pRes, Vec_Int_t ***********************************************************************/ int Gia_ManFromIfLogicCreateLutSpecialJ( Gia_Man_t * pNew, word * pRes, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking ) { - word z = If_CutPerformDeriveJ( NULL, (unsigned *)pRes, Vec_IntSize(vLeaves), Vec_IntSize(vLeaves), NULL, 1 ); + return Gia_ManFromIfLogicCreateLut( pNew, pRes, vLeaves, vCover, vMapping, vMapping2 ); + word Truth; int i, iObjLit1, iObjLit2, iObjLit3; - - if ( ((z >> 63) & 1) == 0 ) // S44 decomposition + word z = If_CutPerformDeriveJ( NULL, (unsigned *)pRes, Vec_IntSize(vLeaves), Vec_IntSize(vLeaves), NULL, 1 ); + assert( z != 0 ); + if ( ((z >> 63) & 1) == 0 ) { // create first LUT Vec_IntClear( vLeavesTemp ); @@ -1292,7 +1294,7 @@ int Gia_ManFromIfLogicCreateLutSpecialJ( Gia_Man_t * pNew, word * pRes, Vec_Int_ ***********************************************************************/ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp, - word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking, int fCheck75, int fCheck44e ) + word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking, int fCheck75, int fEnableCheck07 ) { int nLeaves = Vec_IntSize(vLeaves); int i, Length, nLutLeaf, nLutLeaf2, nLutRoot, iObjLit1, iObjLit2, iObjLit3; @@ -1300,9 +1302,9 @@ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t if ( fCheck75 ) pStr = "54"; // perform special case matching for 44 - if ( fCheck44e ) - { - if ( Vec_IntSize(vLeaves) <= 5 ) + if ( fEnableCheck07 ) + { + if ( 0 && Vec_IntSize(vLeaves) <= 4 ) { // create mapping iObjLit1 = Gia_ManFromIfLogicCreateLut( pNew, pRes, vLeaves, vCover, vMapping, vMapping2 ); @@ -1314,7 +1316,7 @@ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t Vec_IntAddToEntry( vPacking, 0, 1 ); } return iObjLit1; - } + } return Gia_ManFromIfLogicCreateLutSpecialJ( pNew, pRes, vLeaves, vLeavesTemp, vCover, vMapping, vMapping2, vPacking ); } if ( ((If_Man_t *)pIfMan)->pPars->fLut6Filter && Vec_IntSize(vLeaves) == 6 ) @@ -1916,6 +1918,234 @@ void Gia_ManFromIfGetConfig( Vec_Int_t * vConfigs, If_Man_t * pIfMan, If_Cut_t * Vec_StrPush( vConfigsStr, '\n' ); } } +/**Function************************************************************* + + Synopsis [Print configuration during encoding.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManConfigPrint( word Truth4, word z, int nLeaves ) +{ + static int Count = 0; + int i; + printf( "[%4d] Encoding (nLeaves=%d): ", Count++, nLeaves ); + // Simple LUT4 case (Truth4 != 0, z == 0) + if ( z == 0 ) + { + printf( "%04lX{", (unsigned long)(Truth4 & 0xFFFF) ); + for ( i = 0; i < nLeaves && i < 4; i++ ) + printf( "%c", 'a' + i ); + printf( "} [Cell 0, LUT4]\n" ); + return; + } + if ( ((z >> 63) & 1) == 0 ) + { + // Extract truth tables + word Truth1 = z & 0xFFFF; + word Truth2 = (z >> 32) & 0xFFFF; + printf( "h=%04lX{", (unsigned long)Truth1 ); + // First LUT4 inputs from bits 16-31 + for ( i = 0; i < 4; i++ ) + { + int v = (int)((z >> (16 + (i << 2))) & 7); + if ( v == 6 && nLeaves == 5 ) + printf( "0" ); // Constant 0 for 5-input cuts + else if ( v == 7 ) + printf( "?" ); // Internal connection (shouldn't appear in first LUT) + else if ( v <= 6 ) + printf( "%c", 'a' + v ); + else + printf( "?" ); + } + printf( "} "); + printf( "i=%04lX{", (unsigned long)Truth2 ); + // Second LUT4 inputs from bits 48-63 + for ( i = 0; i < 4; i++ ) + { + int v = (int)((z >> (48 + (i << 2))) & 7); + if ( v == 6 && nLeaves == 5 ) + printf( "0" ); // Constant 0 for 5-input cuts + else if ( v == 7 ) + printf( "h" ); // Output of first LUT + else if ( v <= 6 ) + printf( "%c", 'a' + v ); + else + printf( "?" ); + } + printf( "} [Cell 1, S44]\n" ); + } + else + { + int Pla2Var[9]; + extern void If_PermUnpack( unsigned Value, int Pla2Var[9] ); + If_PermUnpack( (unsigned)(z >> 32), Pla2Var ); + // Extract truth tables + word Truth1 = z & 0xFFFF; + word Truth2 = (z >> 16) & 0xFFFF; + printf( "j=%04lX{", (unsigned long)Truth1 ); + // First LUT4 inputs + for ( i = 0; i < 4; i++ ) + { + if ( Pla2Var[i] == 9 ) + printf( "0" ); // Will be encoded as constant 0 + else if ( Pla2Var[i] < 9 ) + printf( "%c", 'a' + Pla2Var[i] ); + else + printf( "?" ); + } + printf( "} "); + printf( "k=%04lX{", (unsigned long)Truth2 ); + // Second LUT4 inputs + for ( i = 4; i < 8; i++ ) + { + if ( Pla2Var[i] == 9 ) + printf( "0" ); // Will be encoded as constant 0 + else if ( Pla2Var[i] < 9 ) + printf( "%c", 'a' + Pla2Var[i] ); + else + printf( "?" ); + } + printf( "} "); + // final + printf( "l=<" ); + if ( Pla2Var[8] == 9 ) + printf( "0" ); // Will be encoded as constant 0 + else if ( Pla2Var[8] < 9 ) + printf( "%c", 'a' + Pla2Var[8] ); + else + printf( "?" ); + printf( "jk> [Cell 2, 9-input MUX]\n" ); + } +} + +/**Function************************************************************* + + Synopsis [Derive configurations.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, If_Cut_t * pCutBest ) +{ + int i, CellId, nBytes; + int startPos = Vec_StrSize(vConfigs2); + + // Determine cell type based on the number of leaves and configuration + if ( pCutBest->nLeaves <= 4 ) + { + // Cell type 0: Simple LUT4 + CellId = 0; + nBytes = 3; // 1 byte CellId + 2 bytes truth table (16 bits) + // Write CellId + Vec_StrPush( vConfigs2, (char)CellId ); + // Write truth table (16 bits for LUT4) + word Truth = *If_CutTruthW(pIfMan, pCutBest); + Vec_StrPush( vConfigs2, (char)(Truth & 0xFF) ); + Vec_StrPush( vConfigs2, (char)((Truth >> 8) & 0xFF) ); + // Pad to 4-byte boundary + while ( (Vec_StrSize(vConfigs2) - startPos) % 4 != 0 ) + Vec_StrPush( vConfigs2, 0 ); + //Gia_ManConfigPrint( Truth, 0, pCutBest->nLeaves ); + } + else + { + word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)If_CutTruthW(pIfMan, pCutBest), pCutBest->nLeaves, pCutBest->nLeaves, NULL, 1 ); + //Gia_ManConfigPrint( 0, z, pCutBest->nLeaves ); + if ( ((z >> 63) & 1) == 0 ) + { + CellId = 1; + unsigned char mappingBytes[4] = {0}; + // Write CellId + Vec_StrPush( vConfigs2, (char)CellId ); + // Write input mappings for first LUT4 (4 inputs) + for ( i = 0; i < 4; i++ ) + { + int v = (int)((z >> (16 + (i << 2))) & 7); + if ( v == 6 && pCutBest->nLeaves == 5 ) + mappingBytes[i / 2] |= (0 << ((i % 2) * 4)); // constant 0 + else + mappingBytes[i / 2] |= ((v+2) << ((i % 2) * 4)); // leaf v (direct mapping) + } + Vec_StrPush( vConfigs2, (char)mappingBytes[0] ); + Vec_StrPush( vConfigs2, (char)mappingBytes[1] ); + // Write input mappings for second LUT4 (4 inputs) + mappingBytes[0] = mappingBytes[1] = 0; + for ( i = 0; i < 4; i++ ) + { + int v = (int)((z >> (48 + (i << 2))) & 7); + if ( v == 6 && pCutBest->nLeaves == 5 ) + mappingBytes[i / 2] |= (0 << ((i % 2) * 4)); // constant 0 + else if ( v == 7 ) + mappingBytes[i / 2] |= ((7+2) << ((i % 2) * 4)); // output of first LUT at index N+2 where N=7 + else + mappingBytes[i / 2] |= ((v+2) << ((i % 2) * 4)); // leaf v (direct mapping) + } + Vec_StrPush( vConfigs2, (char)mappingBytes[0] ); + Vec_StrPush( vConfigs2, (char)mappingBytes[1] ); + // Write truth tables + word Truth1 = z & 0xFFFF; + word Truth2 = (z >> 32) & 0xFFFF; + Vec_StrPush( vConfigs2, (char)(Truth1 & 0xFF) ); + Vec_StrPush( vConfigs2, (char)((Truth1 >> 8) & 0xFF) ); + Vec_StrPush( vConfigs2, (char)(Truth2 & 0xFF) ); + Vec_StrPush( vConfigs2, (char)((Truth2 >> 8) & 0xFF) ); + // Pad to 4-byte boundary + while ( (Vec_StrSize(vConfigs2) - startPos) % 4 != 0 ) + Vec_StrPush( vConfigs2, 0 ); + } + else + { + CellId = 2; + int Pla2Var[9]; + extern void If_PermUnpack( unsigned Value, int Pla2Var[9] ); + If_PermUnpack( (unsigned)(z >> 32), Pla2Var ); + // Write CellId + Vec_StrPush( vConfigs2, (char)CellId ); + // Write input mappings (9 inputs, 4 bits each, packed) + unsigned char mappingByte = 0; + int bitPos = 0; + for ( i = 0; i < 9; i++ ) + { + int v; + if ( Pla2Var[i] == 9 ) // constant 0 + v = 0; + else // leaf index + v = Pla2Var[i] + 2; + if ( bitPos == 0 ) { + mappingByte = v & 0xF; + bitPos = 4; + } + else { + mappingByte |= (v & 0xF) << 4; + Vec_StrPush( vConfigs2, (char)mappingByte ); + bitPos = 0; + } + } + // Push last byte if needed + if ( bitPos != 0 ) + Vec_StrPush( vConfigs2, (char)mappingByte ); + // Write truth tables for the two LUT4s only (MUX is structural, not a LUT) + word Truth1 = z & 0xFFFF; + word Truth2 = (z >> 16) & 0xFFFF; + Vec_StrPush( vConfigs2, (char)(Truth1 & 0xFF) ); + Vec_StrPush( vConfigs2, (char)((Truth1 >> 8) & 0xFF) ); + Vec_StrPush( vConfigs2, (char)(Truth2 & 0xFF) ); + Vec_StrPush( vConfigs2, (char)((Truth2 >> 8) & 0xFF) ); + // Pad to 4-byte boundary + while ( (Vec_StrSize(vConfigs2) - startPos) % 4 != 0 ) + Vec_StrPush( vConfigs2, 0 ); + } + } +} int Gia_ManFromIfLogicFindCell( If_Man_t * pIfMan, Gia_Man_t * pNew, Gia_Man_t * pTemp, If_Cut_t * pCutBest, Ifn_Ntk_t * pNtkCell, int nLutMax, Vec_Int_t * vLeaves, Vec_Int_t * vLits, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vConfigs ) { int iLit; @@ -2109,14 +2339,15 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan ) If_Cut_t * pCutBest; If_Obj_t * pIfObj, * pIfLeaf; Vec_Int_t * vMapping, * vMapping2, * vPacking = NULL, * vConfigs = NULL; + Vec_Str_t * vConfigs2 = NULL; Vec_Int_t * vLeaves, * vLeaves2, * vCover, * vLits; Vec_Str_t * vConfigsStr = NULL; Ifn_Ntk_t * pNtkCell = NULL; sat_solver * pSat = NULL; int i, k, Entry; assert( !pIfMan->pPars->fDeriveLuts || pIfMan->pPars->fTruth ); -// if ( pIfMan->pPars->fEnableCheck07 ) -// pIfMan->pPars->fDeriveLuts = 0; + //if ( pIfMan->pPars->fEnableCheck07 ) + // pIfMan->pPars->fDeriveLuts = 0; // start mapping and packing vMapping = Vec_IntStart( If_ManObjNum(pIfMan) ); vMapping2 = Vec_IntStart( 1 ); @@ -2136,6 +2367,8 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan ) if ( fWriteConfigs ) vConfigsStr = Vec_StrAlloc( 1000 ); } + if ( pIfMan->pPars->fEnableCheck07 ) + vConfigs2 = Vec_StrAlloc( 1000 ); // create new manager pNew = Gia_ManStart( If_ManObjNum(pIfMan) ); // iterate through nodes used in the mapping @@ -2223,6 +2456,12 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan ) pIfObj->iCopy = Abc_LitNotCond( pIfObj->iCopy, pCutBest->fCompl ); if ( vConfigs && Vec_IntSize(vLeaves) > 1 && !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(pIfObj->iCopy))) && pIfObj->iCopy > 1 ) Gia_ManFromIfGetConfig( vConfigs, pIfMan, pCutBest, pIfObj->iCopy, vConfigsStr ); + else if ( vConfigs2 && Vec_IntSize(vLeaves) > 1 && !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(pIfObj->iCopy))) && pIfObj->iCopy > 1 ) { + assert( pCutBest->fCompl == 0 ); + //pCutBest->iCutFunc = Abc_LitNotCond( pCutBest->iCutFunc, Abc_LitIsCompl(pIfObj->iCopy) ); + Gia_ManFromIfGetConfig2( vConfigs2, pIfMan, pCutBest ); + //pCutBest->iCutFunc = Abc_LitNotCond( pCutBest->iCutFunc, Abc_LitIsCompl(pIfObj->iCopy) ); + } } else { @@ -2235,6 +2474,8 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan ) Vec_IntForEachEntry( vLeaves, Entry, k ) Vec_IntPush( vMapping2, Abc_Lit2Var(Entry) ); Vec_IntPush( vMapping2, Abc_Lit2Var(pIfObj->iCopy) ); + //if ( pIfMan->pPars->fEnableCheck07 && vConfigs2 && Vec_IntSize(vLeaves) > 1 ) + // Gia_ManFromIfGetConfig2( vConfigs2, pIfMan, pCutBest ); } } else if ( If_ObjIsCi(pIfObj) ) @@ -2279,11 +2520,14 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan ) assert( pNew->vPacking == NULL ); assert( pNew->vConfigs == NULL ); assert( pNew->pCellStr == NULL ); + assert( pNew->vConfigs2== NULL ); pNew->vMapping = vMapping; pNew->vPacking = vPacking; pNew->vConfigs = vConfigs; pNew->pCellStr = vConfigs ? Abc_UtilStrsav( If_DsdManGetCellStr(pIfMan->pIfDsdMan) ) : NULL; - assert( !vConfigs || Vec_IntSize(vConfigs) == 2 + Vec_IntEntry(vConfigs, 0) * Vec_IntEntry(vConfigs, 1) ); + pNew->vConfigs2= vConfigs2; + assert( !vConfigs || Vec_IntSize(vConfigs) == 2 + Vec_IntEntry(vConfigs, 0) * Vec_IntEntry(vConfigs, 1) ); + // vConfigs2 is now a byte vector, no fixed size relationship // verify that COs have mapping { Gia_Obj_t * pObj; @@ -2503,6 +2747,10 @@ void Gia_ManTransferTiming( Gia_Man_t * p, Gia_Man_t * pGia ) p->vConfigs = pGia->vConfigs; pGia->vConfigs = NULL; p->pCellStr = pGia->pCellStr; pGia->pCellStr = NULL; } + if ( pGia->vConfigs2 ) + { + p->vConfigs2 = pGia->vConfigs2; pGia->vConfigs2 = NULL; + } if ( pGia->pManTime == NULL ) return; p->pManTime = pGia->pManTime; pGia->pManTime = NULL; @@ -2628,6 +2876,7 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars ) */ ABC_FREE( p->pCellStr ); Vec_IntFreeP( &p->vConfigs ); + Vec_StrFreeP( &p->vConfigs2 ); // disable cut minimization when GIA strucure is needed if ( !pPars->fDelayOpt && !pPars->fDelayOptLut && !pPars->fDsdBalance && !pPars->fUserRecLib && !pPars->fUserSesLib && !pPars->fDeriveLuts && !pPars->fUseDsd && !pPars->fUseTtPerm && !pPars->pFuncCell2 ) pPars->fCutMin = 0; diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index efedcfb0a..72ec211ef 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -142,6 +142,7 @@ void Gia_ManStop( Gia_Man_t * p ) Vec_IntFreeP( &p->vCellMapping ); Vec_IntFreeP( &p->vPacking ); Vec_IntFreeP( &p->vConfigs ); + Vec_StrFreeP( &p->vConfigs2 ); ABC_FREE( p->pCellStr ); Vec_FltFreeP( &p->vInArrs ); Vec_FltFreeP( &p->vOutReqs ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 56993e208..2787c0a82 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -35644,6 +35644,8 @@ int Abc_CommandAbc9Strash( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManTransferPacking( pTemp, pAbc->pGia ); Gia_ManTransferTiming( pTemp, pAbc->pGia ); } + else if ( Gia_ManHasMapping(pAbc->pGia) && pAbc->pGia->vConfigs2 ) + pTemp = (Gia_Man_t *)If_ManDeriveGiaFromCells2( pAbc->pGia ); else if ( Gia_ManHasMapping(pAbc->pGia) && pAbc->pGia->vConfigs ) pTemp = (Gia_Man_t *)If_ManDeriveGiaFromCells( pAbc->pGia ); else if ( Gia_ManHasMapping(pAbc->pGia) ) @@ -35692,6 +35694,7 @@ int Abc_CommandAbc9Strash( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManTransferTiming( pTemp, pAbc->pGia ); pAbc->pGia->vConfigs = pTemp->vConfigs; pTemp->vConfigs = NULL; pAbc->pGia->pCellStr = pTemp->pCellStr; pTemp->pCellStr = NULL; + pAbc->pGia->vConfigs2= pTemp->vConfigs2; pTemp->vConfigs2= NULL; } Abc_FrameUpdateGia( pAbc, pTemp ); return 0; diff --git a/src/map/if/ifTune.c b/src/map/if/ifTune.c index 9195fc8e0..47d90b4fd 100644 --- a/src/map/if/ifTune.c +++ b/src/map/if/ifTune.c @@ -892,6 +892,342 @@ void * If_ManDeriveGiaFromCells( void * pGia ) } +/**Function************************************************************* + + Synopsis [Print cell configuration data.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void If_ManConfigPrint( unsigned char * pConfigData, int nLeaves ) +{ + unsigned char CellId = pConfigData[0]; + int i; + static int Count = 0; + printf( "[%4d] ", Count++ ); // Print instance number + if ( CellId == 0 ) + { + // Extract 16-bit truth table + word Truth = ((word)pConfigData[2] << 8) | pConfigData[1]; + printf( "%04lX{", (unsigned long)Truth ); + // Print as simple {abcd} since it's just a direct LUT4 + for ( i = 0; i < nLeaves && i < 4; i++ ) + printf( "%c", 'a' + i ); + printf( "}" ); + // Pad with spaces if less than 4 inputs + for ( i = nLeaves; i < 4; i++ ) + printf( " " ); + printf( " [Cell %d, %d leaves]\n", CellId, nLeaves ); + } + else if ( CellId == 1 ) + { + // First LUT4 + word Truth1 = ((word)pConfigData[6] << 8) | pConfigData[5]; + printf( "h=%04lX{", (unsigned long)Truth1 ); + for ( i = 0; i < 4; i++ ) + { + int v = (pConfigData[1 + i/2] >> ((i%2) * 4)) & 0xF; + if ( v == 0 ) + printf( "0"); + else if ( v == 1 ) + printf( "1"); + else if ( v >= 2 && v < 2 + nLeaves ) + printf( "%c", 'a' + (v-2)); + else + printf( "?"); + } + printf( "} "); + // Second LUT4 + word Truth2 = ((word)pConfigData[8] << 8) | pConfigData[7]; + printf( "i=%04lX{", (unsigned long)Truth2 ); + for ( i = 0; i < 4; i++ ) + { + int v = (pConfigData[3 + i/2] >> ((i%2) * 4)) & 0xF; + if ( v == 0 ) + printf( "0"); + else if ( v == 1 ) + printf( "1"); + else if ( v >= 2 && v < 2 + nLeaves ) + printf( "%c", 'a' + (v-2)); + else if ( v == 9 ) + printf( "h"); // Output of first LUT + else + printf( "?"); + } + printf( "} [Cell %d, %d leaves]\n", CellId, nLeaves ); + } + else if ( CellId == 2 ) + { + // Extract 9 input mappings + int inputs[9]; + int bitPos = 0; + for ( i = 0; i < 9; i++ ) + { + if ( bitPos == 0 ) + { + inputs[i] = pConfigData[1 + i/2] & 0xF; + bitPos = 4; + } + else + { + inputs[i] = (pConfigData[1 + i/2] >> 4) & 0xF; + bitPos = 0; + } + } + // First LUT4 + word Truth1 = ((word)pConfigData[7] << 8) | pConfigData[6]; + printf( "j=%04lX{", (unsigned long)Truth1 ); + for ( i = 0; i < 4; i++ ) + { + int v = inputs[i]; + if ( v == 0 ) + printf( "0"); + else if ( v == 1 ) + printf( "1"); + else if ( v >= 2 && v < 2 + nLeaves ) + printf( "%c", 'a' + (v-2)); + else + printf( "?"); + } + printf( "} "); + // Second LUT4 + word Truth2 = ((word)pConfigData[9] << 8) | pConfigData[8]; + printf( "k=%04lX{", (unsigned long)Truth2 ); + for ( i = 4; i < 8; i++ ) + { + int v = inputs[i]; + if ( v == 0 ) + printf( "0"); + else if ( v == 1 ) + printf( "1"); + else if ( v >= 2 && v < 2 + nLeaves ) + printf( "%c", 'a' + (v-2)); + else + printf( "?"); + } + printf( "} "); + // final node + printf( "l=<"); + int v = inputs[8]; + if ( v == 0 ) + printf( "0"); + else if ( v == 1 ) + printf( "1"); + else if ( v >= 2 && v < 2 + nLeaves ) + printf( "%c", 'a' + (v-2)); + else + printf( "?"); + printf( "jk> [Cell %d, %d leaves]\n", CellId, nLeaves ); + } + else + { + printf( "Unknown cell type %d!\n", CellId ); + } +} + +/**Function************************************************************* + + Synopsis [Derive GIA using programmable bits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * If_ManDeriveGiaFromCells2( void * pGia ) +{ + Gia_Man_t * p = (Gia_Man_t *)pGia; + Gia_Man_t * pNew, * pTemp; + Vec_Int_t * vCover, * vLeaves; + Gia_Obj_t * pObj; + unsigned char * pConfigData; + int k, i, iLut, iVar; + int Count = 0; + assert( p->vConfigs2 != NULL ); + assert( Gia_ManHasMapping(p) ); + // create new manager + pNew = Gia_ManStart( 6*Gia_ManObjNum(p)/5 + 100 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + // map primary inputs + Gia_ManFillValue(p); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + // iterate through nodes used in the mapping + vLeaves = Vec_IntAlloc( 16 ); + vCover = Vec_IntAlloc( 1 << 16 ); + Gia_ManHashStart( pNew ); + // Process each mapped node + int bytePos = 0; + Gia_ManForEachAnd( p, pObj, iLut ) + { + if ( Gia_ObjIsBuf(pObj) ) + { + pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); + continue; + } + if ( !Gia_ObjIsLut(p, iLut) ) + continue; + + // collect incoming literals + Vec_IntClear( vLeaves ); + Gia_LutForEachFanin( p, iLut, iVar, k ) + Vec_IntPush( vLeaves, Gia_ManObj(p, iVar)->Value ); + // Get configuration data for this instance + pConfigData = (unsigned char *)Vec_StrEntryP( p->vConfigs2, bytePos ); + //If_ManConfigPrint( pConfigData, Vec_IntSize(vLeaves) ); + unsigned char CellId = pConfigData[0]; + if ( CellId == 0 ) + { + // Extract 16-bit truth table + word Truth = ((word)pConfigData[2] << 8) | pConfigData[1]; + Truth = Abc_Tt6Stretch( Truth, 4 ); + extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); + Gia_ManObj(p, iLut)->Value = Kit_TruthToGia( pNew, (unsigned *)&Truth, Vec_IntSize(vLeaves), vCover, vLeaves, 1 ); + bytePos += 4; // 1 byte CellId + 2 bytes truth table + 1 padding + } + else if ( CellId == 1 ) + { + Vec_Int_t * vLeavesTemp = Vec_IntAlloc( 4 ); + int iObjLit1, iObjLit2; + // First LUT4 - extract inputs and truth table + Vec_IntClear( vLeavesTemp ); + for ( i = 0; i < 4; i++ ) + { + int v = (pConfigData[1 + i/2] >> ((i%2) * 4)) & 0xF; + if ( v == 0 ) + Vec_IntPush( vLeavesTemp, 0 ); // constant 0 + else if ( v == 1 ) + Vec_IntPush( vLeavesTemp, 1 ); // constant 1 + else if ( v >= 2 && v < 2 + Vec_IntSize(vLeaves) ) + Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v - 2) ); // leaf (v-2) + else + assert( 0 ); // Invalid value + } + word Truth1 = ((word)pConfigData[6] << 8) | pConfigData[5]; + Truth1 = Abc_Tt6Stretch( Truth1, 4 ); + extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); + iObjLit1 = Kit_TruthToGia( pNew, (unsigned *)&Truth1, Vec_IntSize(vLeavesTemp), vCover, vLeavesTemp, 1 ); + // Second LUT4 - extract inputs and truth table + Vec_IntClear( vLeavesTemp ); + for ( i = 0; i < 4; i++ ) + { + int v = (pConfigData[3 + i/2] >> ((i%2) * 4)) & 0xF; + if ( v == 0 ) + Vec_IntPush( vLeavesTemp, 0 ); // constant 0 + else if ( v == 1 ) + Vec_IntPush( vLeavesTemp, 1 ); // constant 1 + else if ( v >= 2 && v < 2 + Vec_IntSize(vLeaves) ) + Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v - 2) ); // leaf (v-2) + else if ( v == 9 ) // N+2 where N=7 (number of S44 inputs) + Vec_IntPush( vLeavesTemp, iObjLit1 ); // output of first LUT (internal connection) + else + assert( 0 ); // Invalid value + } + word Truth2 = ((word)pConfigData[8] << 8) | pConfigData[7]; + Truth2 = Abc_Tt6Stretch( Truth2, 4 ); + iObjLit2 = Kit_TruthToGia( pNew, (unsigned *)&Truth2, Vec_IntSize(vLeavesTemp), vCover, vLeavesTemp, 1 ); + Gia_ManObj(p, iLut)->Value = iObjLit2; + Vec_IntFree( vLeavesTemp ); + bytePos += 12; // 1 byte CellId + 4 bytes mapping + 4 bytes truth tables + 3 padding + } + else if ( CellId == 2 ) + { + Vec_Int_t * vLeavesTemp = Vec_IntAlloc( 4 ); + int iObjLit1, iObjLit2, iObjLit3; + // Extract 9 input mappings (4 bits each, packed) + int inputs[9]; + int bitPos = 0; + for ( i = 0; i < 9; i++ ) + { + if ( bitPos == 0 ) + { + inputs[i] = pConfigData[1 + i/2] & 0xF; + bitPos = 4; + } + else + { + inputs[i] = (pConfigData[1 + i/2] >> 4) & 0xF; + bitPos = 0; + } + } + // First LUT4 (inputs 0-3) + Vec_IntClear( vLeavesTemp ); + for ( i = 0; i < 4; i++ ) + { + int v = inputs[i]; + if ( v == 0 ) + Vec_IntPush( vLeavesTemp, 0 ); // constant 0 + else if ( v == 1 ) + Vec_IntPush( vLeavesTemp, 1 ); // constant 1 + else if ( v >= 2 && v < 2 + Vec_IntSize(vLeaves) ) + Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v - 2) ); // leaf (v-2) + else + assert( 0 ); // Invalid value + } + word Truth1 = ((word)pConfigData[7] << 8) | pConfigData[6]; + Truth1 = Abc_Tt6Stretch( Truth1, 4 ); + extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); + iObjLit1 = Kit_TruthToGia( pNew, (unsigned *)&Truth1, Vec_IntSize(vLeavesTemp), vCover, vLeavesTemp, 1 ); + // Second LUT4 (inputs 4-7) + Vec_IntClear( vLeavesTemp ); + for ( i = 4; i < 8; i++ ) + { + int v = inputs[i]; + if ( v == 0 ) + Vec_IntPush( vLeavesTemp, 0 ); // constant 0 + else if ( v == 1 ) + Vec_IntPush( vLeavesTemp, 1 ); // constant 1 + else if ( v >= 2 && v < 2 + Vec_IntSize(vLeaves) ) + Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v - 2) ); // leaf (v-2) + else + assert( 0 ); // Invalid value + } + word Truth2 = ((word)pConfigData[9] << 8) | pConfigData[8]; + Truth2 = Abc_Tt6Stretch( Truth2, 4 ); + iObjLit2 = Kit_TruthToGia( pNew, (unsigned *)&Truth2, Vec_IntSize(vLeavesTemp), vCover, vLeavesTemp, 1 ); + // MUX (select is input 8) - structural implementation + int iSelectLit; + int v = inputs[8]; + if ( v == 0 ) + iSelectLit = 0; // constant 0 select + else if ( v == 1 ) + iSelectLit = 1; // constant 1 select (unlikely for select) + else if ( v >= 2 && v < 2 + Vec_IntSize(vLeaves) ) + iSelectLit = Vec_IntEntry(vLeaves, v - 2); // select from leaf (v-2) + else + assert( 0 ); // Invalid value + iObjLit3 = Gia_ManHashMux( pNew, iSelectLit, iObjLit2, iObjLit1 ); + Gia_ManObj(p, iLut)->Value = iObjLit3; + Vec_IntFree( vLeavesTemp ); + bytePos += 12; // 1 byte CellId + 5 bytes mapping + 4 bytes truth tables + 2 padding + } + else + { + assert( 0 ); // Unknown cell type + } + Count++; + } + + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Vec_IntFree( vLeaves ); + Vec_IntFree( vCover ); + // perform cleanup + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + /**Function************************************************************* Synopsis [Derive truth table given the configulation values.]