mirror of https://github.com/YosysHQ/abc.git
Supporting programmable cell libraries.
This commit is contained in:
parent
a9d62d845d
commit
7c6b779327
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 []
|
||||
|
|
|
|||
|
|
@ -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.]
|
||||
|
|
|
|||
Loading…
Reference in New Issue