ifLibLut.c 9.89 KB
Newer Older
Alan Mishchenko committed
1 2
/**CFile****************************************************************

Alan Mishchenko committed
3
  FileName    [ifLibLut.c]
Alan Mishchenko committed
4 5 6 7 8 9 10 11 12 13 14 15 16

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

Alan Mishchenko committed
17
  Revision    [$Id: ifLibLut.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
Alan Mishchenko committed
18 19 20 21 22

***********************************************************************/

#include "if.h"

23 24 25
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
26 27 28 29
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

Alan Mishchenko committed
30
static inline char * If_UtilStrsav( char *s ) {  return !s ? s : strcpy(ABC_ALLOC(char, strlen(s)+1), s);  }
Alan Mishchenko committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [Reads the description of LUTs from the LUT library file.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
47
If_LibLut_t * If_LibLutRead( char * FileName )
Alan Mishchenko committed
48 49
{
    char pBuffer[1000], * pToken;
50
    If_LibLut_t * p;
Alan Mishchenko committed
51 52 53 54 55 56
    FILE * pFile;
    int i, k;

    pFile = fopen( FileName, "r" );
    if ( pFile == NULL )
    {
57
        Abc_Print( -1, "Cannot open LUT library file \"%s\".\n", FileName );
Alan Mishchenko committed
58 59 60
        return NULL;
    }

61 62
    p = ABC_ALLOC( If_LibLut_t, 1 );
    memset( p, 0, sizeof(If_LibLut_t) );
Alan Mishchenko committed
63 64 65 66 67 68 69 70 71 72 73 74
    p->pName = If_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) )
        {
75
            Abc_Print( 1, "Error in the LUT library file \"%s\".\n", FileName );
76
            ABC_FREE( p->pName );
Alan Mishchenko committed
77
            ABC_FREE( p );
Alan Mishchenko committed
78 79 80 81 82 83 84 85 86
            return NULL;
        }

        // read area
        pToken = strtok( NULL, " \t\n" );
        p->pLutAreas[i] = (float)atof(pToken);

        // read delays
        k = 0;
Alan Mishchenko committed
87
        while ( (pToken = strtok( NULL, " \t\n" )) )
Alan Mishchenko committed
88 89 90 91 92
            p->pLutDelays[i][k++] = (float)atof(pToken);

        // check for out-of-bound
        if ( k > i )
        {
93 94
            ABC_FREE( p->pName );
            ABC_FREE( p );
95
            Abc_Print( 1, "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i );
Alan Mishchenko committed
96 97 98
            return NULL;
        }

Alan Mishchenko committed
99
        // check if var delays are specified
Alan Mishchenko committed
100 101 102 103 104
        if ( k > 1 )
            p->fVarPinDelays = 1;

        if ( i == IF_MAX_LUTSIZE )
        {
105 106
            ABC_FREE( p->pName );
            ABC_FREE( p );
107
            Abc_Print( 1, "Skipping LUTs of size more than %d.\n", i );
Alan Mishchenko committed
108 109 110 111 112 113 114 115 116 117 118 119 120
            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 )
121
                    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", 
Alan Mishchenko committed
122 123
                        k, i, p->pLutDelays[i][k] );
                if ( k && p->pLutDelays[i][k-1] > p->pLutDelays[i][k] )
124
                    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", 
Alan Mishchenko committed
125 126 127 128 129 130 131 132 133
                        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 )
134
                Abc_Print( 0, "LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n", 
Alan Mishchenko committed
135
                    i, p->pLutDelays[i][0] );
Alan Mishchenko committed
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
        }
    }

    return p;
}

