1 /**CFile****************************************************************
2 
3   FileName    [sclCon.h]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Standard-cell library representation.]
8 
9   Synopsis    [Constraint manager.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - August 24, 2012.]
16 
17   Revision    [$Id: sclCon.h,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #ifndef ABC__scl_Con__h
22 #define ABC__scl_Con__h
23 
24 ABC_NAMESPACE_HEADER_START
25 
26 ////////////////////////////////////////////////////////////////////////
27 ///                        DECLARATIONS                              ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 typedef struct Scl_Con_t_ Scl_Con_t;
31 struct Scl_Con_t_
32 {
33     char *         pFileName;   // constraint file name
34     char *         pModelName;  // current design name
35     char *         pInCellDef;  // default input driving gate
36     int            tInArrDef;   // default input arrival time
37     int            tInSlewDef;  // default input slew
38     int            tInLoadDef;  // default input load
39     int            tOutReqDef;  // default output required time
40     int            tOutLoadDef; // default output load
41     Vec_Ptr_t      vInCells;    // input driving gate names
42     Vec_Ptr_t      vInCellsPtr; // input driving gates
43     Vec_Int_t      vInArrs;     // input arrival times
44     Vec_Int_t      vInSlews;    // input slews
45     Vec_Int_t      vInLoads;    // input loads
46     Vec_Int_t      vOutReqs;    // output required times
47     Vec_Int_t      vOutLoads;   // output loads
48     Abc_Nam_t *    pNamI;       // input names
49     Abc_Nam_t *    pNamO;       // output names
50 };
51 
52 #define SCL_INPUT_CELL   "input_cell"
53 #define SCL_INPUT_ARR    "input_arrival"
54 #define SCL_INPUT_SLEW   "input_slew"
55 #define SCL_INPUT_LOAD   "input_load"
56 #define SCL_OUTPUT_REQ   "output_required"
57 #define SCL_OUTPUT_LOAD  "output_load"
58 
59 #define SCL_DIRECTIVE(ITEM)     "."#ITEM
60 #define SCL_DEF_DIRECTIVE(ITEM) ".default_"#ITEM
61 
62 #define SCL_NUM          1000
63 #define SCL_INFINITY    (0x3FFFFFFF)
64 
Scl_Flt2Int(float w)65 static inline int       Scl_Flt2Int( float w )   { return SCL_NUM*w;        }
Scl_Int2Flt(int i)66 static inline float     Scl_Int2Flt( int i )     { return (float)i/SCL_NUM; }
67 
68 ////////////////////////////////////////////////////////////////////////
69 ///                     FUNCTION DEFINITIONS                         ///
70 ////////////////////////////////////////////////////////////////////////
71 
72 /**Function*************************************************************
73 
74   Synopsis    [Manager construction.]
75 
76   Description []
77 
78   SideEffects []
79 
80   SeeAlso     []
81 
82 ***********************************************************************/
Scl_ConAlloc(char * pFileName,Abc_Nam_t * pNamI,Abc_Nam_t * pNamO)83 static inline Scl_Con_t * Scl_ConAlloc( char * pFileName, Abc_Nam_t * pNamI, Abc_Nam_t * pNamO )
84 {
85     Scl_Con_t * p  = ABC_CALLOC( Scl_Con_t, 1 );
86     p->pFileName   = Abc_UtilStrsav( pFileName );
87     p->pNamI       = pNamI;
88     p->pNamO       = pNamO;
89     p->pModelName  = NULL;
90     p->pInCellDef  = NULL;
91     p->tInArrDef   = SCL_INFINITY;
92     p->tInSlewDef  = SCL_INFINITY;
93     p->tInLoadDef  = SCL_INFINITY;
94     p->tOutReqDef  = SCL_INFINITY;
95     p->tOutLoadDef = SCL_INFINITY;
96     Vec_PtrFill( &p->vInCells,  Abc_NamObjNumMax(pNamI)-1, NULL );
97     Vec_IntFill( &p->vInArrs,   Abc_NamObjNumMax(pNamI)-1, SCL_INFINITY );
98     Vec_IntFill( &p->vInSlews,  Abc_NamObjNumMax(pNamI)-1, SCL_INFINITY );
99     Vec_IntFill( &p->vInLoads,  Abc_NamObjNumMax(pNamI)-1, SCL_INFINITY );
100     Vec_IntFill( &p->vOutReqs,  Abc_NamObjNumMax(pNamO)-1, SCL_INFINITY );
101     Vec_IntFill( &p->vOutLoads, Abc_NamObjNumMax(pNamO)-1, SCL_INFINITY );
102     return p;
103 }
Scl_ConFree(Scl_Con_t * p)104 static inline void Scl_ConFree( Scl_Con_t * p )
105 {
106     Vec_PtrErase( &p->vInCellsPtr );
107     Vec_PtrFreeData( &p->vInCells );
108     Vec_PtrErase( &p->vInCells );
109     Vec_IntErase( &p->vInArrs );
110     Vec_IntErase( &p->vInSlews );
111     Vec_IntErase( &p->vInLoads );
112     Vec_IntErase( &p->vOutReqs );
113     Vec_IntErase( &p->vOutLoads );
114     Abc_NamDeref( p->pNamI );
115     Abc_NamDeref( p->pNamO );
116     ABC_FREE( p->pInCellDef );
117     ABC_FREE( p->pModelName );
118     ABC_FREE( p->pFileName );
119     ABC_FREE( p );
120 }
121 
122 
123 /**Function*************************************************************
124 
125   Synopsis    [Manager serialization.]
126 
127   Description []
128 
129   SideEffects []
130 
131   SeeAlso     []
132 
133 ***********************************************************************/
Scl_ConParse(Scl_Con_t * p,Abc_Nam_t * pNamI,Abc_Nam_t * pNamO)134 static inline int Scl_ConParse( Scl_Con_t * p, Abc_Nam_t * pNamI, Abc_Nam_t * pNamO )
135 {
136     char Buffer[1000];
137     char * pToken, * pToken2, * pToken3, * pName;
138     int i, Num = -1, nLines = 0; int Value;
139     FILE * pFile = fopen( p->pFileName, "rb" );
140     while ( fgets( Buffer, 1000, pFile ) )
141     {
142         nLines++;
143         pToken = strtok( Buffer, " \t\r\n" );
144         if ( pToken == NULL )
145             continue;
146         pToken2 = strtok( NULL, " \t\r\n" );
147         if ( pToken2 == NULL )
148         {
149             printf( "Line %d: Skipping directive \"%s\" without argument.\n", nLines, pToken );
150             continue;
151         }
152         pToken3 = strtok( NULL, " \t\r\n" );
153         if ( !strcmp(pToken, ".model") )                                p->pModelName  = Abc_UtilStrsav(pToken2);
154         else if ( !strcmp(pToken, SCL_DEF_DIRECTIVE(SCL_INPUT_CELL)) )  p->pInCellDef  = Abc_UtilStrsav(pToken2);
155         else if ( !strcmp(pToken, SCL_DEF_DIRECTIVE(SCL_INPUT_ARR))  )  p->tInArrDef   = Scl_Flt2Int(atof(pToken2));
156         else if ( !strcmp(pToken, SCL_DEF_DIRECTIVE(SCL_INPUT_SLEW)) )  p->tInSlewDef  = Scl_Flt2Int(atof(pToken2));
157         else if ( !strcmp(pToken, SCL_DEF_DIRECTIVE(SCL_INPUT_LOAD)) )  p->tInLoadDef  = Scl_Flt2Int(atof(pToken2));
158         else if ( !strcmp(pToken, SCL_DEF_DIRECTIVE(SCL_OUTPUT_REQ)) )  p->tOutReqDef  = Scl_Flt2Int(atof(pToken2));
159         else if ( !strcmp(pToken, SCL_DEF_DIRECTIVE(SCL_OUTPUT_LOAD)))  p->tOutLoadDef = Scl_Flt2Int(atof(pToken2));
160         else if ( pToken3 == NULL ) { printf( "Directive %s should be followed by two arguments.\n", pToken ); continue; }
161         else if ( !strcmp(pToken, SCL_DIRECTIVE(SCL_INPUT_CELL))  )     if ( (Num = Abc_NamStrFind(pNamI, pToken2)) > 0 )  Vec_PtrWriteEntry( &p->vInCells,  Num-1, Abc_UtilStrsav(pToken3) );    else printf( "Line %d: Cannot find input \"%s\".\n", nLines, pToken2 );
162         else if ( !strcmp(pToken, SCL_DIRECTIVE(SCL_INPUT_ARR))   )     if ( (Num = Abc_NamStrFind(pNamI, pToken2)) > 0 )  Vec_IntWriteEntry( &p->vInArrs,   Num-1, Scl_Flt2Int(atof(pToken3)) ); else printf( "Line %d: Cannot find input \"%s\".\n", nLines, pToken2 );
163         else if ( !strcmp(pToken, SCL_DIRECTIVE(SCL_INPUT_SLEW))  )     if ( (Num = Abc_NamStrFind(pNamI, pToken2)) > 0 )  Vec_IntWriteEntry( &p->vInSlews,  Num-1, Scl_Flt2Int(atof(pToken3)) ); else printf( "Line %d: Cannot find input \"%s\".\n", nLines, pToken2 );
164         else if ( !strcmp(pToken, SCL_DIRECTIVE(SCL_INPUT_LOAD))  )     if ( (Num = Abc_NamStrFind(pNamI, pToken2)) > 0 )  Vec_IntWriteEntry( &p->vInLoads,  Num-1, Scl_Flt2Int(atof(pToken3)) ); else printf( "Line %d: Cannot find input \"%s\".\n", nLines, pToken2 );
165         else if ( !strcmp(pToken, SCL_DIRECTIVE(SCL_OUTPUT_REQ))  )     if ( (Num = Abc_NamStrFind(pNamO, pToken2)) > 0 )  Vec_IntWriteEntry( &p->vOutReqs,  Num-1, Scl_Flt2Int(atof(pToken3)) ); else printf( "Line %d: Cannot find output \"%s\".\n", nLines, pToken2 );
166         else if ( !strcmp(pToken, SCL_DIRECTIVE(SCL_OUTPUT_LOAD)) )     if ( (Num = Abc_NamStrFind(pNamO, pToken2)) > 0 )  Vec_IntWriteEntry( &p->vOutLoads, Num-1, Scl_Flt2Int(atof(pToken3)) ); else printf( "Line %d: Cannot find output \"%s\".\n", nLines, pToken2 );
167         else printf( "Line %d: Skipping unrecognized directive \"%s\".\n", nLines, pToken );
168     }
169     // set missing defaults
170     if ( p->pInCellDef  == NULL )          p->pInCellDef  = NULL; // consider using buffer from the current library
171     if ( p->tInArrDef   == SCL_INFINITY )  p->tInArrDef   = 0;
172     if ( p->tInSlewDef  == SCL_INFINITY )  p->tInSlewDef  = 0;
173     if ( p->tInLoadDef  == SCL_INFINITY )  p->tInLoadDef  = 0;
174     if ( p->tOutReqDef  == SCL_INFINITY )  p->tOutReqDef  = 0;
175     if ( p->tOutLoadDef == SCL_INFINITY )  p->tOutLoadDef = 0;
176     // set individual defaults
177     if ( p->pInCellDef )
178     Vec_PtrForEachEntry(char *, &p->vInCells, pName, i) if ( pName == NULL )          Vec_PtrWriteEntry( &p->vInCells,  i, Abc_UtilStrsav(p->pInCellDef) );
179     Vec_IntForEachEntry( &p->vInArrs, Value, i )        if ( Value == SCL_INFINITY )  Vec_IntWriteEntry( &p->vInArrs,   i, p->tInArrDef );
180     Vec_IntForEachEntry( &p->vInSlews, Value, i )       if ( Value == SCL_INFINITY )  Vec_IntWriteEntry( &p->vInSlews,  i, p->tInSlewDef );
181     Vec_IntForEachEntry( &p->vInLoads, Value, i )       if ( Value == SCL_INFINITY )  Vec_IntWriteEntry( &p->vInLoads,  i, p->tInLoadDef );
182     Vec_IntForEachEntry( &p->vOutReqs, Value, i )       if ( Value == SCL_INFINITY )  Vec_IntWriteEntry( &p->vOutReqs,  i, p->tOutReqDef );
183     Vec_IntForEachEntry( &p->vOutLoads, Value, i )      if ( Value == SCL_INFINITY )  Vec_IntWriteEntry( &p->vOutLoads, i, p->tOutLoadDef );
184 
185     fclose( pFile );
186     return 1;
187 }
Scl_ConRead(char * pFileName,Abc_Nam_t * pNamI,Abc_Nam_t * pNamO)188 static inline Scl_Con_t * Scl_ConRead( char * pFileName, Abc_Nam_t * pNamI, Abc_Nam_t * pNamO )
189 {
190     Scl_Con_t * p = Scl_ConAlloc( pFileName, pNamI, pNamO );
191     if ( Scl_ConParse(p, pNamI, pNamO) )
192         return p;
193     Scl_ConFree( p );
194     return NULL;
195 }
Scl_ConWrite(Scl_Con_t * p,char * pFileName)196 static inline void Scl_ConWrite( Scl_Con_t * p, char * pFileName )
197 {
198     char * pName; int Value; int i;
199     FILE * pFile = pFileName ? fopen( pFileName, "wb" ) : stdout;
200     if ( pFile == NULL )
201     {
202         printf( "Cannot open output file \"%s\".\n", pFileName );
203         return;
204     }
205     fprintf( pFile, ".model %s\n", p->pModelName );
206 
207     if ( p->pInCellDef )        fprintf( pFile, ".default_%s %s\n",   SCL_INPUT_CELL,  p->pInCellDef );
208     if ( p->tInArrDef   != 0 )  fprintf( pFile, ".default_%s %.2f\n", SCL_INPUT_ARR,   Scl_Int2Flt(p->tInArrDef) );
209     if ( p->tInSlewDef  != 0 )  fprintf( pFile, ".default_%s %.2f\n", SCL_INPUT_SLEW,  Scl_Int2Flt(p->tInSlewDef) );
210     if ( p->tInLoadDef  != 0 )  fprintf( pFile, ".default_%s %.2f\n", SCL_INPUT_LOAD,  Scl_Int2Flt(p->tInLoadDef) );
211     if ( p->tOutReqDef  != 0 )  fprintf( pFile, ".default_%s %.2f\n", SCL_OUTPUT_REQ,  Scl_Int2Flt(p->tOutReqDef) );
212     if ( p->tOutLoadDef != 0 )  fprintf( pFile, ".default_%s %.2f\n", SCL_OUTPUT_LOAD, Scl_Int2Flt(p->tOutLoadDef) );
213 
214     Vec_PtrForEachEntry(char *, &p->vInCells, pName, i) if ( pName && (!p->pInCellDef || strcmp(pName,p->pInCellDef)) )  fprintf( pFile, ".%s %s %s\n",   SCL_INPUT_CELL,  Abc_NamStr(p->pNamI, i+1), pName );
215     Vec_IntForEachEntry( &p->vInArrs, Value, i )        if ( Value != p->tInArrDef )   fprintf( pFile, ".%s %s %.2f\n", SCL_INPUT_ARR,   Abc_NamStr(p->pNamI, i+1), Scl_Int2Flt(Value) );
216     Vec_IntForEachEntry( &p->vInSlews, Value, i )       if ( Value != p->tInSlewDef )  fprintf( pFile, ".%s %s %.2f\n", SCL_INPUT_SLEW,  Abc_NamStr(p->pNamI, i+1), Scl_Int2Flt(Value) );
217     Vec_IntForEachEntry( &p->vInLoads, Value, i )       if ( Value != p->tInLoadDef )  fprintf( pFile, ".%s %s %.2f\n", SCL_INPUT_LOAD,  Abc_NamStr(p->pNamI, i+1), Scl_Int2Flt(Value) );
218     Vec_IntForEachEntry( &p->vOutReqs, Value, i )       if ( Value != p->tOutReqDef )  fprintf( pFile, ".%s %s %.2f\n", SCL_OUTPUT_REQ,  Abc_NamStr(p->pNamO, i+1), Scl_Int2Flt(Value) );
219     Vec_IntForEachEntry( &p->vOutLoads, Value, i )      if ( Value != p->tOutLoadDef ) fprintf( pFile, ".%s %s %.2f\n", SCL_OUTPUT_LOAD, Abc_NamStr(p->pNamO, i+1), Scl_Int2Flt(Value) );
220 
221     if ( pFile != stdout )
222         fclose ( pFile );
223 }
224 
225 /**Function*************************************************************
226 
227   Synopsis    [Internal APIs.]
228 
229   Description []
230 
231   SideEffects []
232 
233   SeeAlso     []
234 
235 ***********************************************************************/
Scl_ConHasInCells_(Scl_Con_t * p)236 static inline int    Scl_ConHasInCells_( Scl_Con_t * p )        { return Vec_PtrCountZero(&p->vInCells)  != Vec_PtrSize(&p->vInCells);  }
Scl_ConHasInArrs_(Scl_Con_t * p)237 static inline int    Scl_ConHasInArrs_( Scl_Con_t * p )         { return Vec_IntCountZero(&p->vInArrs)   != Vec_IntSize(&p->vInArrs);   }
Scl_ConHasInSlews_(Scl_Con_t * p)238 static inline int    Scl_ConHasInSlews_( Scl_Con_t * p )        { return Vec_IntCountZero(&p->vInSlews)  != Vec_IntSize(&p->vInSlews);  }
Scl_ConHasInLoads_(Scl_Con_t * p)239 static inline int    Scl_ConHasInLoads_( Scl_Con_t * p )        { return Vec_IntCountZero(&p->vInLoads)  != Vec_IntSize(&p->vInLoads);  }
Scl_ConHasOutReqs_(Scl_Con_t * p)240 static inline int    Scl_ConHasOutReqs_( Scl_Con_t * p )        { return Vec_IntCountZero(&p->vOutReqs)  != Vec_IntSize(&p->vOutReqs);  }
Scl_ConHasOutLoads_(Scl_Con_t * p)241 static inline int    Scl_ConHasOutLoads_( Scl_Con_t * p )       { return Vec_IntCountZero(&p->vOutLoads) != Vec_IntSize(&p->vOutLoads); }
242 
Scl_ConGetInCell_(Scl_Con_t * p,int i)243 static inline char * Scl_ConGetInCell_( Scl_Con_t * p, int i )  { return (char*)Vec_PtrEntry( &p->vInCells,  i ); }
Scl_ConGetInArr_(Scl_Con_t * p,int i)244 static inline int    Scl_ConGetInArr_( Scl_Con_t * p, int i )   { return Vec_IntEntry( &p->vInArrs,   i ); }
Scl_ConGetInSlew_(Scl_Con_t * p,int i)245 static inline int    Scl_ConGetInSlew_( Scl_Con_t * p, int i )  { return Vec_IntEntry( &p->vInSlews,  i ); }
Scl_ConGetInLoad_(Scl_Con_t * p,int i)246 static inline int    Scl_ConGetInLoad_( Scl_Con_t * p, int i )  { return Vec_IntEntry( &p->vInLoads,  i ); }
Scl_ConGetOutReq_(Scl_Con_t * p,int i)247 static inline int    Scl_ConGetOutReq_( Scl_Con_t * p, int i )  { return Vec_IntEntry( &p->vOutReqs,  i ); }
Scl_ConGetOutLoad_(Scl_Con_t * p,int i)248 static inline int    Scl_ConGetOutLoad_( Scl_Con_t * p, int i ) { return Vec_IntEntry( &p->vOutLoads, i ); }
249 
250 /**Function*************************************************************
251 
252   Synopsis    [External APIs.]
253 
254   Description []
255 
256   SideEffects []
257 
258   SeeAlso     []
259 
260 ***********************************************************************/
261 extern Scl_Con_t *   Scl_ConReadMan();
262 
Scl_ConIsRunning()263 static inline int    Scl_ConIsRunning()               { return Scl_ConReadMan() != NULL;                  }
264 
Scl_ConHasInCells()265 static inline int    Scl_ConHasInCells()              { return Scl_ConHasInCells_ ( Scl_ConReadMan() );   }
Scl_ConHasInArrs()266 static inline int    Scl_ConHasInArrs()               { return Scl_ConHasInArrs_  ( Scl_ConReadMan() );   }
Scl_ConHasInSlews()267 static inline int    Scl_ConHasInSlews()              { return Scl_ConHasInSlews_ ( Scl_ConReadMan() );   }
Scl_ConHasInLoads()268 static inline int    Scl_ConHasInLoads()              { return Scl_ConHasInLoads_ ( Scl_ConReadMan() );   }
Scl_ConHasOutReqs()269 static inline int    Scl_ConHasOutReqs()              { return Scl_ConHasOutReqs_ ( Scl_ConReadMan() );   }
Scl_ConHasOutLoads()270 static inline int    Scl_ConHasOutLoads()             { return Scl_ConHasOutLoads_( Scl_ConReadMan() );   }
271 
Scl_ConGetInCell(int i)272 static inline char * Scl_ConGetInCell( int i )        { return Scl_ConGetInCell_ ( Scl_ConReadMan(), i ); }
Scl_ConGetInArr(int i)273 static inline int    Scl_ConGetInArr( int i )         { return Scl_ConGetInArr_  ( Scl_ConReadMan(), i ); }
Scl_ConGetInSlew(int i)274 static inline int    Scl_ConGetInSlew( int i )        { return Scl_ConGetInSlew_ ( Scl_ConReadMan(), i ); }
Scl_ConGetInLoad(int i)275 static inline int    Scl_ConGetInLoad( int i )        { return Scl_ConGetInLoad_ ( Scl_ConReadMan(), i ); }
Scl_ConGetOutReq(int i)276 static inline int    Scl_ConGetOutReq( int i )        { return Scl_ConGetOutReq_ ( Scl_ConReadMan(), i ); }
Scl_ConGetOutLoad(int i)277 static inline int    Scl_ConGetOutLoad( int i )       { return Scl_ConGetOutLoad_( Scl_ConReadMan(), i ); }
278 
Scl_ConGetInArrFloat(int i)279 static inline float  Scl_ConGetInArrFloat( int i )    { return Scl_Int2Flt( Scl_ConGetInArr(i) );         }
Scl_ConGetInSlewFloat(int i)280 static inline float  Scl_ConGetInSlewFloat( int i )   { return Scl_Int2Flt( Scl_ConGetInSlew(i) );        }
Scl_ConGetInLoadFloat(int i)281 static inline float  Scl_ConGetInLoadFloat( int i )   { return Scl_Int2Flt( Scl_ConGetInLoad(i) );        }
Scl_ConGetOutReqFloat(int i)282 static inline float  Scl_ConGetOutReqFloat( int i )   { return Scl_Int2Flt( Scl_ConGetOutReq(i) );        }
Scl_ConGetOutLoadFloat(int i)283 static inline float  Scl_ConGetOutLoadFloat( int i )  { return Scl_Int2Flt( Scl_ConGetOutLoad(i) );       }
284 
285 
286 ABC_NAMESPACE_HEADER_END
287 
288 #endif
289 
290 ////////////////////////////////////////////////////////////////////////
291 ///                       END OF FILE                                ///
292 ////////////////////////////////////////////////////////////////////////
293 
294