1 /**CFile****************************************************************
2 
3   FileName    [fraHot.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [New FRAIG package.]
8 
9   Synopsis    [Computing and using one-hotness conditions.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 30, 2007.]
16 
17   Revision    [$Id: fraHot.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "fra.h"
22 
23 ABC_NAMESPACE_IMPL_START
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 ///                        DECLARATIONS                              ///
28 ////////////////////////////////////////////////////////////////////////
29 
Fra_RegToLit(int n,int c)30 static inline int  Fra_RegToLit( int n, int c )   { return c? -n-1 : n+1;       }
Fra_LitReg(int n)31 static inline int  Fra_LitReg( int n )            { return (n>0)? n-1 : -n-1;   }
Fra_LitSign(int n)32 static inline int  Fra_LitSign( int n )           { return (n<0);               }
33 
34 ////////////////////////////////////////////////////////////////////////
35 ///                     FUNCTION DEFINITIONS                         ///
36 ////////////////////////////////////////////////////////////////////////
37 
38 /**Function*************************************************************
39 
40   Synopsis    [Returns 1 if simulation info is composed of all zeros.]
41 
42   Description []
43 
44   SideEffects []
45 
46   SeeAlso     []
47 
48 ***********************************************************************/
Fra_OneHotNodeIsConst(Fra_Sml_t * pSeq,Aig_Obj_t * pObj)49 int Fra_OneHotNodeIsConst( Fra_Sml_t * pSeq, Aig_Obj_t * pObj )
50 {
51     unsigned * pSims;
52     int i;
53     pSims = Fra_ObjSim(pSeq, pObj->Id);
54     for ( i = pSeq->nWordsPref; i < pSeq->nWordsTotal; i++ )
55         if ( pSims[i] )
56             return 0;
57     return 1;
58 }
59 
60 /**Function*************************************************************
61 
62   Synopsis    [Returns 1 if simulation infos are equal.]
63 
64   Description []
65 
66   SideEffects []
67 
68   SeeAlso     []
69 
70 ***********************************************************************/
Fra_OneHotNodesAreEqual(Fra_Sml_t * pSeq,Aig_Obj_t * pObj0,Aig_Obj_t * pObj1)71 int Fra_OneHotNodesAreEqual( Fra_Sml_t * pSeq, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
72 {
73     unsigned * pSims0, * pSims1;
74     int i;
75     pSims0 = Fra_ObjSim(pSeq, pObj0->Id);
76     pSims1 = Fra_ObjSim(pSeq, pObj1->Id);
77     for ( i = pSeq->nWordsPref; i < pSeq->nWordsTotal; i++ )
78         if ( pSims0[i] != pSims1[i] )
79             return 0;
80     return 1;
81 }
82 
83 /**Function*************************************************************
84 
85   Synopsis    [Returns 1 if implications holds.]
86 
87   Description []
88 
89   SideEffects []
90 
91   SeeAlso     []
92 
93 ***********************************************************************/
Fra_OneHotNodesAreClause(Fra_Sml_t * pSeq,Aig_Obj_t * pObj1,Aig_Obj_t * pObj2,int fCompl1,int fCompl2)94 int Fra_OneHotNodesAreClause( Fra_Sml_t * pSeq, Aig_Obj_t * pObj1, Aig_Obj_t * pObj2, int fCompl1, int fCompl2 )
95 {
96     unsigned * pSim1, * pSim2;
97     int k;
98     pSim1 = Fra_ObjSim(pSeq, pObj1->Id);
99     pSim2 = Fra_ObjSim(pSeq, pObj2->Id);
100     if ( fCompl1 && fCompl2 )
101     {
102         for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ )
103             if ( pSim1[k] & pSim2[k] )
104                 return 0;
105     }
106     else if ( fCompl1 )
107     {
108         for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ )
109             if ( pSim1[k] & ~pSim2[k] )
110                 return 0;
111     }
112     else if ( fCompl2 )
113     {
114         for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ )
115             if ( ~pSim1[k] & pSim2[k] )
116                 return 0;
117     }
118     else
119         assert( 0 );
120     return 1;
121 }
122 
123 /**Function*************************************************************
124 
125   Synopsis    [Computes one-hot implications.]
126 
127   Description []
128 
129   SideEffects []
130 
131   SeeAlso     []
132 
133 ***********************************************************************/
Fra_OneHotCompute(Fra_Man_t * p,Fra_Sml_t * pSim)134 Vec_Int_t * Fra_OneHotCompute( Fra_Man_t * p, Fra_Sml_t * pSim )
135 {
136     int fSkipConstEqu = 1;
137     Vec_Int_t * vOneHots;
138     Aig_Obj_t * pObj1, * pObj2;
139     int i, k;
140     int nTruePis = Aig_ManCiNum(pSim->pAig) - Aig_ManRegNum(pSim->pAig);
141     assert( pSim->pAig == p->pManAig );
142     vOneHots = Vec_IntAlloc( 100 );
143     Aig_ManForEachLoSeq( pSim->pAig, pObj1, i )
144     {
145         if ( fSkipConstEqu && Fra_OneHotNodeIsConst(pSim, pObj1) )
146             continue;
147         assert( i-nTruePis >= 0 );
148 //        Aig_ManForEachLoSeq( pSim->pAig, pObj2, k )
149 //        Vec_PtrForEachEntryStart( Aig_Obj_t *, pSim->pAig->vPis, pObj2, k, Aig_ManCiNum(p)-Aig_ManRegNum(p) )
150         Vec_PtrForEachEntryStart( Aig_Obj_t *, pSim->pAig->vCis, pObj2, k, i+1 )
151         {
152             if ( fSkipConstEqu && Fra_OneHotNodeIsConst(pSim, pObj2) )
153                 continue;
154             if ( fSkipConstEqu && Fra_OneHotNodesAreEqual( pSim, pObj1, pObj2 ) )
155                 continue;
156             assert( k-nTruePis >= 0 );
157             if ( Fra_OneHotNodesAreClause( pSim, pObj1, pObj2, 1, 1 ) )
158             {
159                 Vec_IntPush( vOneHots, Fra_RegToLit(i-nTruePis, 1) );
160                 Vec_IntPush( vOneHots, Fra_RegToLit(k-nTruePis, 1) );
161                 continue;
162             }
163             if ( Fra_OneHotNodesAreClause( pSim, pObj1, pObj2, 0, 1 ) )
164             {
165                 Vec_IntPush( vOneHots, Fra_RegToLit(i-nTruePis, 0) );
166                 Vec_IntPush( vOneHots, Fra_RegToLit(k-nTruePis, 1) );
167                 continue;
168             }
169             if ( Fra_OneHotNodesAreClause( pSim, pObj1, pObj2, 1, 0 ) )
170             {
171                 Vec_IntPush( vOneHots, Fra_RegToLit(i-nTruePis, 1) );
172                 Vec_IntPush( vOneHots, Fra_RegToLit(k-nTruePis, 0) );
173                 continue;
174             }
175         }
176     }
177     return vOneHots;
178 }
179 
180 /**Function*************************************************************
181 
182   Synopsis    [Assumes one-hot implications in the SAT solver.]
183 
184   Description []
185 
186   SideEffects []
187 
188   SeeAlso     []
189 
190 **********************************************************************/
Fra_OneHotAssume(Fra_Man_t * p,Vec_Int_t * vOneHots)191 void Fra_OneHotAssume( Fra_Man_t * p, Vec_Int_t * vOneHots )
192 {
193     Aig_Obj_t * pObj1, * pObj2;
194     int i, Out1, Out2, pLits[2];
195     int nPiNum = Aig_ManCiNum(p->pManFraig) - Aig_ManRegNum(p->pManFraig);
196     assert( p->pPars->nFramesK == 1 ); // add to only one frame
197     for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 )
198     {
199         Out1 = Vec_IntEntry( vOneHots, i );
200         Out2 = Vec_IntEntry( vOneHots, i+1 );
201         if ( Out1 == 0 && Out2 == 0 )
202             continue;
203         pObj1 = Aig_ManCi( p->pManFraig, nPiNum + Fra_LitReg(Out1) );
204         pObj2 = Aig_ManCi( p->pManFraig, nPiNum + Fra_LitReg(Out2) );
205         pLits[0] = toLitCond( Fra_ObjSatNum(pObj1), Fra_LitSign(Out1) );
206         pLits[1] = toLitCond( Fra_ObjSatNum(pObj2), Fra_LitSign(Out2) );
207         // add constraint to solver
208         if ( !sat_solver_addclause( p->pSat, pLits, pLits + 2 ) )
209         {
210             printf( "Fra_OneHotAssume(): Adding clause makes SAT solver unsat.\n" );
211             sat_solver_delete( p->pSat );
212             p->pSat = NULL;
213             return;
214         }
215     }
216 }
217 
218 /**Function*************************************************************
219 
220   Synopsis    [Checks one-hot implications.]
221 
222   Description []
223 
224   SideEffects []
225 
226   SeeAlso     []
227 
228 **********************************************************************/
Fra_OneHotCheck(Fra_Man_t * p,Vec_Int_t * vOneHots)229 void Fra_OneHotCheck( Fra_Man_t * p, Vec_Int_t * vOneHots )
230 {
231     Aig_Obj_t * pObj1, * pObj2;
232     int RetValue, i, Out1, Out2;
233     int nTruePos = Aig_ManCoNum(p->pManFraig) - Aig_ManRegNum(p->pManFraig);
234     for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 )
235     {
236         Out1 = Vec_IntEntry( vOneHots, i );
237         Out2 = Vec_IntEntry( vOneHots, i+1 );
238         if ( Out1 == 0 && Out2 == 0 )
239             continue;
240         pObj1 = Aig_ManCo( p->pManFraig, nTruePos + Fra_LitReg(Out1) );
241         pObj2 = Aig_ManCo( p->pManFraig, nTruePos + Fra_LitReg(Out2) );
242         RetValue = Fra_NodesAreClause( p, pObj1, pObj2, Fra_LitSign(Out1), Fra_LitSign(Out2) );
243         if ( RetValue != 1 )
244         {
245             p->pCla->fRefinement = 1;
246             if ( RetValue == 0 )
247                 Fra_SmlResimulate( p );
248             if ( Vec_IntEntry(vOneHots, i) != 0 )
249                 printf( "Fra_OneHotCheck(): Clause is not refined!\n" );
250             assert( Vec_IntEntry(vOneHots, i) == 0 );
251         }
252     }
253 }
254 
255 /**Function*************************************************************
256 
257   Synopsis    [Removes those implications that no longer hold.]
258 
259   Description [Returns 1 if refinement has happened.]
260 
261   SideEffects []
262 
263   SeeAlso     []
264 
265 ***********************************************************************/
Fra_OneHotRefineUsingCex(Fra_Man_t * p,Vec_Int_t * vOneHots)266 int Fra_OneHotRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vOneHots )
267 {
268     Aig_Obj_t * pObj1, * pObj2;
269     int i, Out1, Out2, RetValue = 0;
270     int nPiNum = Aig_ManCiNum(p->pManAig) - Aig_ManRegNum(p->pManAig);
271     assert( p->pSml->pAig == p->pManAig );
272     for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 )
273     {
274         Out1 = Vec_IntEntry( vOneHots, i );
275         Out2 = Vec_IntEntry( vOneHots, i+1 );
276         if ( Out1 == 0 && Out2 == 0 )
277             continue;
278         // get the corresponding nodes
279         pObj1 = Aig_ManCi( p->pManAig, nPiNum + Fra_LitReg(Out1) );
280         pObj2 = Aig_ManCi( p->pManAig, nPiNum + Fra_LitReg(Out2) );
281         // check if implication holds using this simulation info
282         if ( !Fra_OneHotNodesAreClause( p->pSml, pObj1, pObj2, Fra_LitSign(Out1), Fra_LitSign(Out2) ) )
283         {
284             Vec_IntWriteEntry( vOneHots, i, 0 );
285             Vec_IntWriteEntry( vOneHots, i+1, 0 );
286             RetValue = 1;
287         }
288     }
289     return RetValue;
290 }
291 
292 /**Function*************************************************************
293 
294   Synopsis    [Removes those implications that no longer hold.]
295 
296   Description [Returns 1 if refinement has happened.]
297 
298   SideEffects []
299 
300   SeeAlso     []
301 
302 ***********************************************************************/
Fra_OneHotCount(Fra_Man_t * p,Vec_Int_t * vOneHots)303 int Fra_OneHotCount( Fra_Man_t * p, Vec_Int_t * vOneHots )
304 {
305     int i, Out1, Out2, Counter = 0;
306     for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 )
307     {
308         Out1 = Vec_IntEntry( vOneHots, i );
309         Out2 = Vec_IntEntry( vOneHots, i+1 );
310         if ( Out1 == 0 && Out2 == 0 )
311             continue;
312         Counter++;
313     }
314     return Counter;
315 }
316 
317 /**Function*************************************************************
318 
319   Synopsis    [Estimates the coverage of state space by clauses.]
320 
321   Description []
322 
323   SideEffects []
324 
325   SeeAlso     []
326 
327 ***********************************************************************/
Fra_OneHotEstimateCoverage(Fra_Man_t * p,Vec_Int_t * vOneHots)328 void Fra_OneHotEstimateCoverage( Fra_Man_t * p, Vec_Int_t * vOneHots )
329 {
330     int nSimWords = (1<<14);
331     int nRegs = Aig_ManRegNum(p->pManAig);
332     Vec_Ptr_t * vSimInfo;
333     unsigned * pSim1, * pSim2, * pSimTot;
334     int i, w, Out1, Out2, nCovered, Counter = 0;
335     abctime clk = Abc_Clock();
336 
337     // generate random sim-info at register outputs
338     vSimInfo = Vec_PtrAllocSimInfo( nRegs + 1, nSimWords );
339 //    srand( 0xAABBAABB );
340     Aig_ManRandom(1);
341     for ( i = 0; i < nRegs; i++ )
342     {
343         pSim1 = (unsigned *)Vec_PtrEntry( vSimInfo, i );
344         for ( w = 0; w < nSimWords; w++ )
345             pSim1[w] = Fra_ObjRandomSim();
346     }
347     pSimTot = (unsigned *)Vec_PtrEntry( vSimInfo, nRegs );
348 
349     // collect simulation info
350     memset( pSimTot, 0, sizeof(unsigned) * nSimWords );
351     for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 )
352     {
353         Out1 = Vec_IntEntry( vOneHots, i );
354         Out2 = Vec_IntEntry( vOneHots, i+1 );
355         if ( Out1 == 0 && Out2 == 0 )
356             continue;
357 //printf( "(%c%d,%c%d) ",
358 //Fra_LitSign(Out1)? '-': '+', Fra_LitReg(Out1),
359 //Fra_LitSign(Out2)? '-': '+', Fra_LitReg(Out2) );
360         Counter++;
361         pSim1 = (unsigned *)Vec_PtrEntry( vSimInfo, Fra_LitReg(Out1) );
362         pSim2 = (unsigned *)Vec_PtrEntry( vSimInfo, Fra_LitReg(Out2) );
363         if ( Fra_LitSign(Out1) && Fra_LitSign(Out2) )
364             for ( w = 0; w < nSimWords; w++ )
365                 pSimTot[w] |=  pSim1[w] &  pSim2[w];
366         else if ( Fra_LitSign(Out1) )
367             for ( w = 0; w < nSimWords; w++ )
368                 pSimTot[w] |=  pSim1[w] & ~pSim2[w];
369         else if ( Fra_LitSign(Out2) )
370             for ( w = 0; w < nSimWords; w++ )
371                 pSimTot[w] |= ~pSim1[w] &  pSim2[w];
372         else
373             assert( 0 );
374     }
375 //printf( "\n" );
376     // count the total number of patterns contained in the don't-care
377     nCovered = 0;
378     for ( w = 0; w < nSimWords; w++ )
379         nCovered += Aig_WordCountOnes( pSimTot[w] );
380     Vec_PtrFree( vSimInfo );
381     // print the result
382     printf( "Care states ratio = %f. ", 1.0 * (nSimWords * 32 - nCovered) / (nSimWords * 32) );
383     printf( "(%d out of %d patterns)  ", nSimWords * 32 - nCovered, nSimWords * 32 );
384     ABC_PRT( "Time", Abc_Clock() - clk );
385 }
386 
387 /**Function*************************************************************
388 
389   Synopsis    [Creates one-hotness EXDC.]
390 
391   Description []
392 
393   SideEffects []
394 
395   SeeAlso     []
396 
397 ***********************************************************************/
Fra_OneHotCreateExdc(Fra_Man_t * p,Vec_Int_t * vOneHots)398 Aig_Man_t * Fra_OneHotCreateExdc( Fra_Man_t * p, Vec_Int_t * vOneHots )
399 {
400     Aig_Man_t * pNew;
401     Aig_Obj_t * pObj1, * pObj2, * pObj;
402     int i, Out1, Out2, nTruePis;
403     pNew = Aig_ManStart( Vec_IntSize(vOneHots)/2 );
404 //    for ( i = 0; i < Aig_ManRegNum(p->pManAig); i++ )
405 //        Aig_ObjCreateCi(pNew);
406     Aig_ManForEachCi( p->pManAig, pObj, i )
407         Aig_ObjCreateCi(pNew);
408     nTruePis = Aig_ManCiNum(p->pManAig) - Aig_ManRegNum(p->pManAig);
409     for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 )
410     {
411         Out1 = Vec_IntEntry( vOneHots, i );
412         Out2 = Vec_IntEntry( vOneHots, i+1 );
413         if ( Out1 == 0 && Out2 == 0 )
414             continue;
415         pObj1 = Aig_ManCi( pNew, nTruePis + Fra_LitReg(Out1) );
416         pObj2 = Aig_ManCi( pNew, nTruePis + Fra_LitReg(Out2) );
417         pObj1 = Aig_NotCond( pObj1, Fra_LitSign(Out1) );
418         pObj2 = Aig_NotCond( pObj2, Fra_LitSign(Out2) );
419         pObj  = Aig_Or( pNew, pObj1, pObj2 );
420         Aig_ObjCreateCo( pNew, pObj );
421     }
422     Aig_ManCleanup(pNew);
423 //    printf( "Created AIG with %d nodes and %d outputs.\n", Aig_ManNodeNum(pNew), Aig_ManCoNum(pNew) );
424     return pNew;
425 }
426 
427 
428 /**Function*************************************************************
429 
430   Synopsis    [Assumes one-hot implications in the SAT solver.]
431 
432   Description []
433 
434   SideEffects []
435 
436   SeeAlso     []
437 
438 **********************************************************************/
Fra_OneHotAddKnownConstraint(Fra_Man_t * p,Vec_Ptr_t * vOnehots)439 void Fra_OneHotAddKnownConstraint( Fra_Man_t * p, Vec_Ptr_t * vOnehots )
440 {
441     Vec_Int_t * vGroup;
442     Aig_Obj_t * pObj1, * pObj2;
443     int k, i, j, Out1, Out2, pLits[2];
444     //
445     // these constrants should be added to different timeframes!
446     // (also note that PIs follow first - then registers)
447     //
448     Vec_PtrForEachEntry( Vec_Int_t *, vOnehots, vGroup, k )
449     {
450         Vec_IntForEachEntry( vGroup, Out1, i )
451         Vec_IntForEachEntryStart( vGroup, Out2, j, i+1 )
452         {
453             pObj1 = Aig_ManCi( p->pManFraig, Out1 );
454             pObj2 = Aig_ManCi( p->pManFraig, Out2 );
455             pLits[0] = toLitCond( Fra_ObjSatNum(pObj1), 1 );
456             pLits[1] = toLitCond( Fra_ObjSatNum(pObj2), 1 );
457             // add constraint to solver
458             if ( !sat_solver_addclause( p->pSat, pLits, pLits + 2 ) )
459             {
460                 printf( "Fra_OneHotAddKnownConstraint(): Adding clause makes SAT solver unsat.\n" );
461                 sat_solver_delete( p->pSat );
462                 p->pSat = NULL;
463                 return;
464             }
465         }
466     }
467 }
468 
469 
470 ////////////////////////////////////////////////////////////////////////
471 ///                       END OF FILE                                ///
472 ////////////////////////////////////////////////////////////////////////
473 
474 
475 ABC_NAMESPACE_IMPL_END
476 
477