fpgaLib.c 7.17 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/**CFile****************************************************************

  FileName    [fpgaLib.c]

  PackageName [MVSIS 1.3: Multi-valued logic synthesis system.]

  Synopsis    [Technology mapping for variable-size-LUT FPGAs.]

  Author      [MVSIS Group]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 2.0. Started - August 18, 2004.]

  Revision    [$Id: fpgaLib.c,v 1.4 2005/01/23 06:59:41 alanmi Exp $]

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

#include "fpgaInt.h"

21 22 23
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
24 25 26 27 28
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
29
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
30 31 32 33
////////////////////////////////////////////////////////////////////////

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

Alan Mishchenko committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
  Synopsis    [APIs to access LUT library.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int         Fpga_LutLibReadVarMax( Fpga_LutLib_t * p )               { return p->LutMax;     }
float *     Fpga_LutLibReadLutAreas( Fpga_LutLib_t * p )             { return p->pLutAreas;  }
float       Fpga_LutLibReadLutArea( Fpga_LutLib_t * p, int Size )    { assert( Size <= p->LutMax ); return p->pLutAreas[Size];  }

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

Alan Mishchenko committed
49 50 51 52 53 54 55 56 57
  Synopsis    [Reads the description of LUTs from the LUT library file.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
58
Fpga_LutLib_t * Fpga_LutLibRead( char * FileName, int fVerbose )
Alan Mishchenko committed
59 60 61 62
{
    char pBuffer[1000], * pToken;
    Fpga_LutLib_t * p;
    FILE * pFile;
Alan Mishchenko committed
63
    int i, k;
Alan Mishchenko committed
64 65 66 67 68 69 70 71

    pFile = fopen( FileName, "r" );
    if ( pFile == NULL )
    {
        printf( "Cannot open LUT library file \"%s\".\n", FileName );
        return NULL;
    }

Alan Mishchenko committed
72
    p = ABC_ALLOC( Fpga_LutLib_t, 1 );
Alan Mishchenko committed
73
    memset( p, 0, sizeof(Fpga_LutLib_t) );
Alan Mishchenko committed
74
    p->pName = Extra_UtilStrsav( FileName );
Alan Mishchenko committed
75 76 77 78 79 80 81 82 83 84 85 86

    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) )
        {
            printf( "Error in the LUT library file \"%s\".\n", FileName );
Alan Mishchenko committed
87
            ABC_FREE( p );
Alan Mishchenko committed
88 89 90
            return NULL;
        }

Alan Mishchenko committed
91
        // read area
Alan Mishchenko committed
92 93 94
        pToken = strtok( NULL, " \t\n" );
        p->pLutAreas[i] = (float)atof(pToken);

Alan Mishchenko committed
95 96
        // read delays
        k = 0;
Alan Mishchenko committed
97
        while ( (pToken = strtok( NULL, " \t\n" )) )
Alan Mishchenko committed
98 99 100 101 102 103 104 105 106 107 108 109
            p->pLutDelays[i][k++] = (float)atof(pToken);

        // check for out-of-bound
        if ( k > i )
        {
            printf( "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i );
            return NULL;
        }

        // check if var delays are specifies
        if ( k > 1 )
            p->fVarPinDelays = 1;
Alan Mishchenko committed
110 111 112 113

        if ( i == FPGA_MAX_LUTSIZE )
        {
            printf( "Skipping LUTs of size more than %d.\n", i );
Alan Mishchenko committed
114
            return NULL;
Alan Mishchenko committed
115 116 117 118
        }
        i++;
    }
    p->LutMax = i-1;
119
/*
Alan Mishchenko committed
120 121 122
    if ( p->LutMax > FPGA_MAX_LEAVES )
    {
        p->LutMax = FPGA_MAX_LEAVES;
Alan Mishchenko committed
123
        printf( "Warning: LUTs with more than %d inputs will not be used.\n", FPGA_MAX_LEAVES );
Alan Mishchenko committed
124
    }
125
*/
Alan Mishchenko committed
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
    // 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 )
                    printf( "Warning: 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] )
                    printf( "Warning: 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 )
                printf( "Warning: LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n", 
Alan Mishchenko committed
147
                    i, p->pLutDelays[i][0] );
Alan Mishchenko committed
148 149 150
        }
    }

Alan Mishchenko committed
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
    return p;
}

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

  Synopsis    [Duplicates the LUT library.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Fpga_LutLib_t * Fpga_LutLibDup( Fpga_LutLib_t * p )
{
    Fpga_LutLib_t * pNew;
Alan Mishchenko committed
168
    pNew = ABC_ALLOC( Fpga_LutLib_t, 1 );
Alan Mishchenko committed
169
    *pNew = *p;
Alan Mishchenko committed
170
    pNew->pName = Extra_UtilStrsav( pNew->pName );
Alan Mishchenko committed
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
    return pNew;
}

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

  Synopsis    [Frees the LUT library.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fpga_LutLibFree( Fpga_LutLib_t * pLutLib )
{
    if ( pLutLib == NULL )
        return;
Alan Mishchenko committed
189 190
    ABC_FREE( pLutLib->pName );
    ABC_FREE( pLutLib );
Alan Mishchenko committed
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
}


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

  Synopsis    [Prints the LUT library.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fpga_LutLibPrint( Fpga_LutLib_t * pLutLib )
{
Alan Mishchenko committed
207
    int i, k;
Alan Mishchenko committed
208 209
    printf( "# The area/delay of k-variable LUTs:\n" );
    printf( "# k    area     delay\n" );
Alan Mishchenko committed
210 211 212 213 214 215 216 217 218 219 220 221 222
    if ( pLutLib->fVarPinDelays )
    {
        for ( i = 1; i <= pLutLib->LutMax; i++ )
        {
            printf( "%d   %7.2f  ", i, pLutLib->pLutAreas[i] );
            for ( k = 0; k < i; k++ )
                printf( " %7.2f", pLutLib->pLutDelays[i][k] );
            printf( "\n" );
        }
    }
    else
        for ( i = 1; i <= pLutLib->LutMax; i++ )
            printf( "%d   %7.2f   %7.2f\n", i, pLutLib->pLutAreas[i], pLutLib->pLutDelays[i][0] );
Alan Mishchenko committed
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
}

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

  Synopsis    [Returns 1 if the delays are discrete.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fpga_LutLibDelaysAreDiscrete( Fpga_LutLib_t * pLutLib )
{
    float Delay;
    int i;
    for ( i = 1; i <= pLutLib->LutMax; i++ )
    {
Alan Mishchenko committed
242
        Delay = pLutLib->pLutDelays[i][0];
Alan Mishchenko committed
243 244 245 246 247 248 249 250 251 252 253
        if ( ((float)((int)Delay)) != Delay )
            return 0;
    }
    return 1;
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


254 255
ABC_NAMESPACE_IMPL_END