Experiments with LUT mapping.

This commit is contained in:
Alan Mishchenko 2025-11-01 01:21:37 -07:00
parent 6034f6621b
commit a9d62d845d
7 changed files with 716 additions and 11 deletions

View File

@ -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

View File

@ -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) )
{

View File

@ -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

View File

@ -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;

View File

@ -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 );

View File

@ -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;

View File

@ -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.]