mirror of https://github.com/YosysHQ/abc.git
796 lines
22 KiB
C
796 lines
22 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [ifLibLut.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [FPGA mapping based on priority cuts.]
|
|
|
|
Synopsis [LUT library.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - November 21, 2006.]
|
|
|
|
Revision [$Id: ifLibLut.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "if.h"
|
|
#include "base/main/mainInt.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Reads the description of LUTs from the LUT library file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
If_LibLut_t * If_LibLutReadString( char * pStr )
|
|
{
|
|
If_LibLut_t * p;
|
|
Vec_Ptr_t * vStrs;
|
|
char * pToken, * pBuffer, * pStrNew, * pStrMem;
|
|
int i, k, j;
|
|
|
|
if ( pStr == NULL || pStr[0] == 0 )
|
|
return NULL;
|
|
|
|
vStrs = Vec_PtrAlloc( 1000 );
|
|
pStrNew = pStrMem = Abc_UtilStrsav( pStr );
|
|
while ( *pStrNew )
|
|
{
|
|
Vec_PtrPush( vStrs, pStrNew );
|
|
while ( *pStrNew != '\n' )
|
|
pStrNew++;
|
|
while ( *pStrNew == '\n' )
|
|
*pStrNew++ = '\0';
|
|
}
|
|
|
|
p = ABC_ALLOC( If_LibLut_t, 1 );
|
|
memset( p, 0, sizeof(If_LibLut_t) );
|
|
|
|
i = 1;
|
|
//while ( fgets( pBuffer, 1000, pFile ) != NULL )
|
|
Vec_PtrForEachEntry( char *, vStrs, pBuffer, j )
|
|
{
|
|
if ( pBuffer[0] == 0 )
|
|
continue;
|
|
pToken = strtok( pBuffer, " \t\n" );
|
|
if ( pToken == NULL )
|
|
continue;
|
|
if ( pToken[0] == '#' )
|
|
continue;
|
|
if ( i != atoi(pToken) )
|
|
{
|
|
Abc_Print( 1, "Error in the LUT library string.\n" );
|
|
ABC_FREE( p->pName );
|
|
ABC_FREE( p );
|
|
ABC_FREE( pStrMem );
|
|
Vec_PtrFree( vStrs );
|
|
return NULL;
|
|
}
|
|
|
|
// read area
|
|
pToken = strtok( NULL, " \t\n" );
|
|
p->pLutAreas[i] = (float)atof(pToken);
|
|
|
|
// read delays
|
|
k = 0;
|
|
while ( (pToken = strtok( NULL, " \t\n" )) )
|
|
p->pLutDelays[i][k++] = (float)atof(pToken);
|
|
|
|
// check for out-of-bound
|
|
if ( k > i )
|
|
{
|
|
Abc_Print( 1, "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i );
|
|
ABC_FREE( p->pName );
|
|
ABC_FREE( p );
|
|
ABC_FREE( pStrMem );
|
|
Vec_PtrFree( vStrs );
|
|
return NULL;
|
|
}
|
|
|
|
// check if var delays are specified
|
|
if ( k > 1 )
|
|
p->fVarPinDelays = 1;
|
|
|
|
if ( i == IF_MAX_LUTSIZE )
|
|
{
|
|
Abc_Print( 1, "Skipping LUTs of size more than %d.\n", i );
|
|
ABC_FREE( p->pName );
|
|
ABC_FREE( p );
|
|
ABC_FREE( pStrMem );
|
|
Vec_PtrFree( vStrs );
|
|
return NULL;
|
|
}
|
|
i++;
|
|
}
|
|
p->LutMax = i-1;
|
|
|
|
// check the library
|
|
if ( p->fVarPinDelays )
|
|
{
|
|
for ( i = 1; i <= p->LutMax; i++ )
|
|
for ( k = 0; k < i; k++ )
|
|
{
|
|
if ( p->pLutDelays[i][k] <= 0.0 )
|
|
Abc_Print( 0, "Pin %d of LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n",
|
|
k, i, p->pLutDelays[i][k] );
|
|
if ( k && p->pLutDelays[i][k-1] > p->pLutDelays[i][k] )
|
|
Abc_Print( 0, "Pin %d of LUT %d has delay %f. Pin %d of LUT %d has delay %f. Pin delays should be in non-decreasing order. Technology mapping may not work correctly.\n",
|
|
k-1, i, p->pLutDelays[i][k-1],
|
|
k, i, p->pLutDelays[i][k] );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( i = 1; i <= p->LutMax; i++ )
|
|
{
|
|
if ( p->pLutDelays[i][0] <= 0.0 )
|
|
Abc_Print( 0, "LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n",
|
|
i, p->pLutDelays[i][0] );
|
|
}
|
|
}
|
|
|
|
// cleanup
|
|
ABC_FREE( pStrMem );
|
|
Vec_PtrFree( vStrs );
|
|
return p;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Sets the library associated with the string.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Abc_FrameSetLutLibrary( Abc_Frame_t * pAbc, char * pLutLibString )
|
|
{
|
|
If_LibLut_t * pLib = If_LibLutReadString( pLutLibString );
|
|
if ( pLib == NULL )
|
|
{
|
|
fprintf( stdout, "Reading LUT library from string has failed.\n" );
|
|
return 0;
|
|
}
|
|
// replace the current library
|
|
If_LibLutFree( (If_LibLut_t *)Abc_FrameReadLibLut() );
|
|
Abc_FrameSetLibLut( pLib );
|
|
return 1;
|
|
}
|
|
int Abc_FrameSetLutLibraryTest( Abc_Frame_t * pAbc )
|
|
{
|
|
char * pStr = "1 1.00 1000\n2 1.00 1000 1200\n3 1.00 1000 1200 1400\n4 1.00 1000 1200 1400 1600\n5 1.00 1000 1200 1400 1600 1800\n6 1.00 1000 1200 1400 1600 1800 2000\n\n\n";
|
|
Abc_FrameSetLutLibrary( pAbc, pStr );
|
|
return 1;
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Reads the description of LUTs from the LUT library file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
If_LibLut_t * If_LibLutRead( char * FileName )
|
|
{
|
|
char pBuffer[1000], * pToken;
|
|
If_LibLut_t * p;
|
|
FILE * pFile;
|
|
int i, k;
|
|
|
|
pFile = fopen( FileName, "r" );
|
|
if ( pFile == NULL )
|
|
{
|
|
Abc_Print( -1, "Cannot open LUT library file \"%s\".\n", FileName );
|
|
return NULL;
|
|
}
|
|
|
|
p = ABC_ALLOC( If_LibLut_t, 1 );
|
|
memset( p, 0, sizeof(If_LibLut_t) );
|
|
p->pName = Abc_UtilStrsav( FileName );
|
|
|
|
i = 1;
|
|
while ( fgets( pBuffer, 1000, pFile ) != NULL )
|
|
{
|
|
pToken = strtok( pBuffer, " \t\n" );
|
|
if ( pToken == NULL )
|
|
continue;
|
|
if ( pToken[0] == '#' )
|
|
continue;
|
|
if ( i != atoi(pToken) )
|
|
{
|
|
Abc_Print( 1, "Error in the LUT library file \"%s\".\n", FileName );
|
|
ABC_FREE( p->pName );
|
|
ABC_FREE( p );
|
|
fclose( pFile );
|
|
return NULL;
|
|
}
|
|
|
|
// read area
|
|
pToken = strtok( NULL, " \t\n" );
|
|
p->pLutAreas[i] = (float)atof(pToken);
|
|
|
|
// read delays
|
|
k = 0;
|
|
while ( (pToken = strtok( NULL, " \t\n" )) )
|
|
p->pLutDelays[i][k++] = (float)atof(pToken);
|
|
|
|
// check for out-of-bound
|
|
if ( k > i )
|
|
{
|
|
ABC_FREE( p->pName );
|
|
ABC_FREE( p );
|
|
Abc_Print( 1, "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i );
|
|
fclose( pFile );
|
|
return NULL;
|
|
}
|
|
|
|
// check if var delays are specified
|
|
if ( k > 1 )
|
|
p->fVarPinDelays = 1;
|
|
|
|
if ( i == IF_MAX_LUTSIZE )
|
|
{
|
|
ABC_FREE( p->pName );
|
|
ABC_FREE( p );
|
|
Abc_Print( 1, "Skipping LUTs of size more than %d.\n", i );
|
|
fclose( pFile );
|
|
return NULL;
|
|
}
|
|
i++;
|
|
}
|
|
p->LutMax = i-1;
|
|
|
|
// check the library
|
|
if ( p->fVarPinDelays )
|
|
{
|
|
for ( i = 1; i <= p->LutMax; i++ )
|
|
for ( k = 0; k < i; k++ )
|
|
{
|
|
if ( p->pLutDelays[i][k] <= 0.0 )
|
|
Abc_Print( 0, "Pin %d of LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n",
|
|
k, i, p->pLutDelays[i][k] );
|
|
if ( k && p->pLutDelays[i][k-1] > p->pLutDelays[i][k] )
|
|
Abc_Print( 0, "Pin %d of LUT %d has delay %f. Pin %d of LUT %d has delay %f. Pin delays should be in non-decreasing order. Technology mapping may not work correctly.\n",
|
|
k-1, i, p->pLutDelays[i][k-1],
|
|
k, i, p->pLutDelays[i][k] );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( i = 1; i <= p->LutMax; i++ )
|
|
{
|
|
if ( p->pLutDelays[i][0] <= 0.0 )
|
|
Abc_Print( 0, "LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n",
|
|
i, p->pLutDelays[i][0] );
|
|
}
|
|
}
|
|
|
|
fclose( pFile );
|
|
return p;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Duplicates the LUT library.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
If_LibLut_t * If_LibLutDup( If_LibLut_t * p )
|
|
{
|
|
If_LibLut_t * pNew;
|
|
pNew = ABC_ALLOC( If_LibLut_t, 1 );
|
|
*pNew = *p;
|
|
pNew->pName = Abc_UtilStrsav( pNew->pName );
|
|
return pNew;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Frees the LUT library.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void If_LibLutFree( If_LibLut_t * pLutLib )
|
|
{
|
|
if ( pLutLib == NULL )
|
|
return;
|
|
ABC_FREE( pLutLib->pName );
|
|
ABC_FREE( pLutLib );
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Prints the LUT library.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void If_LibLutPrint( If_LibLut_t * pLutLib )
|
|
{
|
|
int i, k;
|
|
Abc_Print( 1, "# The area/delay of k-variable LUTs:\n" );
|
|
Abc_Print( 1, "# k area delay\n" );
|
|
if ( pLutLib->fVarPinDelays )
|
|
{
|
|
for ( i = 1; i <= pLutLib->LutMax; i++ )
|
|
{
|
|
Abc_Print( 1, "%d %7.2f ", i, pLutLib->pLutAreas[i] );
|
|
for ( k = 0; k < i; k++ )
|
|
Abc_Print( 1, " %7.2f", pLutLib->pLutDelays[i][k] );
|
|
Abc_Print( 1, "\n" );
|
|
}
|
|
}
|
|
else
|
|
for ( i = 1; i <= pLutLib->LutMax; i++ )
|
|
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 [Computes the record size.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static int If_LibCellComputeRecordSize( char * pFuncDesc, int nInputs )
|
|
{
|
|
int i, nMapBytes, nRecordSize;
|
|
assert( pFuncDesc != NULL );
|
|
nMapBytes = (Abc_Base2Log(nInputs + 2) + 7) / 8;
|
|
nRecordSize = 1 + nInputs * nMapBytes;
|
|
for ( i = 0; pFuncDesc[i]; i++ )
|
|
{
|
|
int nLutVars = 0;
|
|
if ( pFuncDesc[i] != '{' )
|
|
continue;
|
|
for ( i++; pFuncDesc[i] && pFuncDesc[i] != '}'; i++ )
|
|
if ( pFuncDesc[i] >= 'a' && pFuncDesc[i] <= 'z' )
|
|
nLutVars++;
|
|
assert( nLutVars < 31 );
|
|
nRecordSize += ((1 << nLutVars) + 7) / 8;
|
|
if ( pFuncDesc[i] == 0 )
|
|
break;
|
|
}
|
|
return nRecordSize;
|
|
}
|
|
|
|
/**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;
|
|
p->pCellRecordSizes[CellId] = If_LibCellComputeRecordSize( FuncDesc, 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 [Returns the maximum number of inputs in the cell library.]
|
|
|
|
Description [Used for auto-detecting K value for &if command.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int If_LibCellGetMaxInputs( If_LibCell_t * pCellLib )
|
|
{
|
|
int i, nMaxInputs = 0;
|
|
if ( pCellLib == NULL )
|
|
return 0;
|
|
for ( i = 0; i < pCellLib->nCellNum; i++ )
|
|
if ( pCellLib->nCellInputs[i] > nMaxInputs )
|
|
nMaxInputs = pCellLib->nCellInputs[i];
|
|
return nMaxInputs;
|
|
}
|
|
|
|
/**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.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int If_LibLutDelaysAreDiscrete( If_LibLut_t * pLutLib )
|
|
{
|
|
float Delay;
|
|
int i;
|
|
for ( i = 1; i <= pLutLib->LutMax; i++ )
|
|
{
|
|
Delay = pLutLib->pLutDelays[i][0];
|
|
if ( ((float)((int)Delay)) != Delay )
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns 1 if the delays are discrete.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int If_LibLutDelaysAreDifferent( If_LibLut_t * pLutLib )
|
|
{
|
|
int i, k;
|
|
float Delay = pLutLib->pLutDelays[1][0];
|
|
if ( pLutLib->fVarPinDelays )
|
|
{
|
|
for ( i = 2; i <= pLutLib->LutMax; i++ )
|
|
for ( k = 0; k < i; k++ )
|
|
if ( pLutLib->pLutDelays[i][k] != Delay )
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
for ( i = 2; i <= pLutLib->LutMax; i++ )
|
|
if ( pLutLib->pLutDelays[i][0] != Delay )
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Sets simple LUT library.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
If_LibLut_t * If_LibLutSetSimple( int nLutSize )
|
|
{
|
|
If_LibLut_t s_LutLib10= { "lutlib",10, 0, {0,1,1,1,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1},{1},{1},{1}} };
|
|
If_LibLut_t s_LutLib9 = { "lutlib", 9, 0, {0,1,1,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1},{1},{1}} };
|
|
If_LibLut_t s_LutLib8 = { "lutlib", 8, 0, {0,1,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1},{1}} };
|
|
If_LibLut_t s_LutLib7 = { "lutlib", 7, 0, {0,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1}} };
|
|
If_LibLut_t s_LutLib6 = { "lutlib", 6, 0, {0,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1}} };
|
|
If_LibLut_t s_LutLib5 = { "lutlib", 5, 0, {0,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1}} };
|
|
If_LibLut_t s_LutLib4 = { "lutlib", 4, 0, {0,1,1,1,1}, {{0},{1},{1},{1},{1}} };
|
|
If_LibLut_t s_LutLib3 = { "lutlib", 3, 0, {0,1,1,1}, {{0},{1},{1},{1}} };
|
|
If_LibLut_t * pLutLib;
|
|
assert( nLutSize >= 3 && nLutSize <= 10 );
|
|
switch ( nLutSize )
|
|
{
|
|
case 3: pLutLib = &s_LutLib3; break;
|
|
case 4: pLutLib = &s_LutLib4; break;
|
|
case 5: pLutLib = &s_LutLib5; break;
|
|
case 6: pLutLib = &s_LutLib6; break;
|
|
case 7: pLutLib = &s_LutLib7; break;
|
|
case 8: pLutLib = &s_LutLib8; break;
|
|
case 9: pLutLib = &s_LutLib9; break;
|
|
case 10: pLutLib = &s_LutLib10; break;
|
|
default: pLutLib = NULL; break;
|
|
}
|
|
if ( pLutLib == NULL )
|
|
return NULL;
|
|
return If_LibLutDup(pLutLib);
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Gets the delay of the fastest pin.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
float If_LibLutFastestPinDelay( If_LibLut_t * p )
|
|
{
|
|
return !p? 1.0 : p->pLutDelays[p->LutMax][0];
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Gets the delay of the slowest pin.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
float If_LibLutSlowestPinDelay( If_LibLut_t * p )
|
|
{
|
|
return !p? 1.0 : (p->fVarPinDelays? p->pLutDelays[p->LutMax][p->LutMax-1]: p->pLutDelays[p->LutMax][0]);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|