/**Function*************************************************************

  Synopsis    [Duplicates the LUT library.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
153
If_LibLut_t * If_LibLutDup( If_LibLut_t * p )
Alan Mishchenko committed
154
{
155 156
    If_LibLut_t * pNew;
    pNew = ABC_ALLOC( If_LibLut_t, 1 );
Alan Mishchenko committed
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
    *pNew = *p;
    pNew->pName = If_UtilStrsav( pNew->pName );
    return pNew;
}

/**Function*************************************************************

  Synopsis    [Frees the LUT library.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
173
void If_LibLutFree( If_LibLut_t * pLutLib )
Alan Mishchenko committed
174 175 176
{
    if ( pLutLib == NULL )
        return;
Alan Mishchenko committed
177 178
    ABC_FREE( pLutLib->pName );
    ABC_FREE( pLutLib );
Alan Mishchenko committed
179 180 181 182 183 184 185 186 187 188 189 190 191 192
}


/**Function*************************************************************

  Synopsis    [Prints the LUT library.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
193
void If_LibLutPrint( If_LibLut_t * pLutLib )
Alan Mishchenko committed
194 195
{
    int i, k;
196 197
    Abc_Print( 1, "# The area/delay of k-variable LUTs:\n" );
    Abc_Print( 1, "# k    area     delay\n" );
Alan Mishchenko committed
198 199 200 201
    if ( pLutLib->fVarPinDelays )
    {
        for ( i = 1; i <= pLutLib->LutMax; i++ )
        {
202
            Abc_Print( 1, "%d   %7.2f  ", i, pLutLib->pLutAreas[i] );
Alan Mishchenko committed
203
            for ( k = 0; k < i; k++ )
204 205
                Abc_Print( 1, " %7.2f", pLutLib->pLutDelays[i][k] );
            Abc_Print( 1, "\n" );
Alan Mishchenko committed
206 207 208 209
        }
    }
    else
        for ( i = 1; i <= pLutLib->LutMax; i++ )
210
            Abc_Print( 1, "%d   %7.2f   %7.2f\n", i, pLutLib->pLutAreas[i], pLutLib->pLutDelays[i][0] );
Alan Mishchenko committed
211 212 213 214 215 216 217 218 219 220 221 222 223
}

/**Function*************************************************************

  Synopsis    [Returns 1 if the delays are discrete.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
224
int If_LibLutDelaysAreDiscrete( If_LibLut_t * pLutLib )
Alan Mishchenko committed
225 226 227 228 229 230 231 232 233 234 235 236 237 238
{
    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*************************************************************

Alan Mishchenko committed
239 240 241 242 243 244 245 246 247
  Synopsis    [Returns 1 if the delays are discrete.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
248
int If_LibLutDelaysAreDifferent( If_LibLut_t * pLutLib )
Alan Mishchenko committed
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
{
    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*************************************************************

Alan Mishchenko committed
270 271 272 273 274 275 276 277 278
  Synopsis    [Sets simple LUT library.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
279
If_LibLut_t * If_LibLutSetSimple( int nLutSize )
Alan Mishchenko committed
280
{
281 282 283 284 285 286 287 288 289
    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;
Alan Mishchenko committed
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
    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;
305
    return If_LibLutDup(pLutLib);
Alan Mishchenko committed
306 307
}

Alan Mishchenko committed
308 309 310 311 312 313 314 315 316 317 318
/**Function*************************************************************

  Synopsis    [Gets the delay of the fastest pin.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
319
float If_LibLutFastestPinDelay( If_LibLut_t * p )
Alan Mishchenko committed
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
{
    return !p? 1.0 : p->pLutDelays[p->LutMax][0];
}

/**Function*************************************************************

  Synopsis    [Gets the delay of the slowest pin.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
335
float If_LibLutSlowestPinDelay( If_LibLut_t * p )
Alan Mishchenko committed
336 337 338 339
{
    return !p? 1.0 : (p->fVarPinDelays? p->pLutDelays[p->LutMax][p->LutMax-1]: p->pLutDelays[p->LutMax][0]);
}

Alan Mishchenko committed
340 341 342 343 344
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


345 346
ABC_NAMESPACE_IMPL_END