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