ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
hopBalance.c
Go to the documentation of this file.
1
20
21#include "hop.h"
22
24
25
29
30static Hop_Obj_t * Hop_NodeBalance_rec( Hop_Man_t * pNew, Hop_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel );
31static Vec_Ptr_t * Hop_NodeBalanceCone( Hop_Obj_t * pObj, Vec_Vec_t * vStore, int Level );
32static int Hop_NodeBalanceFindLeft( Vec_Ptr_t * vSuper );
33static void Hop_NodeBalancePermute( Hop_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor );
34static void Hop_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Hop_Obj_t * pObj );
35
39
51Hop_Man_t * Hop_ManBalance( Hop_Man_t * p, int fUpdateLevel )
52{
53 Hop_Man_t * pNew;
54 Hop_Obj_t * pObj, * pObjNew;
55 Vec_Vec_t * vStore;
56 int i;
57 // create the new manager
58 pNew = Hop_ManStart();
59 pNew->fRefCount = 0;
60 // map the PI nodes
62 Hop_ManConst1(p)->pData = Hop_ManConst1(pNew);
63 Hop_ManForEachPi( p, pObj, i )
64 pObj->pData = Hop_ObjCreatePi(pNew);
65 // balance the AIG
66 vStore = Vec_VecAlloc( 50 );
67 Hop_ManForEachPo( p, pObj, i )
68 {
69 pObjNew = Hop_NodeBalance_rec( pNew, Hop_ObjFanin0(pObj), vStore, 0, fUpdateLevel );
70 Hop_ObjCreatePo( pNew, Hop_NotCond( pObjNew, Hop_ObjFaninC0(pObj) ) );
71 }
72 Vec_VecFree( vStore );
73 // remove dangling nodes
74// Hop_ManCreateRefs( pNew );
75// if ( i = Hop_ManCleanup( pNew ) )
76// printf( "Cleanup after balancing removed %d dangling nodes.\n", i );
77 // check the resulting AIG
78 if ( !Hop_ManCheck(pNew) )
79 printf( "Hop_ManBalance(): The check has failed.\n" );
80 return pNew;
81}
82
94Hop_Obj_t * Hop_NodeBalance_rec( Hop_Man_t * pNew, Hop_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel )
95{
96 Hop_Obj_t * pObjNew;
97 Vec_Ptr_t * vSuper;
98 int i;
99 assert( !Hop_IsComplement(pObjOld) );
100 // return if the result is known
101 if ( pObjOld->pData )
102 return (Hop_Obj_t *)pObjOld->pData;
103 assert( Hop_ObjIsNode(pObjOld) );
104 // get the implication supergate
105 vSuper = Hop_NodeBalanceCone( pObjOld, vStore, Level );
106 // check if supergate contains two nodes in the opposite polarity
107 if ( vSuper->nSize == 0 )
108 return (Hop_Obj_t *)(pObjOld->pData = Hop_ManConst0(pNew));
109 if ( Vec_PtrSize(vSuper) < 2 )
110 printf( "BUG!\n" );
111 // for each old node, derive the new well-balanced node
112 for ( i = 0; i < Vec_PtrSize(vSuper); i++ )
113 {
114 pObjNew = Hop_NodeBalance_rec( pNew, Hop_Regular((Hop_Obj_t *)vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel );
115 vSuper->pArray[i] = Hop_NotCond( pObjNew, Hop_IsComplement((Hop_Obj_t *)vSuper->pArray[i]) );
116 }
117 // build the supergate
118 pObjNew = Hop_NodeBalanceBuildSuper( pNew, vSuper, Hop_ObjType(pObjOld), fUpdateLevel );
119 // make sure the balanced node is not assigned
120// assert( pObjOld->Level >= Hop_Regular(pObjNew)->Level );
121 assert( pObjOld->pData == NULL );
122 return (Hop_Obj_t *)(pObjOld->pData = pObjNew);
123}
124
136int Hop_NodeBalanceCone_rec( Hop_Obj_t * pRoot, Hop_Obj_t * pObj, Vec_Ptr_t * vSuper )
137{
138 int RetValue1, RetValue2, i;
139 // check if the node is visited
140 if ( Hop_Regular(pObj)->fMarkB )
141 {
142 // check if the node occurs in the same polarity
143 for ( i = 0; i < vSuper->nSize; i++ )
144 if ( vSuper->pArray[i] == pObj )
145 return 1;
146 // check if the node is present in the opposite polarity
147 for ( i = 0; i < vSuper->nSize; i++ )
148 if ( vSuper->pArray[i] == Hop_Not(pObj) )
149 return -1;
150 assert( 0 );
151 return 0;
152 }
153 // if the new node is complemented or a PI, another gate begins
154 if ( pObj != pRoot && (Hop_IsComplement(pObj) || Hop_ObjType(pObj) != Hop_ObjType(pRoot) || Hop_ObjRefs(pObj) > 1 || Vec_PtrSize(vSuper) > 10000) )
155 {
156 Vec_PtrPush( vSuper, pObj );
157 Hop_Regular(pObj)->fMarkB = 1;
158 return 0;
159 }
160 assert( !Hop_IsComplement(pObj) );
161 assert( Hop_ObjIsNode(pObj) );
162 // go through the branches
163 RetValue1 = Hop_NodeBalanceCone_rec( pRoot, Hop_ObjChild0(pObj), vSuper );
164 RetValue2 = Hop_NodeBalanceCone_rec( pRoot, Hop_ObjChild1(pObj), vSuper );
165 if ( RetValue1 == -1 || RetValue2 == -1 )
166 return -1;
167 // return 1 if at least one branch has a duplicate
168 return RetValue1 || RetValue2;
169}
170
182Vec_Ptr_t * Hop_NodeBalanceCone( Hop_Obj_t * pObj, Vec_Vec_t * vStore, int Level )
183{
184 Vec_Ptr_t * vNodes;
185 int RetValue, i;
186 assert( !Hop_IsComplement(pObj) );
187 // extend the storage
188 if ( Vec_VecSize( vStore ) <= Level )
189 Vec_VecPush( vStore, Level, 0 );
190 // get the temporary array of nodes
191 vNodes = Vec_VecEntry( vStore, Level );
192 Vec_PtrClear( vNodes );
193 // collect the nodes in the implication supergate
194 RetValue = Hop_NodeBalanceCone_rec( pObj, pObj, vNodes );
195 assert( vNodes->nSize > 1 );
196 // unmark the visited nodes
197 Vec_PtrForEachEntry( Hop_Obj_t *, vNodes, pObj, i )
198 Hop_Regular(pObj)->fMarkB = 0;
199 // if we found the node and its complement in the same implication supergate,
200 // return empty set of nodes (meaning that we should use constant-0 node)
201 if ( RetValue == -1 )
202 vNodes->nSize = 0;
203 return vNodes;
204}
205
218{
219 int Diff = Hop_ObjLevel(Hop_Regular(*pp1)) - Hop_ObjLevel(Hop_Regular(*pp2));
220 if ( Diff > 0 )
221 return -1;
222 if ( Diff < 0 )
223 return 1;
224 Diff = Hop_Regular(*pp1)->Id - Hop_Regular(*pp2)->Id;
225 if ( Diff > 0 )
226 return -1;
227 if ( Diff < 0 )
228 return 1;
229 return 0;
230}
231
243Hop_Obj_t * Hop_NodeBalanceBuildSuper( Hop_Man_t * p, Vec_Ptr_t * vSuper, Hop_Type_t Type, int fUpdateLevel )
244{
245 Hop_Obj_t * pObj1, * pObj2;
246 int LeftBound;
247 assert( vSuper->nSize > 1 );
248 // sort the new nodes by level in the decreasing order
249 Vec_PtrSort( vSuper, (int (*)(const void *, const void *))Hop_NodeCompareLevelsDecrease );
250 // balance the nodes
251 while ( vSuper->nSize > 1 )
252 {
253 // find the left bound on the node to be paired
254 LeftBound = (!fUpdateLevel)? 0 : Hop_NodeBalanceFindLeft( vSuper );
255 // find the node that can be shared (if no such node, randomize choice)
256 Hop_NodeBalancePermute( p, vSuper, LeftBound, Type == AIG_EXOR );
257 // pull out the last two nodes
258 pObj1 = (Hop_Obj_t *)Vec_PtrPop(vSuper);
259 pObj2 = (Hop_Obj_t *)Vec_PtrPop(vSuper);
260 Hop_NodeBalancePushUniqueOrderByLevel( vSuper, Hop_Oper(p, pObj1, pObj2, Type) );
261 }
262 return (Hop_Obj_t *)Vec_PtrEntry(vSuper, 0);
263}
264
280int Hop_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )
281{
282 Hop_Obj_t * pObjRight, * pObjLeft;
283 int Current;
284 // if two or less nodes, pair with the first
285 if ( Vec_PtrSize(vSuper) < 3 )
286 return 0;
287 // set the pointer to the one before the last
288 Current = Vec_PtrSize(vSuper) - 2;
289 pObjRight = (Hop_Obj_t *)Vec_PtrEntry( vSuper, Current );
290 // go through the nodes to the left of this one
291 for ( Current--; Current >= 0; Current-- )
292 {
293 // get the next node on the left
294 pObjLeft = (Hop_Obj_t *)Vec_PtrEntry( vSuper, Current );
295 // if the level of this node is different, quit the loop
296 if ( Hop_ObjLevel(Hop_Regular(pObjLeft)) != Hop_ObjLevel(Hop_Regular(pObjRight)) )
297 break;
298 }
299 Current++;
300 // get the node, for which the equality holds
301 pObjLeft = (Hop_Obj_t *)Vec_PtrEntry( vSuper, Current );
302 assert( Hop_ObjLevel(Hop_Regular(pObjLeft)) == Hop_ObjLevel(Hop_Regular(pObjRight)) );
303 return Current;
304}
305
318void Hop_NodeBalancePermute( Hop_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor )
319{
320 Hop_Obj_t * pObj1, * pObj2, * pObj3, * pGhost;
321 int RightBound, i;
322 // get the right bound
323 RightBound = Vec_PtrSize(vSuper) - 2;
324 assert( LeftBound <= RightBound );
325 if ( LeftBound == RightBound )
326 return;
327 // get the two last nodes
328 pObj1 = (Hop_Obj_t *)Vec_PtrEntry( vSuper, RightBound + 1 );
329 pObj2 = (Hop_Obj_t *)Vec_PtrEntry( vSuper, RightBound );
330 if ( Hop_Regular(pObj1) == p->pConst1 || Hop_Regular(pObj2) == p->pConst1 )
331 return;
332 // find the first node that can be shared
333 for ( i = RightBound; i >= LeftBound; i-- )
334 {
335 pObj3 = (Hop_Obj_t *)Vec_PtrEntry( vSuper, i );
336 if ( Hop_Regular(pObj3) == p->pConst1 )
337 {
338 Vec_PtrWriteEntry( vSuper, i, pObj2 );
339 Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
340 return;
341 }
342 pGhost = Hop_ObjCreateGhost( p, pObj1, pObj3, fExor? AIG_EXOR : AIG_AND );
343 if ( Hop_TableLookup( p, pGhost ) )
344 {
345 if ( pObj3 == pObj2 )
346 return;
347 Vec_PtrWriteEntry( vSuper, i, pObj2 );
348 Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
349 return;
350 }
351 }
352/*
353 // we did not find the node to share, randomize choice
354 {
355 int Choice = rand() % (RightBound - LeftBound + 1);
356 pObj3 = Vec_PtrEntry( vSuper, LeftBound + Choice );
357 if ( pObj3 == pObj2 )
358 return;
359 Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pObj2 );
360 Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
361 }
362*/
363}
364
376void Hop_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Hop_Obj_t * pObj )
377{
378 Hop_Obj_t * pObj1, * pObj2;
379 int i;
380 if ( Vec_PtrPushUnique(vStore, pObj) )
381 return;
382 // find the p of the node
383 for ( i = vStore->nSize-1; i > 0; i-- )
384 {
385 pObj1 = (Hop_Obj_t *)vStore->pArray[i ];
386 pObj2 = (Hop_Obj_t *)vStore->pArray[i-1];
387 if ( Hop_ObjLevel(Hop_Regular(pObj1)) <= Hop_ObjLevel(Hop_Regular(pObj2)) )
388 break;
389 vStore->pArray[i ] = pObj2;
390 vStore->pArray[i-1] = pObj1;
391 }
392}
393
394
398
399
401
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
Cube * p
Definition exorList.c:222
int Hop_NodeBalanceCone_rec(Hop_Obj_t *pRoot, Hop_Obj_t *pObj, Vec_Ptr_t *vSuper)
Definition hopBalance.c:136
int Hop_NodeCompareLevelsDecrease(Hop_Obj_t **pp1, Hop_Obj_t **pp2)
Definition hopBalance.c:217
Hop_Obj_t * Hop_NodeBalanceBuildSuper(Hop_Man_t *p, Vec_Ptr_t *vSuper, Hop_Type_t Type, int fUpdateLevel)
Definition hopBalance.c:243
Hop_Man_t * Hop_ManBalance(Hop_Man_t *p, int fUpdateLevel)
FUNCTION DEFINITIONS ///.
Definition hopBalance.c:51
Hop_Obj_t * Hop_ObjCreatePo(Hop_Man_t *p, Hop_Obj_t *pDriver)
Definition hopObj.c:67
typedefABC_NAMESPACE_HEADER_START struct Hop_Man_t_ Hop_Man_t
INCLUDES ///.
Definition hop.h:49
int Hop_ManCheck(Hop_Man_t *p)
DECLARATIONS ///.
Definition hopCheck.c:45
Hop_Type_t
Definition hop.h:54
@ AIG_EXOR
Definition hop.h:60
@ AIG_AND
Definition hop.h:59
#define Hop_ManForEachPi(p, pObj, i)
ITERATORS ///.
Definition hop.h:259
Hop_Obj_t * Hop_TableLookup(Hop_Man_t *p, Hop_Obj_t *pGhost)
FUNCTION DEFINITIONS ///.
Definition hopTable.c:71
Hop_Obj_t * Hop_Oper(Hop_Man_t *p, Hop_Obj_t *p0, Hop_Obj_t *p1, Hop_Type_t Type)
Definition hopOper.c:83
#define Hop_ManForEachPo(p, pObj, i)
Definition hop.h:262
Hop_Obj_t * Hop_ObjCreatePi(Hop_Man_t *p)
DECLARATIONS ///.
Definition hopObj.c:45
Hop_Man_t * Hop_ManStart()
DECLARATIONS ///.
Definition hopMan.c:45
struct Hop_Obj_t_ Hop_Obj_t
Definition hop.h:50
void Hop_ManCleanData(Hop_Man_t *p)
Definition hopUtil.c:63
void * pData
Definition hop.h:68
#define assert(ex)
Definition util_old.h:213
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition vecVec.h:42