Supporting programmable cell libraries.

This commit is contained in:
Alan Mishchenko 2025-11-01 01:23:30 -07:00
parent a9d62d845d
commit 7c6b779327
6 changed files with 398 additions and 0 deletions

View File

@ -100,6 +100,7 @@ extern ABC_DLL Vec_Ptr_t * Abc_FrameReadStore();
extern ABC_DLL int Abc_FrameReadStoreSize();
extern ABC_DLL void * Abc_FrameReadLibLut();
extern ABC_DLL void * Abc_FrameReadLibLutI( int i );
extern ABC_DLL void * Abc_FrameReadLibCell();
extern ABC_DLL void * Abc_FrameReadLibBox();
extern ABC_DLL void * Abc_FrameReadLibGen();
extern ABC_DLL void * Abc_FrameReadLibGen2();
@ -139,6 +140,7 @@ extern ABC_DLL void Abc_FrameSetNtkStore( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_FrameSetNtkStoreSize( int nStored );
extern ABC_DLL void Abc_FrameSetLibLut( void * pLib );
extern ABC_DLL void Abc_FrameSetLibLutI( void * pLib, int i );
extern ABC_DLL void Abc_FrameSetLibCell( void * pLib );
extern ABC_DLL void Abc_FrameSetLibBox( void * pLib );
extern ABC_DLL void Abc_FrameSetLibGen( void * pLib );
extern ABC_DLL void Abc_FrameSetLibGen2( void * pLib );

View File

@ -56,6 +56,7 @@ Vec_Ptr_t * Abc_FrameReadStore() { return s_GlobalFr
int Abc_FrameReadStoreSize() { return Vec_PtrSize(s_GlobalFrame->vStore); }
void * Abc_FrameReadLibLut() { return s_GlobalFrame->pLibLut[0]; }
void * Abc_FrameReadLibLutI( int i ) { return s_GlobalFrame->pLibLut[i]; }
void * Abc_FrameReadLibCell() { return s_GlobalFrame->pLibCell; }
void * Abc_FrameReadLibBox() { return s_GlobalFrame->pLibBox; }
void * Abc_FrameReadLibGen() { return s_GlobalFrame->pLibGen; }
void * Abc_FrameReadLibGen2() { return s_GlobalFrame->pLibGen2; }
@ -93,6 +94,7 @@ int * Abc_FrameOutputNdrArray( Abc_Frame_t * pAbc ) { int * pArray = s_
void Abc_FrameSetLibLut( void * pLib ) { s_GlobalFrame->pLibLut[0]= pLib; }
void Abc_FrameSetLibLutI( void * pLib, int i ) { s_GlobalFrame->pLibLut[i]= pLib; }
void Abc_FrameSetLibCell( void * pLib ) { s_GlobalFrame->pLibCell = pLib; }
void Abc_FrameSetLibBox( void * pLib ) { s_GlobalFrame->pLibBox = pLib; }
void Abc_FrameSetLibGen( void * pLib ) { s_GlobalFrame->pLibGen = pLib; }
void Abc_FrameSetLibGen2( void * pLib ) { s_GlobalFrame->pLibGen2 = pLib; }

View File

@ -99,6 +99,7 @@ struct Abc_Frame_t_
void * pManDsd2; // decomposition manager
// libraries for mapping
void * pLibLut[ABC_LUT_LIBS]; // the current LUT library
void * pLibCell; // the current cell library
void * pLibBox; // the current box library
void * pLibGen; // the current genlib
void * pLibGen2; // the current genlib

View File

@ -80,6 +80,7 @@ typedef struct If_Obj_t_ If_Obj_t;
typedef struct If_Cut_t_ If_Cut_t;
typedef struct If_Set_t_ If_Set_t;
typedef struct If_LibLut_t_ If_LibLut_t;
typedef struct If_LibCell_t_ If_LibCell_t;
typedef struct If_LibBox_t_ If_LibBox_t;
typedef struct If_DsdMan_t_ If_DsdMan_t;
typedef struct Ifn_Ntk_t_ Ifn_Ntk_t;
@ -194,6 +195,17 @@ struct If_LibLut_t_
float pLutDelays[IF_MAX_LUTSIZE+1][IF_MAX_LUTSIZE+1];// the delays of LUTs
};
// the cell library
struct If_LibCell_t_
{
char * pName; // the name of the LUT library
int nCellNum; // the number of cells in the library
int nCellInputs[IF_MAX_LUTSIZE];
char * pCellNames[IF_MAX_LUTSIZE];
float pCellAreas[IF_MAX_LUTSIZE];
int pCellPinDelays[IF_MAX_LUTSIZE][IF_MAX_LUTSIZE];
};
// manager
struct If_Man_t_
{
@ -626,6 +638,10 @@ extern int If_LibLutDelaysAreDifferent( If_LibLut_t * pLutLib );
extern If_LibLut_t * If_LibLutSetSimple( int nLutSize );
extern float If_LibLutFastestPinDelay( If_LibLut_t * p );
extern float If_LibLutSlowestPinDelay( If_LibLut_t * p );
extern If_LibCell_t * If_LibCellRead( char * FileName );
extern If_LibCell_t * If_LibCellDup( If_LibCell_t * p );
extern void If_LibCellFree( If_LibCell_t * pCellLib );
extern void If_LibCellPrint( If_LibCell_t * pCellLib );
/*=== ifLibBox.c =============================================================*/
extern If_LibBox_t * If_LibBoxStart();
extern void If_LibBoxFree( If_LibBox_t * p );
@ -692,6 +708,7 @@ extern void * If_ManSatBuildFromCell( char * pStr, Vec_Int_t ** pvPiVar
extern int If_ManSatFindCofigBits( void * pSat, Vec_Int_t * vPiVars, Vec_Int_t * vPoVars, word * pTruth, int nVars, word Perm, int nInps, Vec_Int_t * vValues );
extern int If_ManSatDeriveGiaFromBits( void * pNew, Ifn_Ntk_t * p, word * pTtData, Vec_Int_t * vLeaves, Vec_Int_t * vValues );
extern void * If_ManDeriveGiaFromCells( void * p );
extern void * If_ManDeriveGiaFromCells2( void * p );
/*=== ifUtil.c ============================================================*/
extern void If_ManCleanNodeCopy( If_Man_t * p );
extern void If_ManCleanCutData( If_Man_t * p );

View File

@ -30,6 +30,8 @@ ABC_NAMESPACE_IMPL_START
static int If_CommandReadLut ( Abc_Frame_t * pAbc, int argc, char **argv );
static int If_CommandPrintLut( Abc_Frame_t * pAbc, int argc, char **argv );
static int If_CommandReadCell( Abc_Frame_t * pAbc, int argc, char **argv );
static int If_CommandPrintCell( Abc_Frame_t * pAbc, int argc, char **argv );
static int If_CommandReadBox ( Abc_Frame_t * pAbc, int argc, char **argv );
static int If_CommandPrintBox( Abc_Frame_t * pAbc, int argc, char **argv );
static int If_CommandWriteBox( Abc_Frame_t * pAbc, int argc, char **argv );
@ -59,6 +61,9 @@ void If_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "FPGA mapping", "read_lut", If_CommandReadLut, 0 );
Cmd_CommandAdd( pAbc, "FPGA mapping", "print_lut", If_CommandPrintLut, 0 );
Cmd_CommandAdd( pAbc, "FPGA mapping", "read_cell", If_CommandReadCell, 0 );
Cmd_CommandAdd( pAbc, "FPGA mapping", "print_cell", If_CommandPrintCell, 0 );
Cmd_CommandAdd( pAbc, "FPGA mapping", "read_box", If_CommandReadBox, 0 );
Cmd_CommandAdd( pAbc, "FPGA mapping", "print_box", If_CommandPrintBox, 0 );
Cmd_CommandAdd( pAbc, "FPGA mapping", "write_box", If_CommandWriteBox, 0 );
@ -248,6 +253,143 @@ usage:
return 1; /* error exit */
}
/**Function*************************************************************
Synopsis [Command procedure to read LUT libraries.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int If_CommandReadCell( Abc_Frame_t * pAbc, int argc, char **argv )
{
FILE * pFile;
FILE * pOut, * pErr;
If_LibCell_t * pLib;
Abc_Ntk_t * pNet;
char * FileName;
int fVerbose;
int c;
pNet = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set the defaults
fVerbose = 1;
Extra_UtilGetoptReset();
while ( (c = Extra_UtilGetopt(argc, argv, "vh")) != EOF )
{
switch (c)
{
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
break;
default:
goto usage;
}
}
if ( argc == globalUtilOptind ) {
fprintf( pErr, "The library file should be specified in the command line.\n" );
goto usage;
}
// remove current libraries
If_LibCellFree( (If_LibCell_t *)Abc_FrameReadLibCell() );
Abc_FrameSetLibCell( NULL );
// get the input file name
FileName = argv[globalUtilOptind];
if ( (pFile = fopen( FileName, "r" )) == NULL )
{
fprintf( pErr, "Cannot open input file \"%s\". ", FileName );
if ( (FileName = Extra_FileGetSimilarName( FileName, ".genlib", ".lib", ".gen", ".g", NULL )) )
fprintf( pErr, "Did you mean \"%s\"?", FileName );
fprintf( pErr, "\n" );
return 1;
}
fclose( pFile );
// set the new network
pLib = If_LibCellRead( FileName );
if ( pLib == NULL )
{
fprintf( pErr, "Reading LUT library has failed.\n" );
goto usage;
}
// replace the current library
Abc_FrameSetLibCell( pLib );
return 0;
usage:
fprintf( pErr, "\nusage: read_cell [-vh] <file>\n");
fprintf( pErr, "\t read the cell library from the file\n" );
fprintf( pErr, "\t-v : toggles enabling of verbose output [default = %s]\n", (fVerbose? "yes" : "no") );
fprintf( pErr, "\t-h : print the command usage\n");
return 1; /* error exit */
}
/**Function*************************************************************
Synopsis [Command procedure to read cell libraries.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int If_CommandPrintCell( Abc_Frame_t * pAbc, int argc, char **argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNet;
int fVerbose;
int c;
pNet = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set the defaults
fVerbose = 1;
Extra_UtilGetoptReset();
while ( (c = Extra_UtilGetopt(argc, argv, "vh")) != EOF )
{
switch (c)
{
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
break;
default:
goto usage;
}
}
if ( argc != globalUtilOptind )
goto usage;
// set the new network
If_LibCellPrint( (If_LibCell_t *)Abc_FrameReadLibCell() );
return 0;
usage:
fprintf( pErr, "\nusage: print_cell [-vh]\n");
fprintf( pErr, "\t print the current cell library\n" );
fprintf( pErr, "\t-v : toggles enabling of verbose output [default = %s]\n", (fVerbose? "yes" : "no") );
fprintf( pErr, "\t-h : print the command usage\n");
return 1; /* error exit */
}
/**Function*************************************************************
Synopsis []

View File

@ -369,6 +369,240 @@ void If_LibLutPrint( If_LibLut_t * pLutLib )
Abc_Print( 1, "%d %7.2f %7.2f\n", i, pLutLib->pLutAreas[i], pLutLib->pLutDelays[i][0] );
}
/**Function*************************************************************
Synopsis [Allocates the cell library structure.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
If_LibCell_t * If_LibCellAlloc( void )
{
If_LibCell_t * p;
p = ABC_ALLOC( If_LibCell_t, 1 );
memset( p, 0, sizeof(If_LibCell_t) );
return p;
}
/**Function*************************************************************
Synopsis [Reads the description of cells from the cell library file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
If_LibCell_t * If_LibCellRead( char * FileName )
{
char pBuffer[1000], * pToken;
If_LibCell_t * p;
FILE * pFile;
int i, k;
int CellId;
char * FuncDesc;
pFile = fopen( FileName, "r" );
if ( pFile == NULL )
{
Abc_Print( -1, "Cannot open cell library file \"%s\".\n", FileName );
return NULL;
}
p = If_LibCellAlloc();
p->pName = Abc_UtilStrsav( FileName );
p->nCellNum = 0;
// Read each line of the file
while ( fgets( pBuffer, 1000, pFile ) != NULL )
{
pToken = strtok( pBuffer, " \t\n" );
if ( pToken == NULL )
continue;
if ( pToken[0] == '#' )
continue;
// Read CellId
CellId = atoi(pToken);
if ( CellId < 0 || CellId >= IF_MAX_LUTSIZE )
{
Abc_Print( -1, "Cell ID %d is out of bounds (0-%d).\n", CellId, IF_MAX_LUTSIZE-1 );
If_LibCellFree( p );
fclose( pFile );
return NULL;
}
// Read FuncDesc
pToken = strtok( NULL, " \t\n" );
if ( pToken == NULL )
{
Abc_Print( -1, "Missing function description for cell %d.\n", CellId );
If_LibCellFree( p );
fclose( pFile );
return NULL;
}
FuncDesc = Abc_UtilStrsav( pToken );
p->pCellNames[CellId] = FuncDesc;
// Determine number of inputs from function description
int nInputs = 0;
if ( FuncDesc[0] >= 'a' && FuncDesc[0] <= 'z' )
{
// If it begins with a letter, that letter indicates the output
// and the number of inputs is that letter - 'a'
nInputs = FuncDesc[0] - 'a';
}
else
{
// Otherwise, find the largest letter in the formula
char maxChar = 'a' - 1;
for ( i = 0; FuncDesc[i]; i++ )
{
if ( FuncDesc[i] >= 'a' && FuncDesc[i] <= 'z' && FuncDesc[i] > maxChar )
maxChar = FuncDesc[i];
}
if ( maxChar >= 'a' )
nInputs = maxChar - 'a' + 1;
}
p->nCellInputs[CellId] = nInputs;
// Read Area
pToken = strtok( NULL, " \t\n" );
if ( pToken == NULL )
{
Abc_Print( -1, "Missing area for cell %d.\n", CellId );
If_LibCellFree( p );
fclose( pFile );
return NULL;
}
p->pCellAreas[CellId] = (float)atof(pToken);
// Read all available delays
k = 0;
while ( (pToken = strtok( NULL, " \t\n" )) != NULL && k < IF_MAX_LUTSIZE )
{
p->pCellPinDelays[CellId][k] = atoi(pToken);
k++;
}
// Check if number of delays matches number of inputs
if ( k != nInputs )
{
Abc_Print( 0, "Warning: Cell %d has %d inputs but %d delays specified.\n", CellId, nInputs, k );
}
p->nCellNum++;
}
fclose( pFile );
// Validate the library
for ( i = 0; i < IF_MAX_LUTSIZE; i++ )
{
if ( p->pCellNames[i] == NULL )
continue;
for ( k = 0; k < IF_MAX_LUTSIZE && p->pCellPinDelays[i][k] > 0; k++ )
{
if ( p->pCellPinDelays[i][k] < 0 )
{
Abc_Print( 0, "Pin %d of cell %d has delay %d. Pin delays should be non-negative. Technology mapping may not work correctly.\n",
k, i, p->pCellPinDelays[i][k] );
}
}
}
return p;
}
/**Function*************************************************************
Synopsis [Duplicates the cell library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
If_LibCell_t * If_LibCellDup( If_LibCell_t * p )
{
If_LibCell_t * pNew;
int i;
pNew = ABC_ALLOC( If_LibCell_t, 1 );
*pNew = *p;
pNew->pName = Abc_UtilStrsav( p->pName );
for ( i = 0; i < IF_MAX_LUTSIZE; i++ )
if ( p->pCellNames[i] )
pNew->pCellNames[i] = Abc_UtilStrsav( p->pCellNames[i] );
return pNew;
}
/**Function*************************************************************
Synopsis [Frees the cell library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void If_LibCellFree( If_LibCell_t * pCellLib )
{
int i;
if ( pCellLib == NULL )
return;
ABC_FREE( pCellLib->pName );
for ( i = 0; i < IF_MAX_LUTSIZE; i++ )
ABC_FREE( pCellLib->pCellNames[i] );
ABC_FREE( pCellLib );
}
/**Function*************************************************************
Synopsis [Prints the cell library.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void If_LibCellPrint( If_LibCell_t * pCellLib )
{
int i, k;
if ( pCellLib == NULL )
{
Abc_Print( 1, "Cell library is not available.\n" );
return;
}
Abc_Print( 1, "# Cell library: %s\n", pCellLib->pName ? pCellLib->pName : "Unknown" );
Abc_Print( 1, "# Number of cells: %d\n", pCellLib->nCellNum );
Abc_Print( 1, "# CellId Inputs Cell Description Area Delays\n" );
for ( i = 0; i < IF_MAX_LUTSIZE; i++ )
{
if ( pCellLib->pCellNames[i] == NULL )
continue;
Abc_Print( 1, "%3d %6d %-32s %6.2f ", i, pCellLib->nCellInputs[i], pCellLib->pCellNames[i], pCellLib->pCellAreas[i] );
// Print all non-zero delays
for ( k = 0; k < IF_MAX_LUTSIZE && pCellLib->pCellPinDelays[i][k] > 0; k++ )
Abc_Print( 1, " %4d", pCellLib->pCellPinDelays[i][k] );
Abc_Print( 1, "\n" );
}
}
/**Function*************************************************************
Synopsis [Returns 1 if the delays are discrete.]