2005-07-29 17:01:00 +02:00
|
|
|
/**CFile****************************************************************
|
|
|
|
|
|
|
|
|
|
FileName [mapperTree.c]
|
|
|
|
|
|
|
|
|
|
PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]
|
|
|
|
|
|
|
|
|
|
Synopsis [Generic technology mapping engine.]
|
|
|
|
|
|
|
|
|
|
Author [MVSIS Group]
|
|
|
|
|
|
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
|
|
|
|
|
|
Date [Ver. 2.0. Started - June 1, 2004.]
|
|
|
|
|
|
|
|
|
|
Revision [$Id: mapperTree.c,v 1.9 2005/01/23 06:59:45 alanmi Exp $]
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
|
|
#ifdef __linux__
|
|
|
|
|
#include <libgen.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "mapperInt.h"
|
|
|
|
|
|
2010-11-01 09:35:04 +01:00
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
|
|
|
|
|
2005-07-29 17:01:00 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// DECLARATIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
static int Map_LibraryReadFileTree( Map_SuperLib_t * pLib, FILE * pFile, char *pFileName );
|
|
|
|
|
static Map_Super_t * Map_LibraryReadGateTree( Map_SuperLib_t * pLib, char * pBuffer, int Number, int nVars );
|
|
|
|
|
static int Map_LibraryDeriveGateInfo( Map_SuperLib_t * pLib, st_table * tExcludeGate );
|
|
|
|
|
static void Map_LibraryAddFaninDelays( Map_SuperLib_t * pLib, Map_Super_t * pGate, Map_Super_t * pFanin, Mio_Pin_t * pPin );
|
|
|
|
|
static int Map_LibraryGetMaxSuperPi_rec( Map_Super_t * pGate );
|
|
|
|
|
static unsigned Map_LibraryGetGateSupp_rec( Map_Super_t * pGate );
|
|
|
|
|
|
|
|
|
|
// fanout limits
|
2008-07-25 17:01:00 +02:00
|
|
|
extern const int s_MapFanoutLimits[10] = { 1/*0*/, 10/*1*/, 5/*2*/, 2/*3*/, 1/*4*/, 1/*5*/, 1/*6*/ };
|
2005-07-29 17:01:00 +02:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
2008-01-31 05:01:00 +01:00
|
|
|
/// FUNCTION DEFINITIONS ///
|
2005-07-29 17:01:00 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Reads the supergate library from file.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
int Map_LibraryReadTree( Map_SuperLib_t * pLib, char * pFileName, char * pExcludeFile )
|
|
|
|
|
{
|
|
|
|
|
FILE * pFile;
|
|
|
|
|
int Status, num;
|
|
|
|
|
Abc_Frame_t * pAbc;
|
|
|
|
|
st_table * tExcludeGate = 0;
|
|
|
|
|
|
|
|
|
|
// read the beginning of the file
|
|
|
|
|
assert( pLib->pGenlib == NULL );
|
2008-01-31 05:01:00 +01:00
|
|
|
pFile = Io_FileOpen( pFileName, "open_path", "r", 1 );
|
|
|
|
|
// pFile = fopen( pFileName, "r" );
|
2005-07-29 17:01:00 +02:00
|
|
|
if ( pFile == NULL )
|
|
|
|
|
{
|
|
|
|
|
printf( "Cannot open input file \"%s\".\n", pFileName );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( pExcludeFile )
|
|
|
|
|
{
|
|
|
|
|
pAbc = Abc_FrameGetGlobalFrame();
|
|
|
|
|
|
|
|
|
|
tExcludeGate = st_init_table(strcmp, st_strhash);
|
2011-03-31 06:02:29 +02:00
|
|
|
if ( (num = Mio_LibraryReadExclude( pExcludeFile, tExcludeGate )) == -1 )
|
2005-07-29 17:01:00 +02:00
|
|
|
{
|
|
|
|
|
st_free_table( tExcludeGate );
|
|
|
|
|
tExcludeGate = 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf ( Abc_FrameReadOut( pAbc ), "Read %d gates from exclude file\n", num );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Status = Map_LibraryReadFileTree( pLib, pFile, pFileName );
|
|
|
|
|
fclose( pFile );
|
|
|
|
|
if ( Status == 0 )
|
|
|
|
|
return 0;
|
|
|
|
|
// prepare the info about the library
|
|
|
|
|
return Map_LibraryDeriveGateInfo( pLib, tExcludeGate );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Reads the library file.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
int Map_LibraryReadFileTree( Map_SuperLib_t * pLib, FILE * pFile, char *pFileName )
|
|
|
|
|
{
|
|
|
|
|
ProgressBar * pProgress;
|
|
|
|
|
char pBuffer[5000], pLibFile[5000];
|
|
|
|
|
FILE * pFileGen;
|
|
|
|
|
Map_Super_t * pGate;
|
|
|
|
|
char * pTemp = 0, * pLibName;
|
|
|
|
|
int nCounter, k, i;
|
|
|
|
|
|
|
|
|
|
// skip empty and comment lines
|
|
|
|
|
while ( fgets( pBuffer, 5000, pFile ) != NULL )
|
|
|
|
|
{
|
|
|
|
|
// skip leading spaces
|
|
|
|
|
for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ );
|
|
|
|
|
// skip comment lines and empty lines
|
|
|
|
|
if ( *pTemp != 0 && *pTemp != '#' )
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get the genlib file name (base)
|
|
|
|
|
pLibName = strtok( pTemp, " \t\r\n" );
|
2008-07-25 17:01:00 +02:00
|
|
|
#ifdef __linux__
|
|
|
|
|
if( strchr( pLibName, '/' ) != NULL )
|
|
|
|
|
pLibName = strrchr( pLibName, '/' ) + 1;
|
|
|
|
|
#else
|
|
|
|
|
if( strchr( pLibName, '\\' ) != NULL )
|
|
|
|
|
pLibName = strrchr( pLibName, '\\' ) + 1;
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-07-29 17:01:00 +02:00
|
|
|
if ( strcmp( pLibName, "GATE" ) == 0 )
|
|
|
|
|
{
|
|
|
|
|
printf( "The input file \"%s\" looks like a GENLIB file and not a supergate library file.\n", pLib->pName );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// now figure out the directory if any in the pFileName
|
|
|
|
|
#ifdef __linux__
|
|
|
|
|
snprintf( pLibFile, 5000, "%s/%s", dirname(strdup(pFileName)), pLibName );
|
|
|
|
|
#else
|
|
|
|
|
{
|
|
|
|
|
char * pStr;
|
|
|
|
|
strcpy( pLibFile, pFileName );
|
|
|
|
|
pStr = pLibFile + strlen(pBuffer) - 1;
|
|
|
|
|
while ( pStr > pLibFile && *pStr != '\\' && *pStr != '/' )
|
|
|
|
|
pStr--;
|
|
|
|
|
if ( pStr == pLibFile )
|
|
|
|
|
strcpy( pLibFile, pLibName );
|
|
|
|
|
else
|
2008-07-25 17:01:00 +02:00
|
|
|
sprintf( pStr, "\\%s", pLibName );
|
2005-07-29 17:01:00 +02:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2008-01-31 05:01:00 +01:00
|
|
|
pFileGen = Io_FileOpen( pLibFile, "open_path", "r", 1 );
|
|
|
|
|
// pFileGen = fopen( pLibFile, "r" );
|
2005-07-29 17:01:00 +02:00
|
|
|
if ( pFileGen == NULL )
|
|
|
|
|
{
|
|
|
|
|
printf( "Cannot open the GENLIB file \"%s\".\n", pLibFile );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
fclose( pFileGen );
|
|
|
|
|
|
|
|
|
|
// read the genlib library
|
2011-03-31 06:02:29 +02:00
|
|
|
pLib->pGenlib = Mio_LibraryRead( pLibFile, 0, 0 );
|
2005-07-29 17:01:00 +02:00
|
|
|
if ( pLib->pGenlib == NULL )
|
|
|
|
|
{
|
|
|
|
|
printf( "Cannot read GENLIB file \"%s\".\n", pLibFile );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// read the number of variables
|
|
|
|
|
fscanf( pFile, "%d\n", &pLib->nVarsMax );
|
|
|
|
|
if ( pLib->nVarsMax < 2 || pLib->nVarsMax > 10 )
|
|
|
|
|
{
|
|
|
|
|
printf( "Suspicious number of variables (%d).\n", pLib->nVarsMax );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// read the number of gates
|
|
|
|
|
fscanf( pFile, "%d\n", &pLib->nSupersReal );
|
|
|
|
|
if ( pLib->nSupersReal < 1 || pLib->nSupersReal > 10000000 )
|
|
|
|
|
{
|
|
|
|
|
printf( "Suspicious number of gates (%d).\n", pLib->nSupersReal );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// read the number of lines
|
|
|
|
|
fscanf( pFile, "%d\n", &pLib->nLines );
|
|
|
|
|
if ( pLib->nLines < 1 || pLib->nLines > 10000000 )
|
|
|
|
|
{
|
|
|
|
|
printf( "Suspicious number of lines (%d).\n", pLib->nLines );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// allocate room for supergate pointers
|
2009-02-15 17:01:00 +01:00
|
|
|
pLib->ppSupers = ABC_ALLOC( Map_Super_t *, pLib->nLines + 10000 );
|
2005-07-29 17:01:00 +02:00
|
|
|
|
|
|
|
|
// create the elementary supergates
|
|
|
|
|
for ( i = 0; i < pLib->nVarsMax; i++ )
|
|
|
|
|
{
|
|
|
|
|
// get a new gate
|
|
|
|
|
pGate = (Map_Super_t *)Extra_MmFixedEntryFetch( pLib->mmSupers );
|
|
|
|
|
memset( pGate, 0, sizeof(Map_Super_t) );
|
|
|
|
|
// assign the elementary variable, the truth table, and the delays
|
|
|
|
|
pGate->Num = i;
|
|
|
|
|
// set the truth table
|
|
|
|
|
pGate->uTruth[0] = pLib->uTruths[i][0];
|
|
|
|
|
pGate->uTruth[1] = pLib->uTruths[i][1];
|
|
|
|
|
// set the arrival times of all input to non-existent delay
|
|
|
|
|
for ( k = 0; k < pLib->nVarsMax; k++ )
|
|
|
|
|
{
|
|
|
|
|
pGate->tDelaysR[k].Rise = pGate->tDelaysR[k].Fall = MAP_NO_VAR;
|
|
|
|
|
pGate->tDelaysF[k].Rise = pGate->tDelaysF[k].Fall = MAP_NO_VAR;
|
|
|
|
|
}
|
|
|
|
|
// set an existent arrival time for rise and fall
|
|
|
|
|
pGate->tDelaysR[i].Rise = 0.0;
|
|
|
|
|
pGate->tDelaysF[i].Fall = 0.0;
|
|
|
|
|
// set the gate
|
|
|
|
|
pLib->ppSupers[i] = pGate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// read the lines
|
|
|
|
|
nCounter = pLib->nVarsMax;
|
|
|
|
|
pProgress = Extra_ProgressBarStart( stdout, pLib->nLines );
|
|
|
|
|
while ( fgets( pBuffer, 5000, pFile ) != NULL )
|
|
|
|
|
{
|
|
|
|
|
for ( pTemp = pBuffer; *pTemp == ' ' || *pTemp == '\r' || *pTemp == '\n'; pTemp++ );
|
|
|
|
|
if ( pTemp[0] == '\0' )
|
|
|
|
|
continue;
|
|
|
|
|
// if ( pTemp[0] == 'a' || pTemp[2] == 'a' )
|
|
|
|
|
// {
|
|
|
|
|
// pLib->nLines--;
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// get the gate
|
|
|
|
|
pGate = Map_LibraryReadGateTree( pLib, pTemp, nCounter, pLib->nVarsMax );
|
|
|
|
|
if ( pGate == NULL )
|
|
|
|
|
{
|
|
|
|
|
Extra_ProgressBarStop( pProgress );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
pLib->ppSupers[nCounter++] = pGate;
|
|
|
|
|
// later we will derive: truth table, delays, area, number of component gates, etc
|
|
|
|
|
|
|
|
|
|
// update the progress bar
|
|
|
|
|
Extra_ProgressBarUpdate( pProgress, nCounter, NULL );
|
|
|
|
|
}
|
|
|
|
|
Extra_ProgressBarStop( pProgress );
|
|
|
|
|
if ( nCounter != pLib->nLines )
|
|
|
|
|
printf( "The number of lines read (%d) is different what the file says (%d).\n", nCounter, pLib->nLines );
|
|
|
|
|
pLib->nSupersAll = nCounter;
|
|
|
|
|
// count the number of real supergates
|
|
|
|
|
nCounter = 0;
|
|
|
|
|
for ( k = 0; k < pLib->nLines; k++ )
|
|
|
|
|
nCounter += pLib->ppSupers[k]->fSuper;
|
|
|
|
|
if ( nCounter != pLib->nSupersReal )
|
|
|
|
|
printf( "The number of gates read (%d) is different what the file says (%d).\n", nCounter, pLib->nSupersReal );
|
|
|
|
|
pLib->nSupersReal = nCounter;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Reads one gate.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
Map_Super_t * Map_LibraryReadGateTree( Map_SuperLib_t * pLib, char * pBuffer, int Number, int nVarsMax )
|
|
|
|
|
{
|
|
|
|
|
Map_Super_t * pGate;
|
|
|
|
|
char * pTemp;
|
|
|
|
|
int i, Num;
|
|
|
|
|
|
|
|
|
|
// start and clean the gate
|
|
|
|
|
pGate = (Map_Super_t *)Extra_MmFixedEntryFetch( pLib->mmSupers );
|
|
|
|
|
memset( pGate, 0, sizeof(Map_Super_t) );
|
|
|
|
|
|
|
|
|
|
// set the gate number
|
|
|
|
|
pGate->Num = Number;
|
|
|
|
|
|
|
|
|
|
// read the mark
|
|
|
|
|
pTemp = strtok( pBuffer, " " );
|
|
|
|
|
if ( pTemp[0] == '*' )
|
|
|
|
|
{
|
|
|
|
|
pGate->fSuper = 1;
|
|
|
|
|
pTemp = strtok( NULL, " " );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// read the root gate
|
|
|
|
|
pGate->pRoot = Mio_LibraryReadGateByName( pLib->pGenlib, pTemp );
|
|
|
|
|
if ( pGate->pRoot == NULL )
|
|
|
|
|
{
|
|
|
|
|
printf( "Cannot read the root gate names %s.\n", pTemp );
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
// set the max number of fanouts
|
|
|
|
|
pGate->nFanLimit = s_MapFanoutLimits[ Mio_GateReadInputs(pGate->pRoot) ];
|
|
|
|
|
|
|
|
|
|
// read the pin-to-pin delay
|
|
|
|
|
for ( i = 0; ( pTemp = strtok( NULL, " \n\0" ) ); i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( pTemp[0] == '#' )
|
|
|
|
|
break;
|
|
|
|
|
if ( i == nVarsMax )
|
|
|
|
|
{
|
|
|
|
|
printf( "There are too many entries on the line.\n" );
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
Num = atoi(pTemp);
|
|
|
|
|
if ( Num < 0 )
|
|
|
|
|
{
|
|
|
|
|
printf( "The number of a child supergate is negative.\n" );
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if ( Num > pLib->nLines )
|
|
|
|
|
{
|
|
|
|
|
printf( "The number of a child supergate (%d) exceeded the number of lines (%d).\n",
|
|
|
|
|
Num, pLib->nLines );
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
pGate->pFanins[i] = pLib->ppSupers[Num];
|
|
|
|
|
}
|
|
|
|
|
pGate->nFanins = i;
|
|
|
|
|
if ( pGate->nFanins != (unsigned)Mio_GateReadInputs(pGate->pRoot) )
|
|
|
|
|
{
|
|
|
|
|
printf( "The number of fanins of a root gate is wrong.\n" );
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// save the gate name, just in case
|
|
|
|
|
if ( pTemp && pTemp[0] == '#' )
|
|
|
|
|
{
|
|
|
|
|
if ( pTemp[1] == 0 )
|
|
|
|
|
pTemp = strtok( NULL, " \n\0" );
|
|
|
|
|
else // skip spaces
|
|
|
|
|
for ( pTemp++; *pTemp == ' '; pTemp++ );
|
|
|
|
|
// save the formula
|
|
|
|
|
pGate->pFormula = Extra_MmFlexEntryFetch( pLib->mmForms, strlen(pTemp)+1 );
|
|
|
|
|
strcpy( pGate->pFormula, pTemp );
|
|
|
|
|
}
|
|
|
|
|
// check the rest of the string
|
|
|
|
|
pTemp = strtok( NULL, " \n\0" );
|
|
|
|
|
if ( pTemp != NULL )
|
|
|
|
|
printf( "The following trailing symbols found \"%s\".\n", pTemp );
|
|
|
|
|
return pGate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Derives information about the library.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
int Map_LibraryDeriveGateInfo( Map_SuperLib_t * pLib, st_table * tExcludeGate )
|
|
|
|
|
{
|
|
|
|
|
Map_Super_t * pGate, * pFanin;
|
|
|
|
|
Mio_Pin_t * pPin;
|
|
|
|
|
unsigned uCanon[2];
|
|
|
|
|
unsigned uTruths[6][2];
|
|
|
|
|
int i, k, nRealVars;
|
|
|
|
|
|
|
|
|
|
// set all the derivable info related to the supergates
|
|
|
|
|
for ( i = pLib->nVarsMax; i < (int)pLib->nLines; i++ )
|
|
|
|
|
{
|
|
|
|
|
pGate = pLib->ppSupers[i];
|
|
|
|
|
|
|
|
|
|
if ( tExcludeGate )
|
|
|
|
|
{
|
|
|
|
|
if ( st_is_member( tExcludeGate, Mio_GateReadName( pGate->pRoot ) ) )
|
|
|
|
|
pGate->fExclude = 1;
|
|
|
|
|
for ( k = 0; k < (int)pGate->nFanins; k++ )
|
|
|
|
|
{
|
|
|
|
|
pFanin = pGate->pFanins[k];
|
|
|
|
|
if ( pFanin->fExclude )
|
|
|
|
|
{
|
|
|
|
|
pGate->fExclude = 1;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// collect the truth tables of the fanins
|
|
|
|
|
for ( k = 0; k < (int)pGate->nFanins; k++ )
|
|
|
|
|
{
|
|
|
|
|
pFanin = pGate->pFanins[k];
|
|
|
|
|
uTruths[k][0] = pFanin->uTruth[0];
|
|
|
|
|
uTruths[k][1] = pFanin->uTruth[1];
|
|
|
|
|
}
|
|
|
|
|
// derive the new truth table
|
|
|
|
|
Mio_DeriveTruthTable( pGate->pRoot, uTruths, pGate->nFanins, 6, pGate->uTruth );
|
|
|
|
|
|
|
|
|
|
// set the initial delays of the supergate
|
|
|
|
|
for ( k = 0; k < pLib->nVarsMax; k++ )
|
|
|
|
|
{
|
|
|
|
|
pGate->tDelaysR[k].Rise = pGate->tDelaysR[k].Fall = MAP_NO_VAR;
|
|
|
|
|
pGate->tDelaysF[k].Rise = pGate->tDelaysF[k].Fall = MAP_NO_VAR;
|
|
|
|
|
}
|
|
|
|
|
// get the linked list of pins for the given root gate
|
|
|
|
|
pPin = Mio_GateReadPins( pGate->pRoot );
|
|
|
|
|
// update the initial delay of the supergate using info from the corresponding pin
|
|
|
|
|
for ( k = 0; k < (int)pGate->nFanins; k++, pPin = Mio_PinReadNext(pPin) )
|
|
|
|
|
{
|
|
|
|
|
// if there is no corresponding pin, this is a bug, return fail
|
|
|
|
|
if ( pPin == NULL )
|
|
|
|
|
{
|
|
|
|
|
printf( "There are less pins than gate inputs.\n" );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// update the delay information of k-th fanins info from the corresponding pin
|
|
|
|
|
Map_LibraryAddFaninDelays( pLib, pGate, pGate->pFanins[k], pPin );
|
|
|
|
|
}
|
|
|
|
|
// if there are some pins left, this is a bug, return fail
|
|
|
|
|
if ( pPin != NULL )
|
|
|
|
|
{
|
|
|
|
|
printf( "There are more pins than gate inputs.\n" );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// find the max delay
|
|
|
|
|
pGate->tDelayMax.Rise = pGate->tDelayMax.Fall = MAP_NO_VAR;
|
|
|
|
|
for ( k = 0; k < pLib->nVarsMax; k++ )
|
|
|
|
|
{
|
|
|
|
|
// the rise of the output depends on the rise and fall of the output
|
|
|
|
|
if ( pGate->tDelayMax.Rise < pGate->tDelaysR[k].Rise )
|
|
|
|
|
pGate->tDelayMax.Rise = pGate->tDelaysR[k].Rise;
|
|
|
|
|
if ( pGate->tDelayMax.Rise < pGate->tDelaysR[k].Fall )
|
|
|
|
|
pGate->tDelayMax.Rise = pGate->tDelaysR[k].Fall;
|
|
|
|
|
// the fall of the output depends on the rise and fall of the output
|
|
|
|
|
if ( pGate->tDelayMax.Fall < pGate->tDelaysF[k].Rise )
|
|
|
|
|
pGate->tDelayMax.Fall = pGate->tDelaysF[k].Rise;
|
|
|
|
|
if ( pGate->tDelayMax.Fall < pGate->tDelaysF[k].Fall )
|
|
|
|
|
pGate->tDelayMax.Fall = pGate->tDelaysF[k].Fall;
|
2008-01-31 05:01:00 +01:00
|
|
|
|
|
|
|
|
pGate->tDelaysF[k].Worst = MAP_MAX( pGate->tDelaysF[k].Fall, pGate->tDelaysF[k].Rise );
|
|
|
|
|
pGate->tDelaysR[k].Worst = MAP_MAX( pGate->tDelaysR[k].Fall, pGate->tDelaysR[k].Rise );
|
2005-07-29 17:01:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// count gates and area of the supergate
|
|
|
|
|
pGate->nGates = 1;
|
|
|
|
|
pGate->Area = (float)Mio_GateReadArea(pGate->pRoot);
|
|
|
|
|
for ( k = 0; k < (int)pGate->nFanins; k++ )
|
|
|
|
|
{
|
|
|
|
|
pGate->nGates += pGate->pFanins[k]->nGates;
|
|
|
|
|
pGate->Area += pGate->pFanins[k]->Area;
|
|
|
|
|
}
|
|
|
|
|
// do not add the gate to the table, if this gate is an internal gate
|
|
|
|
|
// of some supegate and does not correspond to a supergate output
|
|
|
|
|
if ( ( !pGate->fSuper ) || pGate->fExclude )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// find the maximum index of a variable in the support of the supergates
|
|
|
|
|
// this is important for two reasons:
|
|
|
|
|
// (1) to limit the number of permutations considered for canonicization
|
|
|
|
|
// (2) to get rid of equivalence phases to speed-up matching
|
|
|
|
|
nRealVars = Map_LibraryGetMaxSuperPi_rec( pGate ) + 1;
|
|
|
|
|
assert( nRealVars > 0 && nRealVars <= pLib->nVarsMax );
|
|
|
|
|
// if there are some problems with this code, try this instead
|
|
|
|
|
// nRealVars = pLib->nVarsMax;
|
|
|
|
|
|
|
|
|
|
// find the N-canonical form of this supergate
|
|
|
|
|
pGate->nPhases = Map_CanonComputeSlow( pLib->uTruths, pLib->nVarsMax, nRealVars, pGate->uTruth, pGate->uPhases, uCanon );
|
|
|
|
|
// add the supergate into the table by its N-canonical table
|
|
|
|
|
Map_SuperTableInsertC( pLib->tTableC, uCanon, pGate );
|
2005-08-18 17:01:00 +02:00
|
|
|
/*
|
|
|
|
|
{
|
|
|
|
|
int uCanon1, uCanon2;
|
|
|
|
|
uCanon1 = uCanon[0];
|
|
|
|
|
pGate->uTruth[0] = ~pGate->uTruth[0];
|
|
|
|
|
pGate->uTruth[1] = ~pGate->uTruth[1];
|
|
|
|
|
Map_CanonComputeSlow( pLib->uTruths, pLib->nVarsMax, nRealVars, pGate->uTruth, pGate->uPhases, uCanon );
|
|
|
|
|
uCanon2 = uCanon[0];
|
|
|
|
|
Rwt_Man5ExploreCount( uCanon1 < uCanon2 ? uCanon1 : uCanon2 );
|
|
|
|
|
}
|
|
|
|
|
*/
|
2005-07-29 17:01:00 +02:00
|
|
|
}
|
|
|
|
|
// sort the gates in each line
|
|
|
|
|
Map_SuperTableSortSupergatesByDelay( pLib->tTableC, pLib->nSupersAll );
|
|
|
|
|
|
|
|
|
|
// let the glory be manifest
|
|
|
|
|
// Map_LibraryPrintTree( pLib );
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Finds the largest PI number in the support of the supergate.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
int Map_LibraryGetMaxSuperPi_rec( Map_Super_t * pGate )
|
|
|
|
|
{
|
|
|
|
|
int i, VarCur, VarMax = 0;
|
|
|
|
|
if ( pGate->pRoot == NULL )
|
|
|
|
|
return pGate->Num;
|
|
|
|
|
for ( i = 0; i < (int)pGate->nFanins; i++ )
|
|
|
|
|
{
|
|
|
|
|
VarCur = Map_LibraryGetMaxSuperPi_rec( pGate->pFanins[i] );
|
|
|
|
|
if ( VarMax < VarCur )
|
|
|
|
|
VarMax = VarCur;
|
|
|
|
|
}
|
|
|
|
|
return VarMax;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Finds the largest PI number in the support of the supergate.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
unsigned Map_LibraryGetGateSupp_rec( Map_Super_t * pGate )
|
|
|
|
|
{
|
|
|
|
|
unsigned uSupport;
|
|
|
|
|
int i;
|
|
|
|
|
if ( pGate->pRoot == NULL )
|
|
|
|
|
return (unsigned)(1 << (pGate->Num));
|
|
|
|
|
uSupport = 0;
|
|
|
|
|
for ( i = 0; i < (int)pGate->nFanins; i++ )
|
|
|
|
|
uSupport |= Map_LibraryGetGateSupp_rec( pGate->pFanins[i] );
|
|
|
|
|
return uSupport;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Derives the pin-to-pin delay constraints for the supergate.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
void Map_LibraryAddFaninDelays( Map_SuperLib_t * pLib, Map_Super_t * pGate, Map_Super_t * pFanin, Mio_Pin_t * pPin )
|
|
|
|
|
{
|
|
|
|
|
Mio_PinPhase_t PinPhase;
|
|
|
|
|
float tDelayBlockRise, tDelayBlockFall, tDelayPin;
|
2010-11-01 09:35:04 +01:00
|
|
|
int fMaxDelay = 0;
|
2005-07-29 17:01:00 +02:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
// use this node to enable max-delay model
|
|
|
|
|
if ( fMaxDelay )
|
|
|
|
|
{
|
|
|
|
|
float tDelayBlockMax;
|
|
|
|
|
// get the maximum delay
|
|
|
|
|
tDelayBlockMax = (float)Mio_PinReadDelayBlockMax(pPin);
|
|
|
|
|
// go through the supergate inputs
|
|
|
|
|
for ( i = 0; i < pLib->nVarsMax; i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( pFanin->tDelaysR[i].Rise < 0 )
|
|
|
|
|
continue;
|
|
|
|
|
tDelayPin = pFanin->tDelaysR[i].Rise + tDelayBlockMax;
|
|
|
|
|
if ( pGate->tDelaysR[i].Rise < tDelayPin )
|
|
|
|
|
pGate->tDelaysR[i].Rise = tDelayPin;
|
|
|
|
|
}
|
|
|
|
|
// go through the supergate inputs
|
|
|
|
|
for ( i = 0; i < pLib->nVarsMax; i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( pFanin->tDelaysF[i].Fall < 0 )
|
|
|
|
|
continue;
|
|
|
|
|
tDelayPin = pFanin->tDelaysF[i].Fall + tDelayBlockMax;
|
|
|
|
|
if ( pGate->tDelaysF[i].Fall < tDelayPin )
|
|
|
|
|
pGate->tDelaysF[i].Fall = tDelayPin;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get the interesting parameters of this pin
|
|
|
|
|
PinPhase = Mio_PinReadPhase(pPin);
|
|
|
|
|
tDelayBlockRise = (float)Mio_PinReadDelayBlockRise( pPin );
|
|
|
|
|
tDelayBlockFall = (float)Mio_PinReadDelayBlockFall( pPin );
|
|
|
|
|
|
|
|
|
|
// update the rise and fall of the output depending on the phase of the pin
|
|
|
|
|
if ( PinPhase != MIO_PHASE_INV ) // NONINV phase is present
|
|
|
|
|
{
|
|
|
|
|
// the rise of the gate is determined by the rise of the fanin
|
|
|
|
|
// the fall of the gate is determined by the fall of the fanin
|
|
|
|
|
for ( i = 0; i < pLib->nVarsMax; i++ )
|
|
|
|
|
{
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
// consider the rise of the gate
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
// check two types of constraints on the rise of the fanin:
|
|
|
|
|
// (1) the constraints related to the rise of the PIs
|
|
|
|
|
// (2) the constraints related to the fall of the PIs
|
|
|
|
|
if ( pFanin->tDelaysR[i].Rise >= 0 ) // case (1)
|
|
|
|
|
{ // fanin's rise depends on the rise of i-th PI
|
|
|
|
|
// update the rise of the gate's output
|
|
|
|
|
if ( pGate->tDelaysR[i].Rise < pFanin->tDelaysR[i].Rise + tDelayBlockRise )
|
|
|
|
|
pGate->tDelaysR[i].Rise = pFanin->tDelaysR[i].Rise + tDelayBlockRise;
|
|
|
|
|
}
|
|
|
|
|
if ( pFanin->tDelaysR[i].Fall >= 0 ) // case (2)
|
|
|
|
|
{ // fanin's rise depends on the fall of i-th PI
|
|
|
|
|
// update the rise of the gate's output
|
|
|
|
|
if ( pGate->tDelaysR[i].Fall < pFanin->tDelaysR[i].Fall + tDelayBlockRise )
|
|
|
|
|
pGate->tDelaysR[i].Fall = pFanin->tDelaysR[i].Fall + tDelayBlockRise;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
// consider the fall of the gate (similar)
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
// check two types of constraints on the fall of the fanin:
|
|
|
|
|
// (1) the constraints related to the rise of the PIs
|
|
|
|
|
// (2) the constraints related to the fall of the PIs
|
|
|
|
|
if ( pFanin->tDelaysF[i].Rise >= 0 ) // case (1)
|
|
|
|
|
{
|
|
|
|
|
if ( pGate->tDelaysF[i].Rise < pFanin->tDelaysF[i].Rise + tDelayBlockFall )
|
|
|
|
|
pGate->tDelaysF[i].Rise = pFanin->tDelaysF[i].Rise + tDelayBlockFall;
|
|
|
|
|
}
|
|
|
|
|
if ( pFanin->tDelaysF[i].Fall >= 0 ) // case (2)
|
|
|
|
|
{
|
|
|
|
|
if ( pGate->tDelaysF[i].Fall < pFanin->tDelaysF[i].Fall + tDelayBlockFall )
|
|
|
|
|
pGate->tDelaysF[i].Fall = pFanin->tDelaysF[i].Fall + tDelayBlockFall;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ( PinPhase != MIO_PHASE_NONINV ) // INV phase is present
|
|
|
|
|
{
|
|
|
|
|
// the rise of the gate is determined by the fall of the fanin
|
|
|
|
|
// the fall of the gate is determined by the rise of the fanin
|
|
|
|
|
for ( i = 0; i < pLib->nVarsMax; i++ )
|
|
|
|
|
{
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
// consider the rise of the gate's output
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
// check two types of constraints on the fall of the fanin:
|
|
|
|
|
// (1) the constraints related to the rise of the PIs
|
|
|
|
|
// (2) the constraints related to the fall of the PIs
|
|
|
|
|
if ( pFanin->tDelaysF[i].Rise >= 0 ) // case (1)
|
|
|
|
|
{ // fanin's rise depends on the rise of i-th PI
|
|
|
|
|
// update the rise of the gate
|
|
|
|
|
if ( pGate->tDelaysR[i].Rise < pFanin->tDelaysF[i].Rise + tDelayBlockRise )
|
|
|
|
|
pGate->tDelaysR[i].Rise = pFanin->tDelaysF[i].Rise + tDelayBlockRise;
|
|
|
|
|
}
|
|
|
|
|
if ( pFanin->tDelaysF[i].Fall >= 0 ) // case (2)
|
|
|
|
|
{ // fanin's rise depends on the fall of i-th PI
|
|
|
|
|
// update the rise of the gate
|
|
|
|
|
if ( pGate->tDelaysR[i].Fall < pFanin->tDelaysF[i].Fall + tDelayBlockRise )
|
|
|
|
|
pGate->tDelaysR[i].Fall = pFanin->tDelaysF[i].Fall + tDelayBlockRise;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
// consider the fall of the gate (similar)
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
// check two types of constraints on the rise of the fanin:
|
|
|
|
|
// (1) the constraints related to the rise of the PIs
|
|
|
|
|
// (2) the constraints related to the fall of the PIs
|
|
|
|
|
if ( pFanin->tDelaysR[i].Rise >= 0 ) // case (1)
|
|
|
|
|
{
|
|
|
|
|
if ( pGate->tDelaysF[i].Rise < pFanin->tDelaysR[i].Rise + tDelayBlockFall )
|
|
|
|
|
pGate->tDelaysF[i].Rise = pFanin->tDelaysR[i].Rise + tDelayBlockFall;
|
|
|
|
|
}
|
|
|
|
|
if ( pFanin->tDelaysR[i].Fall >= 0 ) // case (2)
|
|
|
|
|
{
|
|
|
|
|
if ( pGate->tDelaysF[i].Fall < pFanin->tDelaysR[i].Fall + tDelayBlockFall )
|
|
|
|
|
pGate->tDelaysF[i].Fall = pFanin->tDelaysR[i].Fall + tDelayBlockFall;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Performs phase transformation for one function.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
unsigned Map_CalculatePhase( unsigned uTruths[][2], int nVars, unsigned uTruth, unsigned uPhase )
|
|
|
|
|
{
|
|
|
|
|
int v, Shift;
|
|
|
|
|
for ( v = 0, Shift = 1; v < nVars; v++, Shift <<= 1 )
|
|
|
|
|
if ( uPhase & Shift )
|
|
|
|
|
uTruth = (((uTruth & ~uTruths[v][0]) << Shift) | ((uTruth & uTruths[v][0]) >> Shift));
|
|
|
|
|
return uTruth;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Performs phase transformation for one function.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
void Map_CalculatePhase6( unsigned uTruths[][2], int nVars, unsigned uTruth[], unsigned uPhase, unsigned uTruthRes[] )
|
|
|
|
|
{
|
|
|
|
|
unsigned uTemp;
|
|
|
|
|
int v, Shift;
|
|
|
|
|
|
|
|
|
|
// initialize the result
|
|
|
|
|
uTruthRes[0] = uTruth[0];
|
|
|
|
|
uTruthRes[1] = uTruth[1];
|
|
|
|
|
if ( uPhase == 0 )
|
|
|
|
|
return;
|
|
|
|
|
// compute the phase
|
|
|
|
|
for ( v = 0, Shift = 1; v < nVars; v++, Shift <<= 1 )
|
|
|
|
|
if ( uPhase & Shift )
|
|
|
|
|
{
|
|
|
|
|
if ( Shift < 32 )
|
|
|
|
|
{
|
|
|
|
|
uTruthRes[0] = (((uTruthRes[0] & ~uTruths[v][0]) << Shift) | ((uTruthRes[0] & uTruths[v][0]) >> Shift));
|
|
|
|
|
uTruthRes[1] = (((uTruthRes[1] & ~uTruths[v][1]) << Shift) | ((uTruthRes[1] & uTruths[v][1]) >> Shift));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
uTemp = uTruthRes[0];
|
|
|
|
|
uTruthRes[0] = uTruthRes[1];
|
|
|
|
|
uTruthRes[1] = uTemp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Prints the supergate library after deriving parameters.]
|
|
|
|
|
|
|
|
|
|
Description [This procedure is very useful to see the library after
|
|
|
|
|
it has been read into the mapper by "read_super" and all the information
|
|
|
|
|
about the supergates derived.]
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
void Map_LibraryPrintTree( Map_SuperLib_t * pLib )
|
|
|
|
|
{
|
|
|
|
|
Map_Super_t * pGate;
|
|
|
|
|
int i, k;
|
|
|
|
|
|
|
|
|
|
// print all the info related to the supergates
|
|
|
|
|
// for ( i = pLib->nVarsMax; i < (int)pLib->nLines; i++ )
|
|
|
|
|
for ( i = pLib->nVarsMax; i < 20; i++ )
|
|
|
|
|
{
|
|
|
|
|
pGate = pLib->ppSupers[i];
|
|
|
|
|
|
|
|
|
|
// write the gate's fanin info and formula
|
|
|
|
|
printf( "%6d ", pGate->Num );
|
|
|
|
|
printf( "%c ", pGate->fSuper? '*' : ' ' );
|
|
|
|
|
printf( "%6s", Mio_GateReadName(pGate->pRoot) );
|
|
|
|
|
for ( k = 0; k < (int)pGate->nFanins; k++ )
|
|
|
|
|
printf( " %6d", pGate->pFanins[k]->Num );
|
|
|
|
|
printf( " %s", pGate->pFormula );
|
|
|
|
|
printf( "\n" );
|
|
|
|
|
|
|
|
|
|
// write the gate's derived info
|
|
|
|
|
Extra_PrintBinary( stdout, pGate->uTruth, 64 );
|
|
|
|
|
printf( " %3d", pGate->nGates );
|
|
|
|
|
printf( " %6.2f", pGate->Area );
|
|
|
|
|
printf( " (%4.2f, %4.2f)", pGate->tDelayMax.Rise, pGate->tDelayMax.Fall );
|
|
|
|
|
printf( "\n" );
|
|
|
|
|
for ( k = 0; k < pLib->nVarsMax; k++ )
|
|
|
|
|
{
|
|
|
|
|
// print the constraint on the rise of the gate in the form (D1, D2),
|
|
|
|
|
// where D1 is the constraint related to the rise of the k-th PI
|
|
|
|
|
// where D2 is the constraint related to the fall of the k-th PI
|
|
|
|
|
if ( pGate->tDelaysR[k].Rise < 0 && pGate->tDelaysR[k].Fall < 0 )
|
|
|
|
|
printf( " (----, ----)" );
|
|
|
|
|
else if ( pGate->tDelaysR[k].Fall < 0 )
|
|
|
|
|
printf( " (%4.2f, ----)", pGate->tDelaysR[k].Rise );
|
|
|
|
|
else if ( pGate->tDelaysR[k].Rise < 0 )
|
|
|
|
|
printf( " (----, %4.2f)", pGate->tDelaysR[k].Fall );
|
|
|
|
|
else
|
|
|
|
|
printf( " (%4.2f, %4.2f)", pGate->tDelaysR[k].Rise, pGate->tDelaysR[k].Fall );
|
|
|
|
|
|
|
|
|
|
// print the constraint on the fall of the gate in the form (D1, D2),
|
|
|
|
|
// where D1 is the constraint related to the rise of the k-th PI
|
|
|
|
|
// where D2 is the constraint related to the fall of the k-th PI
|
|
|
|
|
if ( pGate->tDelaysF[k].Rise < 0 && pGate->tDelaysF[k].Fall < 0 )
|
|
|
|
|
printf( " (----, ----)" );
|
|
|
|
|
else if ( pGate->tDelaysF[k].Fall < 0 )
|
|
|
|
|
printf( " (%4.2f, ----)", pGate->tDelaysF[k].Rise );
|
|
|
|
|
else if ( pGate->tDelaysF[k].Rise < 0 )
|
|
|
|
|
printf( " (----, %4.2f)", pGate->tDelaysF[k].Fall );
|
|
|
|
|
else
|
|
|
|
|
printf( " (%4.2f, %4.2f)", pGate->tDelaysF[k].Rise, pGate->tDelaysF[k].Fall );
|
|
|
|
|
printf( "\n" );
|
|
|
|
|
}
|
|
|
|
|
printf( "\n" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// END OF FILE ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
2010-11-01 09:35:04 +01:00
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
|
|