1 /**CFile****************************************************************
2 
3   FileName    [ifLibLut.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [FPGA mapping based on priority cuts.]
8 
9   Synopsis    [LUT library.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - November 21, 2006.]
16 
17   Revision    [$Id: ifLibLut.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "if.h"
22 #include "base/main/mainInt.h"
23 
24 ABC_NAMESPACE_IMPL_START
25 
26 
27 ////////////////////////////////////////////////////////////////////////
28 ///                        DECLARATIONS                              ///
29 ////////////////////////////////////////////////////////////////////////
30 
31 ////////////////////////////////////////////////////////////////////////
32 ///                     FUNCTION DEFINITIONS                         ///
33 ////////////////////////////////////////////////////////////////////////
34 
35 /**Function*************************************************************
36 
37   Synopsis    [Reads the description of LUTs from the LUT library file.]
38 
39   Description []
40 
41   SideEffects []
42 
43   SeeAlso     []
44 
45 ***********************************************************************/
If_LibLutReadString(char * pStr)46 If_LibLut_t * If_LibLutReadString( char * pStr )
47 {
48     If_LibLut_t * p;
49     Vec_Ptr_t * vStrs;
50     char * pToken, * pBuffer, * pStrNew, * pStrMem;
51     int i, k, j;
52 
53     if ( pStr == NULL || pStr[0] == 0 )
54         return NULL;
55 
56     vStrs = Vec_PtrAlloc( 1000 );
57     pStrNew = pStrMem = Abc_UtilStrsav( pStr );
58     while ( *pStrNew )
59     {
60         Vec_PtrPush( vStrs, pStrNew );
61         while ( *pStrNew != '\n' )
62             pStrNew++;
63         while ( *pStrNew == '\n' )
64             *pStrNew++ = '\0';
65     }
66 
67     p = ABC_ALLOC( If_LibLut_t, 1 );
68     memset( p, 0, sizeof(If_LibLut_t) );
69 
70     i = 1;
71     //while ( fgets( pBuffer, 1000, pFile ) != NULL )
72     Vec_PtrForEachEntry( char *, vStrs, pBuffer, j )
73     {
74         if ( pBuffer[0] == 0 )
75             continue;
76         pToken = strtok( pBuffer, " \t\n" );
77         if ( pToken == NULL )
78             continue;
79         if ( pToken[0] == '#' )
80             continue;
81         if ( i != atoi(pToken) )
82         {
83             Abc_Print( 1, "Error in the LUT library string.\n" );
84             ABC_FREE( p->pName );
85             ABC_FREE( p );
86             ABC_FREE( pStrMem );
87             Vec_PtrFree( vStrs );
88             return NULL;
89         }
90 
91         // read area
92         pToken = strtok( NULL, " \t\n" );
93         p->pLutAreas[i] = (float)atof(pToken);
94 
95         // read delays
96         k = 0;
97         while ( (pToken = strtok( NULL, " \t\n" )) )
98             p->pLutDelays[i][k++] = (float)atof(pToken);
99 
100         // check for out-of-bound
101         if ( k > i )
102         {
103             Abc_Print( 1, "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i );
104             ABC_FREE( p->pName );
105             ABC_FREE( p );
106             ABC_FREE( pStrMem );
107             Vec_PtrFree( vStrs );
108             return NULL;
109         }
110 
111         // check if var delays are specified
112         if ( k > 1 )
113             p->fVarPinDelays = 1;
114 
115         if ( i == IF_MAX_LUTSIZE )
116         {
117             Abc_Print( 1, "Skipping LUTs of size more than %d.\n", i );
118             ABC_FREE( p->pName );
119             ABC_FREE( p );
120             ABC_FREE( pStrMem );
121             Vec_PtrFree( vStrs );
122             return NULL;
123         }
124         i++;
125     }
126     p->LutMax = i-1;
127 
128     // check the library
129     if ( p->fVarPinDelays )
130     {
131         for ( i = 1; i <= p->LutMax; i++ )
132             for ( k = 0; k < i; k++ )
133             {
134                 if ( p->pLutDelays[i][k] <= 0.0 )
135                     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",
136                         k, i, p->pLutDelays[i][k] );
137                 if ( k && p->pLutDelays[i][k-1] > p->pLutDelays[i][k] )
138                     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",
139                         k-1, i, p->pLutDelays[i][k-1],
140                         k, i, p->pLutDelays[i][k] );
141             }
142     }
143     else
144     {
145         for ( i = 1; i <= p->LutMax; i++ )
146         {
147             if ( p->pLutDelays[i][0] <= 0.0 )
148                 Abc_Print( 0, "LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n",
149                     i, p->pLutDelays[i][0] );
150         }
151     }
152 
153     // cleanup
154     ABC_FREE( pStrMem );
155     Vec_PtrFree( vStrs );
156     return p;
157 }
158 
159 /**Function*************************************************************
160 
161   Synopsis    [Sets the library associated with the string.]
162 
163   Description []
164 
165   SideEffects []
166 
167   SeeAlso     []
168 
169 ***********************************************************************/
Abc_FrameSetLutLibrary(Abc_Frame_t * pAbc,char * pLutLibString)170 int Abc_FrameSetLutLibrary( Abc_Frame_t * pAbc, char * pLutLibString )
171 {
172     If_LibLut_t * pLib = If_LibLutReadString( pLutLibString );
173     if ( pLib == NULL )
174     {
175         fprintf( stdout, "Reading LUT library from string has failed.\n" );
176         return 0;
177     }
178     // replace the current library
179     If_LibLutFree( (If_LibLut_t *)Abc_FrameReadLibLut() );
180     Abc_FrameSetLibLut( pLib );
181     return 1;
182 }
Abc_FrameSetLutLibraryTest(Abc_Frame_t * pAbc)183 int Abc_FrameSetLutLibraryTest( Abc_Frame_t * pAbc )
184 {
185     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";
186     Abc_FrameSetLutLibrary( pAbc, pStr );
187     return 1;
188 }
189 
190 
191 /**Function*************************************************************
192 
193   Synopsis    [Reads the description of LUTs from the LUT library file.]
194 
195   Description []
196 
197   SideEffects []
198 
199   SeeAlso     []
200 
201 ***********************************************************************/
If_LibLutRead(char * FileName)202 If_LibLut_t * If_LibLutRead( char * FileName )
203 {
204     char pBuffer[1000], * pToken;
205     If_LibLut_t * p;
206     FILE * pFile;
207     int i, k;
208 
209     pFile = fopen( FileName, "r" );
210     if ( pFile == NULL )
211     {
212         Abc_Print( -1, "Cannot open LUT library file \"%s\".\n", FileName );
213         return NULL;
214     }
215 
216     p = ABC_ALLOC( If_LibLut_t, 1 );
217     memset( p, 0, sizeof(If_LibLut_t) );
218     p->pName = Abc_UtilStrsav( FileName );
219 
220     i = 1;
221     while ( fgets( pBuffer, 1000, pFile ) != NULL )
222     {
223         pToken = strtok( pBuffer, " \t\n" );
224         if ( pToken == NULL )
225             continue;
226         if ( pToken[0] == '#' )
227             continue;
228         if ( i != atoi(pToken) )
229         {
230             Abc_Print( 1, "Error in the LUT library file \"%s\".\n", FileName );
231             ABC_FREE( p->pName );
232             ABC_FREE( p );
233             fclose( pFile );
234             return NULL;
235         }
236 
237         // read area
238         pToken = strtok( NULL, " \t\n" );
239         p->pLutAreas[i] = (float)atof(pToken);
240 
241         // read delays
242         k = 0;
243         while ( (pToken = strtok( NULL, " \t\n" )) )
244             p->pLutDelays[i][k++] = (float)atof(pToken);
245 
246         // check for out-of-bound
247         if ( k > i )
248         {
249             ABC_FREE( p->pName );
250             ABC_FREE( p );
251             Abc_Print( 1, "LUT %d has too many pins (%d). Max allowed is %d.\n", i, k, i );
252             fclose( pFile );
253             return NULL;
254         }
255 
256         // check if var delays are specified
257         if ( k > 1 )
258             p->fVarPinDelays = 1;
259 
260         if ( i == IF_MAX_LUTSIZE )
261         {
262             ABC_FREE( p->pName );
263             ABC_FREE( p );
264             Abc_Print( 1, "Skipping LUTs of size more than %d.\n", i );
265             fclose( pFile );
266             return NULL;
267         }
268         i++;
269     }
270     p->LutMax = i-1;
271 
272     // check the library
273     if ( p->fVarPinDelays )
274     {
275         for ( i = 1; i <= p->LutMax; i++ )
276             for ( k = 0; k < i; k++ )
277             {
278                 if ( p->pLutDelays[i][k] <= 0.0 )
279                     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",
280                         k, i, p->pLutDelays[i][k] );
281                 if ( k && p->pLutDelays[i][k-1] > p->pLutDelays[i][k] )
282                     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",
283                         k-1, i, p->pLutDelays[i][k-1],
284                         k, i, p->pLutDelays[i][k] );
285             }
286     }
287     else
288     {
289         for ( i = 1; i <= p->LutMax; i++ )
290         {
291             if ( p->pLutDelays[i][0] <= 0.0 )
292                 Abc_Print( 0, "LUT %d has delay %f. Pin delays should be non-negative numbers. Technology mapping may not work correctly.\n",
293                     i, p->pLutDelays[i][0] );
294         }
295     }
296 
297     fclose( pFile );
298     return p;
299 }
300 
301 /**Function*************************************************************
302 
303   Synopsis    [Duplicates the LUT library.]
304 
305   Description []
306 
307   SideEffects []
308 
309   SeeAlso     []
310 
311 ***********************************************************************/
If_LibLutDup(If_LibLut_t * p)312 If_LibLut_t * If_LibLutDup( If_LibLut_t * p )
313 {
314     If_LibLut_t * pNew;
315     pNew = ABC_ALLOC( If_LibLut_t, 1 );
316     *pNew = *p;
317     pNew->pName = Abc_UtilStrsav( pNew->pName );
318     return pNew;
319 }
320 
321 /**Function*************************************************************
322 
323   Synopsis    [Frees the LUT library.]
324 
325   Description []
326 
327   SideEffects []
328 
329   SeeAlso     []
330 
331 ***********************************************************************/
If_LibLutFree(If_LibLut_t * pLutLib)332 void If_LibLutFree( If_LibLut_t * pLutLib )
333 {
334     if ( pLutLib == NULL )
335         return;
336     ABC_FREE( pLutLib->pName );
337     ABC_FREE( pLutLib );
338 }
339 
340 
341 /**Function*************************************************************
342 
343   Synopsis    [Prints the LUT library.]
344 
345   Description []
346 
347   SideEffects []
348 
349   SeeAlso     []
350 
351 ***********************************************************************/
If_LibLutPrint(If_LibLut_t * pLutLib)352 void If_LibLutPrint( If_LibLut_t * pLutLib )
353 {
354     int i, k;
355     Abc_Print( 1, "# The area/delay of k-variable LUTs:\n" );
356     Abc_Print( 1, "# k    area     delay\n" );
357     if ( pLutLib->fVarPinDelays )
358     {
359         for ( i = 1; i <= pLutLib->LutMax; i++ )
360         {
361             Abc_Print( 1, "%d   %7.2f  ", i, pLutLib->pLutAreas[i] );
362             for ( k = 0; k < i; k++ )
363                 Abc_Print( 1, " %7.2f", pLutLib->pLutDelays[i][k] );
364             Abc_Print( 1, "\n" );
365         }
366     }
367     else
368         for ( i = 1; i <= pLutLib->LutMax; i++ )
369             Abc_Print( 1, "%d   %7.2f   %7.2f\n", i, pLutLib->pLutAreas[i], pLutLib->pLutDelays[i][0] );
370 }
371 
372 /**Function*************************************************************
373 
374   Synopsis    [Returns 1 if the delays are discrete.]
375 
376   Description []
377 
378   SideEffects []
379 
380   SeeAlso     []
381 
382 ***********************************************************************/
If_LibLutDelaysAreDiscrete(If_LibLut_t * pLutLib)383 int If_LibLutDelaysAreDiscrete( If_LibLut_t * pLutLib )
384 {
385     float Delay;
386     int i;
387     for ( i = 1; i <= pLutLib->LutMax; i++ )
388     {
389         Delay = pLutLib->pLutDelays[i][0];
390         if ( ((float)((int)Delay)) != Delay )
391             return 0;
392     }
393     return 1;
394 }
395 
396 /**Function*************************************************************
397 
398   Synopsis    [Returns 1 if the delays are discrete.]
399 
400   Description []
401 
402   SideEffects []
403 
404   SeeAlso     []
405 
406 ***********************************************************************/
If_LibLutDelaysAreDifferent(If_LibLut_t * pLutLib)407 int If_LibLutDelaysAreDifferent( If_LibLut_t * pLutLib )
408 {
409     int i, k;
410     float Delay = pLutLib->pLutDelays[1][0];
411     if ( pLutLib->fVarPinDelays )
412     {
413         for ( i = 2; i <= pLutLib->LutMax; i++ )
414         for ( k = 0; k < i; k++ )
415             if ( pLutLib->pLutDelays[i][k] != Delay )
416                 return 1;
417     }
418     else
419     {
420         for ( i = 2; i <= pLutLib->LutMax; i++ )
421             if ( pLutLib->pLutDelays[i][0] != Delay )
422                 return 1;
423     }
424     return 0;
425 }
426 
427 /**Function*************************************************************
428 
429   Synopsis    [Sets simple LUT library.]
430 
431   Description []
432 
433   SideEffects []
434 
435   SeeAlso     []
436 
437 ***********************************************************************/
If_LibLutSetSimple(int nLutSize)438 If_LibLut_t * If_LibLutSetSimple( int nLutSize )
439 {
440     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}} };
441     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}} };
442     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}} };
443     If_LibLut_t s_LutLib7 = { "lutlib", 7, 0, {0,1,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1},{1}} };
444     If_LibLut_t s_LutLib6 = { "lutlib", 6, 0, {0,1,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1},{1}} };
445     If_LibLut_t s_LutLib5 = { "lutlib", 5, 0, {0,1,1,1,1,1}, {{0},{1},{1},{1},{1},{1}} };
446     If_LibLut_t s_LutLib4 = { "lutlib", 4, 0, {0,1,1,1,1}, {{0},{1},{1},{1},{1}} };
447     If_LibLut_t s_LutLib3 = { "lutlib", 3, 0, {0,1,1,1}, {{0},{1},{1},{1}} };
448     If_LibLut_t * pLutLib;
449     assert( nLutSize >= 3 && nLutSize <= 10 );
450     switch ( nLutSize )
451     {
452         case 3:  pLutLib = &s_LutLib3; break;
453         case 4:  pLutLib = &s_LutLib4; break;
454         case 5:  pLutLib = &s_LutLib5; break;
455         case 6:  pLutLib = &s_LutLib6; break;
456         case 7:  pLutLib = &s_LutLib7; break;
457         case 8:  pLutLib = &s_LutLib8; break;
458         case 9:  pLutLib = &s_LutLib9; break;
459         case 10: pLutLib = &s_LutLib10; break;
460         default: pLutLib = NULL; break;
461     }
462     if ( pLutLib == NULL )
463         return NULL;
464     return If_LibLutDup(pLutLib);
465 }
466 
467 /**Function*************************************************************
468 
469   Synopsis    [Gets the delay of the fastest pin.]
470 
471   Description []
472 
473   SideEffects []
474 
475   SeeAlso     []
476 
477 ***********************************************************************/
If_LibLutFastestPinDelay(If_LibLut_t * p)478 float If_LibLutFastestPinDelay( If_LibLut_t * p )
479 {
480     return !p? 1.0 : p->pLutDelays[p->LutMax][0];
481 }
482 
483 /**Function*************************************************************
484 
485   Synopsis    [Gets the delay of the slowest pin.]
486 
487   Description []
488 
489   SideEffects []
490 
491   SeeAlso     []
492 
493 ***********************************************************************/
If_LibLutSlowestPinDelay(If_LibLut_t * p)494 float If_LibLutSlowestPinDelay( If_LibLut_t * p )
495 {
496     return !p? 1.0 : (p->fVarPinDelays? p->pLutDelays[p->LutMax][p->LutMax-1]: p->pLutDelays[p->LutMax][0]);
497 }
498 
499 ////////////////////////////////////////////////////////////////////////
500 ///                       END OF FILE                                ///
501 ////////////////////////////////////////////////////////////////////////
502 
503 
504 ABC_NAMESPACE_IMPL_END
505 
506