ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
wlcBlast.c
Go to the documentation of this file.
1
20
21#include "wlc.h"
22#include "misc/tim/tim.h"
23#include "base/main/main.h"
24#include "base/cmd/cmd.h"
25
27
28
32
36
48int Wlc_NtkCountConstBits( int * pArray, int nSize )
49{
50 int i, Counter = 0;
51 for ( i = 0; i < nSize; i++ )
52 Counter += (pArray[i] == 0 || pArray[i] == 1);
53 return Counter;
54}
55
68{
69 Wlc_Obj_t * pObj;
70 int i, nBits = 0;
71 Wlc_NtkCleanCopy( p );
72 Wlc_NtkForEachObj( p, pObj, i )
73 {
74 Wlc_ObjSetCopy( p, i, nBits );
75 nBits += Wlc_ObjRange(pObj);
76 }
77 return nBits;
78}
79int * Wlc_VecCopy( Vec_Int_t * vOut, int * pArray, int nSize )
80{
81 int i; Vec_IntClear( vOut );
82 for( i = 0; i < nSize; i++)
83 Vec_IntPush( vOut, pArray[i] );
84 return Vec_IntArray( vOut );
85}
86int * Wlc_VecLoadFanins( Vec_Int_t * vOut, int * pFanins, int nFanins, int nTotal, int fSigned )
87{
88 int Fill = fSigned ? pFanins[nFanins-1] : 0;
89 int i; Vec_IntClear( vOut );
90 assert( nFanins <= nTotal );
91 for( i = 0; i < nTotal; i++)
92 Vec_IntPush( vOut, i < nFanins ? pFanins[i] : Fill );
93 return Vec_IntArray( vOut );
94}
95int Wlc_BlastGetConst( int * pNum, int nNum )
96{
97 int i, Res = 0;
98 for ( i = 0; i < nNum; i++ )
99 if ( pNum[i] == 1 )
100 Res |= (1 << i);
101 else if ( pNum[i] != 0 )
102 return -1;
103 return Res;
104}
105int Wlc_NtkMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData, int Shift )
106{
107 int iLit0, iLit1;
108 if ( nCtrl == 0 )
109 return Vec_IntEntry( vData, Shift );
110 iLit0 = Wlc_NtkMuxTree_rec( pNew, pCtrl, nCtrl-1, vData, Shift );
111 iLit1 = Wlc_NtkMuxTree_rec( pNew, pCtrl, nCtrl-1, vData, Shift + (1<<(nCtrl-1)) );
112 return Gia_ManHashMux( pNew, pCtrl[nCtrl-1], iLit1, iLit0 );
113}
114int Wlc_NtkMuxTree2_nb( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData, Vec_Int_t * vAnds )
115{
116 int iLitOr = 0, iLitAnd, m;
117 assert( Vec_IntSize(vData) == (1 << nCtrl) );
118 assert( Vec_IntSize(vAnds) == (1 << nCtrl) );
119 for ( m = 0; m < (1 << nCtrl); m++ )
120 {
121 iLitAnd = Gia_ManHashAnd( pNew, Vec_IntEntry(vAnds, m), Vec_IntEntry(vData, m) );
122 iLitOr = Gia_ManHashOr( pNew, iLitOr, iLitAnd );
123 }
124 return iLitOr;
125}
126int Wlc_NtkMuxTree2( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData, Vec_Int_t * vAnds, Vec_Int_t * vTemp )
127{
128 int m, iLit;
129 assert( !nCtrl || Vec_IntSize(vData) == (1 << nCtrl) );
130 assert( !nCtrl || Vec_IntSize(vAnds) == (1 << nCtrl) );
131 Vec_IntClear( vTemp );
132 Vec_IntForEachEntry( vAnds, iLit, m )
133 Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vData, m)) ) );
134 return Abc_LitNot( Gia_ManHashAndMulti(pNew, vTemp) );
135}
136int Wlc_NtkMuxTree3( Gia_Man_t * p, Vec_Int_t * vData, char * pNums, Vec_Int_t ** pvDecs )
137{
138 int i, iStart = 0, nSize = Vec_IntSize(vData);
139 for ( i = (int)strlen(pNums)-1; i >= 0; i-- )
140 {
141 int k, b, nBits = (int)(pNums[i] - '0');
142 Vec_Int_t * vDec = pvDecs[i];
143 for ( k = 0; k < nSize; k++ )
144 Vec_IntWriteEntry( vData, k, Gia_ManHashAnd(p, Vec_IntEntry(vData, k), Vec_IntEntry(vDec, k%Vec_IntSize(vDec))) );
145 for ( b = 0; b < nBits; b++, nSize /= 2 )
146 for ( k = 0; k < nSize/2; k++ )
147 Vec_IntWriteEntry( vData, k, Gia_ManHashOr(p, Vec_IntEntry(vData, 2*k), Vec_IntEntry(vData, 2*k+1)) );
148 iStart += nBits;
149 }
150 assert( nSize == 1 );
151 return Vec_IntEntry(vData, 0);
152}
153Vec_Int_t ** Wlc_NtkMuxTree3DecsDerive( Gia_Man_t * p, int * pIns, int nIns, char * pNums )
154{
155 extern Vec_Int_t * Wlc_BlastDecoder2_rec( Gia_Man_t * p, int * pLits, int nLits );
156 Vec_Int_t ** pvDecs = ABC_ALLOC( Vec_Int_t *, strlen(pNums) ); int i, iStart = 0;
157 for ( i = (int)strlen(pNums)-1; i >= 0; i-- ) {
158 pvDecs[i] = Wlc_BlastDecoder2_rec( p, pIns + iStart, (int)(pNums[i] - '0') );
159 iStart += (int)(pNums[i] - '0');
160 }
161 assert( iStart == nIns );
162 return pvDecs;
163}
164void Wlc_NtkMuxTree3DecsFree( Vec_Int_t ** pvDecs, char * pNums )
165{
166 int i;
167 for ( i = (int)strlen(pNums)-1; i >= 0; i-- )
168 Vec_IntFree( pvDecs[i] );
169 ABC_FREE( pvDecs );
170}
171char * Wlc_NtkMuxTreeString( int nIns )
172{
173 if ( nIns == 1 ) return (char*)"1";
174 if ( nIns == 2 ) return (char*)"11";
175 if ( nIns == 3 ) return (char*)"111";
176 if ( nIns == 4 ) return (char*)"112";
177 if ( nIns == 5 ) return (char*)"1112";
178 if ( nIns == 6 ) return (char*)"1113";
179 if ( nIns == 7 ) return (char*)"1114";
180 if ( nIns == 8 ) return (char*)"1124";
181 if ( nIns == 9 ) return (char*)"11124";
182 if ( nIns == 10 ) return (char*)"11125";
183 if ( nIns == 11 ) return (char*)"11126";
184 if ( nIns == 12 ) return (char*)"11136";
185 if ( nIns == 13 ) return (char*)"11137";
186 if ( nIns == 14 ) return (char*)"11147";
187 if ( nIns == 15 ) return (char*)"11148";
188 if ( nIns == 16 ) return (char*)"11248";
189 return NULL;
190}
192{
193 int i; char * pTemp;
194 Vec_PtrForEachEntry( char *, vNames, pTemp, i )
195 printf( "%2d : %s\n", i, pTemp );
196}
197
209void Wlc_BlastShiftRightInt( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes )
210{
211 int * pRes = Wlc_VecCopy( vRes, pNum, nNum );
212 int Fill = fSticky ? pNum[nNum-1] : 0;
213 int i, j, fShort = 0;
214 assert( nShift <= 32 );
215 for( i = 0; i < nShift; i++ )
216 for( j = 0; j < nNum - fSticky; j++ )
217 {
218 if( fShort || j + (1<<i) >= nNum )
219 {
220 pRes[j] = Gia_ManHashMux( pNew, pShift[i], Fill, pRes[j] );
221 if ( (1<<i) > nNum )
222 fShort = 1;
223 }
224 else
225 pRes[j] = Gia_ManHashMux( pNew, pShift[i], pRes[j+(1<<i)], pRes[j] );
226 }
227}
228void Wlc_BlastShiftRight( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes )
229{
230 int nShiftMax = Abc_Base2Log(nNum);
231 int * pShiftNew = ABC_ALLOC( int, nShift );
232 memcpy( pShiftNew, pShift, sizeof(int)*nShift );
233 if ( nShiftMax < nShift && nShift > 30 )
234 {
235 int i, iRes = pShiftNew[nShiftMax];
236 for ( i = nShiftMax + 1; i < nShift; i++ )
237 iRes = Gia_ManHashOr( pNew, iRes, pShiftNew[i] );
238 pShiftNew[nShiftMax++] = iRes;
239 }
240 else
241 nShiftMax = nShift;
242 Wlc_BlastShiftRightInt( pNew, pNum, nNum, pShiftNew, nShiftMax, fSticky, vRes );
243 ABC_FREE( pShiftNew );
244}
245void Wlc_BlastShiftLeftInt( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes )
246{
247 int * pRes = Wlc_VecCopy( vRes, pNum, nNum );
248 int Fill = fSticky ? pNum[0] : 0;
249 int i, j, fShort = 0;
250 assert( nShift <= 32 );
251 for( i = 0; i < nShift; i++ )
252 for( j = nNum-1; j >= fSticky; j-- )
253 {
254 if( fShort || (1<<i) > j )
255 {
256 pRes[j] = Gia_ManHashMux( pNew, pShift[i], Fill, pRes[j] );
257 if ( (1<<i) > nNum )
258 fShort = 1;
259 }
260 else
261 pRes[j] = Gia_ManHashMux( pNew, pShift[i], pRes[j-(1<<i)], pRes[j] );
262 }
263}
264void Wlc_BlastShiftLeft( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes )
265{
266 int nShiftMax = Abc_Base2Log(nNum);
267 int * pShiftNew = ABC_ALLOC( int, nShift );
268 memcpy( pShiftNew, pShift, sizeof(int)*nShift );
269 if ( nShiftMax < nShift )
270 {
271 int i, iRes = pShiftNew[nShiftMax];
272 for ( i = nShiftMax + 1; i < nShift; i++ )
273 iRes = Gia_ManHashOr( pNew, iRes, pShiftNew[i] );
274 pShiftNew[nShiftMax++] = iRes;
275 }
276 else
277 nShiftMax = nShift;
278 Wlc_BlastShiftLeftInt( pNew, pNum, nNum, pShiftNew, nShiftMax, fSticky, vRes );
279 ABC_FREE( pShiftNew );
280}
281void Wlc_BlastRotateRight( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, Vec_Int_t * vRes )
282{
283 int * pRes = Wlc_VecCopy( vRes, pNum, nNum );
284 int i, j, * pTemp = ABC_ALLOC( int, nNum );
285 assert( nShift <= 32 );
286 for( i = 0; i < nShift; i++, pRes = Wlc_VecCopy(vRes, pTemp, nNum) )
287 for( j = 0; j < nNum; j++ )
288 pTemp[j] = Gia_ManHashMux( pNew, pShift[i], pRes[(j+(1<<i))%nNum], pRes[j] );
289 ABC_FREE( pTemp );
290}
291void Wlc_BlastRotateLeft( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, Vec_Int_t * vRes )
292{
293 int * pRes = Wlc_VecCopy( vRes, pNum, nNum );
294 int i, j, * pTemp = ABC_ALLOC( int, nNum );
295 assert( nShift <= 32 );
296 for( i = 0; i < nShift; i++, pRes = Wlc_VecCopy(vRes, pTemp, nNum) )
297 for( j = 0; j < nNum; j++ )
298 {
299 int move = (j >= (1<<i)) ? (j-(1<<i))%nNum : (nNum - (((1<<i)-j)%nNum)) % nNum;
300 pTemp[j] = Gia_ManHashMux( pNew, pShift[i], pRes[move], pRes[j] );
301// pTemp[j] = Gia_ManHashMux( pNew, pShift[i], pRes[((unsigned)(nNum-(1<<i)+j))%nNum], pRes[j] );
302 }
303 ABC_FREE( pTemp );
304}
305int Wlc_BlastReduction( Gia_Man_t * pNew, int * pFans, int nFans, int Type )
306{
307 if ( Type == WLC_OBJ_REDUCT_AND || Type == WLC_OBJ_REDUCT_NAND )
308 {
309 int k, iLit = 1;
310 for ( k = 0; k < nFans; k++ )
311 iLit = Gia_ManHashAnd( pNew, iLit, pFans[k] );
312 return Abc_LitNotCond( iLit, Type == WLC_OBJ_REDUCT_NAND );
313 }
314 if ( Type == WLC_OBJ_REDUCT_OR || Type == WLC_OBJ_REDUCT_NOR )
315 {
316 int k, iLit = 0;
317 for ( k = 0; k < nFans; k++ )
318 iLit = Gia_ManHashOr( pNew, iLit, pFans[k] );
319 return Abc_LitNotCond( iLit, Type == WLC_OBJ_REDUCT_NOR );
320 }
321 if ( Type == WLC_OBJ_REDUCT_XOR || Type == WLC_OBJ_REDUCT_NXOR )
322 {
323 int k, iLit = 0;
324 for ( k = 0; k < nFans; k++ )
325 iLit = Gia_ManHashXor( pNew, iLit, pFans[k] );
326 return Abc_LitNotCond( iLit, Type == WLC_OBJ_REDUCT_NXOR );
327 }
328 assert( 0 );
329 return -1;
330}
331int Wlc_BlastLess2( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits )
332{
333 int k, iKnown = 0, iRes = 0;
334 for ( k = nBits - 1; k >= 0; k-- )
335 {
336 iRes = Gia_ManHashMux( pNew, iKnown, iRes, Gia_ManHashAnd(pNew, Abc_LitNot(pArg0[k]), pArg1[k]) );
337 iKnown = Gia_ManHashOr( pNew, iKnown, Gia_ManHashXor(pNew, pArg0[k], pArg1[k]) );
338 if ( iKnown == 1 )
339 break;
340 }
341 return iRes;
342}
343void Wlc_BlastLess_rec( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits, int * pYes, int * pNo )
344{
345 if ( nBits > 1 )
346 {
347 int Yes = Gia_ManHashAnd( pNew, Abc_LitNot(pArg0[nBits-1]), pArg1[nBits-1] ), YesR;
348 int No = Gia_ManHashAnd( pNew, Abc_LitNot(pArg1[nBits-1]), pArg0[nBits-1] ), NoR;
349 if ( Yes == 1 || No == 1 )
350 {
351 *pYes = Yes;
352 *pNo = No;
353 return;
354 }
355 Wlc_BlastLess_rec( pNew, pArg0, pArg1, nBits-1, &YesR, &NoR );
356 *pYes = Gia_ManHashOr( pNew, Yes, Gia_ManHashAnd(pNew, Abc_LitNot(No), YesR) );
357 *pNo = Gia_ManHashOr( pNew, No, Gia_ManHashAnd(pNew, Abc_LitNot(Yes), NoR ) );
358 return;
359 }
360 assert( nBits == 1 );
361 *pYes = Gia_ManHashAnd( pNew, Abc_LitNot(pArg0[0]), pArg1[0] );
362 *pNo = Gia_ManHashAnd( pNew, Abc_LitNot(pArg1[0]), pArg0[0] );
363}
364int Wlc_BlastLess( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits )
365{
366 int Yes, No;
367 if ( nBits == 0 )
368 return 0;
369 Wlc_BlastLess_rec( pNew, pArg0, pArg1, nBits, &Yes, &No );
370 return Yes;
371}
372int Wlc_BlastLessSigned( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits )
373{
374 int iDiffSign = Gia_ManHashXor( pNew, pArg0[nBits-1], pArg1[nBits-1] );
375 return Gia_ManHashMux( pNew, iDiffSign, pArg0[nBits-1], Wlc_BlastLess(pNew, pArg0, pArg1, nBits-1) );
376}
377int Wlc_BlastLess3( Gia_Man_t * p, int * pArg1, int * pArg0, int nBits )
378{
379 int i, iLit = 1;
380 for ( i = 0; i < nBits; i++ ) {
381 int iLitA0 = pArg0[i];
382 int iLitA1 = i == nBits-1 ? 0 : pArg0[i+1];
383 int iLitB0 = pArg1[i];
384 int iLitB1 = i == nBits-1 ? 0 : pArg1[i+1];
385 int iOrLit0;
386 if ( i == 0 )
387 iOrLit0 = Gia_ManHashOr(p, Abc_LitNotCond(iLitA0, !(i&1)), Abc_LitNotCond(iLitB0, i&1));
388 else
389 iOrLit0 = Gia_ManHashAnd(p, Abc_LitNotCond(iLitA0, !(i&1)), Abc_LitNotCond(iLitB0, i&1));
390 int iOrLit1 = Gia_ManHashAnd(p, Abc_LitNotCond(iLitA1, !(i&1)), Abc_LitNotCond(iLitB1, i&1));
391 int iOrLit = Gia_ManHashOr(p, iOrLit0, iOrLit1 );
392 iLit = Gia_ManHashOr(p, Abc_LitNot(iLit), iOrLit );
393 }
394 return Abc_LitNotCond(iLit, nBits&1);
395}
396int Wlc_BlastLessSigned3( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits )
397{
398 int iDiffSign = Gia_ManHashXor( pNew, pArg0[nBits-1], pArg1[nBits-1] );
399 return Gia_ManHashMux( pNew, iDiffSign, pArg0[nBits-1], Wlc_BlastLess3(pNew, pArg0, pArg1, nBits-1) );
400}
401void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps )
402{
403 int fUseXor = 0;
404 int fCompl = (a == 1 || b == 1 || c == 1);
405 // propagate complement through the FA - helps generate less redundant logic
406 if ( fCompl )
407 a = Abc_LitNot(a), b = Abc_LitNot(b), c = Abc_LitNot(c);
408 if ( fUseXor )
409 {
410 int Xor = Gia_ManHashXor(pNew, a, b);
411 int And1 = Gia_ManHashAnd(pNew, a, b);
412 int And2 = Gia_ManHashAnd(pNew, c, Xor);
413 *ps = Gia_ManHashXor(pNew, c, Xor);
414 *pc = Gia_ManHashOr (pNew, And1, And2);
415 }
416 else
417 {
418 int And1 = Gia_ManHashAnd(pNew, a, b);
419 int And1_= Gia_ManHashAnd(pNew, Abc_LitNot(a), Abc_LitNot(b));
420 int Xor = Gia_ManHashAnd(pNew, Abc_LitNot(And1), Abc_LitNot(And1_));
421 int And2 = Gia_ManHashAnd(pNew, c, Xor);
422 int And2_= Gia_ManHashAnd(pNew, Abc_LitNot(c), Abc_LitNot(Xor));
423 *ps = Gia_ManHashAnd(pNew, Abc_LitNot(And2), Abc_LitNot(And2_));
424 *pc = Gia_ManHashOr (pNew, And1, And2);
425 }
426 if ( fCompl )
427 *ps = Abc_LitNot(*ps), *pc = Abc_LitNot(*pc);
428}
429int Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0
430{
431 int b;
432 for ( b = 0; b < nBits; b++ )
433 Wlc_BlastFullAdder( pNew, pAdd0[b], pAdd1[b], Carry, &Carry, &pAdd0[b] );
434 return Carry;
435}
436void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0
437{
438 int b;
439 for ( b = 0; b < nBits; b++ )
440 Wlc_BlastFullAdder( pNew, pAdd0[b], Abc_LitNot(pAdd1[b]), Carry, &Carry, &pAdd0[b] );
441}
442
443void Wlc_BlastAdderCLA_one( Gia_Man_t * pNew, int * pGen, int * pPro, int * pCar, int * pGen1, int * pPro1, int * pCar1 )
444{
445 int Temp = Gia_ManHashAnd( pNew, pGen[0], pPro[1] );
446 *pPro1 = Gia_ManHashAnd( pNew, pPro[0], pPro[1] );
447 *pGen1 = Gia_ManHashOr( pNew, Gia_ManHashOr(pNew, pGen[1], Temp), Gia_ManHashAnd(pNew, *pPro1, pCar[0]) );
448 *pCar1 = Gia_ManHashOr( pNew, pGen[0], Gia_ManHashAnd(pNew, pPro[0], pCar[0]) );
449}
450void Wlc_BlastAdderCLA_rec( Gia_Man_t * pNew, int * pGen, int * pPro, int * pCar, int nBits, int * pGen1, int * pPro1 )
451{
452 if ( nBits == 2 )
453 Wlc_BlastAdderCLA_one( pNew, pGen, pPro, pCar, pGen1, pPro1, pCar+1 ); // returns *pGen1, *pPro1, pCar[1]
454 else
455 {
456 int pGen2[2], pPro2[2];
457 assert( nBits % 2 == 0 );
458 // call recursively
459 Wlc_BlastAdderCLA_rec( pNew, pGen, pPro, pCar, nBits/2, pGen2, pPro2 );
460 pCar[nBits/2] = *pGen2;
461 Wlc_BlastAdderCLA_rec( pNew, pGen+nBits/2, pPro+nBits/2, pCar+nBits/2, nBits/2, pGen2+1, pPro2+1 );
462 // create structure
463 Wlc_BlastAdderCLA_one( pNew, pGen2, pPro2, pCar, pGen1, pPro1, pCar+nBits/2 ); // returns *pGen1, *pPro1, pCar[nBits/2]
464 }
465}
466void Wlc_BlastAdderCLA_int( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int CarryIn ) // result is in pAdd0
467{
468 int * pGen = ABC_CALLOC( int, nBits );
469 int * pPro = ABC_CALLOC( int, nBits );
470 int * pCar = ABC_CALLOC( int, nBits+1 );
471 int b, Gen, Pro;
472 if ( nBits == 1 )
473 {
474 int Carry = CarryIn;
475 Wlc_BlastFullAdder( pNew, pAdd0[0], pAdd1[0], Carry, &Carry, &pAdd0[0] );
476 return;
477 }
478 assert( nBits >= 2 );
479 pCar[0] = CarryIn;
480 for ( b = 0; b < nBits; b++ )
481 {
482 pGen[b] = Gia_ManHashAnd(pNew, pAdd0[b], pAdd1[b]);
483 pPro[b] = Gia_ManHashXor(pNew, pAdd0[b], pAdd1[b]);
484 }
485 Wlc_BlastAdderCLA_rec( pNew, pGen, pPro, pCar, nBits, &Gen, &Pro );
486 for ( b = 0; b < nBits; b++ )
487 pAdd0[b] = Gia_ManHashXor(pNew, pPro[b], pCar[b]);
488 ABC_FREE(pGen);
489 ABC_FREE(pPro);
490 ABC_FREE(pCar);
491}
492void Wlc_BlastAdderCLA( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int fSign, int CarryIn ) // result is in pAdd0
493{
494 int i, Log2 = Abc_Base2Log(nBits);
495 int * pAdd0n = ABC_CALLOC( int, 1<<Log2 );
496 int * pAdd1n = ABC_CALLOC( int, 1<<Log2 );
497 for ( i = 0; i < nBits; i++ )
498 {
499 pAdd0n[i] = pAdd0[i];
500 pAdd1n[i] = pAdd1[i];
501 }
502 for ( ; i < (1<<Log2); i++ )
503 {
504 pAdd0n[i] = fSign ? pAdd0[nBits-1] : 0;
505 pAdd1n[i] = fSign ? pAdd1[nBits-1] : 0;
506 }
507 Wlc_BlastAdderCLA_int( pNew, pAdd0n, pAdd1n, 1<<Log2, CarryIn );
508 for ( i = 0; i < nBits; i++ )
509 pAdd0[i] = pAdd0n[i];
510 ABC_FREE(pAdd0n);
511 ABC_FREE(pAdd1n);
512}
513
514void Wlc_BlastAdderFast_int( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int Log2, int CarryIn ) // result is in pAdd0
515{
516 int i, b, Gen, Pro, nBits = 1 << Log2;
517 int * pGen = ABC_CALLOC( int, nBits+1 );
518 int * pPro = ABC_CALLOC( int, nBits+1 );
519 int * pPro2= ABC_CALLOC( int, nBits+1 );
520 if ( nBits == 1 )
521 {
522 int Carry = CarryIn;
523 Wlc_BlastFullAdder( pNew, pAdd0[0], pAdd1[0], Carry, &Carry, &pAdd0[0] );
524 ABC_FREE(pGen);
525 ABC_FREE(pPro);
526 ABC_FREE(pPro2);
527 return;
528 }
529 assert( nBits >= 2 );
530 pGen[0] = CarryIn;
531 pPro[0] = 0;
532 pPro2[0]= 0;
533 for ( b = 1; b <= nBits; b++ )
534 {
535 pGen[b] = Gia_ManHashAnd(pNew, pAdd0[b-1], pAdd1[b-1]);
536 pPro[b] = Gia_ManHashXor(pNew, pAdd0[b-1], pAdd1[b-1]);
537 pPro2[b]= pPro[b];
538 }
539
540 // Han-Carlson adder from http://www.aoki.ecei.tohoku.ac.jp/arith/mg/algorithm.html
541 for ( b = 1; b <= nBits; b += 2 )
542 {
543 Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-1]) );
544 Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-1]);
545 pPro[b] = Pro;
546 pGen[b] = Gen;
547 }
548 for ( i = 1; i < Log2-1; i++ )
549 {
550 for ( b = 1 + 2*i; b <= nBits; b += 2 )
551 {
552 Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-i*2]) );
553 Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-i*2]);
554 pPro[b] = Pro;
555 pGen[b] = Gen;
556 }
557 }
558 for ( b = nBits/2 + 1; b <= nBits; b += 2 )
559 {
560 Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-nBits/2]) );
561 Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-nBits/2]);
562 pPro[b] = Pro;
563 pGen[b] = Gen;
564 }
565 for ( b = 2; b <= nBits; b += 2 )
566 {
567 Gen = Gia_ManHashOr( pNew, pGen[b], Gia_ManHashAnd(pNew, pPro[b], pGen[b-1]) );
568 Pro = Gia_ManHashAnd(pNew, pPro[b], pPro[b-1]);
569 pPro[b] = Pro;
570 pGen[b] = Gen;
571 }
572
573 for ( b = 0; b < nBits; b++ )
574 pAdd0[b] = Gia_ManHashXor(pNew, pPro2[b+1], pGen[b]);
575 pAdd0[nBits] = pGen[nBits];
576
577 ABC_FREE(pGen);
578 ABC_FREE(pPro);
579 ABC_FREE(pPro2);
580}
581void Wlc_BlastAdderFast( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int fSign, int CarryIn ) // result is in pAdd0
582{
583 int i, Log2 = Abc_Base2Log(nBits);
584 int * pAdd0n = ABC_CALLOC( int, (1<<Log2)+1 );
585 int * pAdd1n = ABC_CALLOC( int, (1<<Log2)+1 );
586 for ( i = 0; i < nBits; i++ )
587 {
588 pAdd0n[i] = pAdd0[i];
589 pAdd1n[i] = pAdd1[i];
590 }
591 for ( ; i < (1<<Log2); i++ )
592 {
593 pAdd0n[i] = fSign ? pAdd0[nBits-1] : 0;
594 pAdd1n[i] = fSign ? pAdd1[nBits-1] : 0;
595 }
596 Wlc_BlastAdderFast_int( pNew, pAdd0n, pAdd1n, Log2, CarryIn );
597 for ( i = 0; i <= nBits; i++ )
598 pAdd0[i] = pAdd0n[i];
599 ABC_FREE(pAdd0n);
600 ABC_FREE(pAdd1n);
601}
602
603void Wlc_BlastMinus( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vRes )
604{
605 int * pRes = Wlc_VecCopy( vRes, pNum, nNum );
606 int i, invert = 0;
607 for ( i = 0; i < nNum; i++ )
608 {
609 pRes[i] = Gia_ManHashMux( pNew, invert, Abc_LitNot(pRes[i]), pRes[i] );
610 invert = Gia_ManHashOr( pNew, invert, pNum[i] );
611 }
612}
613void Wlc_BlastMultiplier2( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits, Vec_Int_t * vTemp, Vec_Int_t * vRes )
614{
615 int i, j;
616 Vec_IntFill( vRes, nBits, 0 );
617 for ( i = 0; i < nBits; i++ )
618 {
619 Vec_IntFill( vTemp, i, 0 );
620 for ( j = 0; Vec_IntSize(vTemp) < nBits; j++ )
621 Vec_IntPush( vTemp, Gia_ManHashAnd(pNew, pArg0[j], pArg1[i]) );
622 assert( Vec_IntSize(vTemp) == nBits );
623 Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vTemp), nBits, 0 );
624 }
625}
626void Wlc_BlastFullAdderCtrl( Gia_Man_t * pNew, int a, int ac, int b, int c, int * pc, int * ps, int fNeg )
627{
628 int And = Abc_LitNotCond( Gia_ManHashAnd(pNew, a, ac), fNeg );
629 Wlc_BlastFullAdder( pNew, And, b, c, pc, ps );
630}
631void Wlc_BlastFullAdderSubtr( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps, int fSub )
632{
633 Wlc_BlastFullAdder( pNew, Gia_ManHashXor(pNew, a, fSub), b, c, pc, ps );
634}
635void Wlc_BlastMultiplier( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vTemp, Vec_Int_t * vRes, int fSigned )
636{
637 int * pRes, * pArgC, * pArgS, a, b, Carry = fSigned;
638 assert( nArgA > 0 && nArgB > 0 );
639 assert( fSigned == 0 || fSigned == 1 );
640 // prepare result
641 Vec_IntFill( vRes, nArgA + nArgB, 0 );
642 //Vec_IntFill( vRes, nArgA + nArgB + 1, 0 );
643 pRes = Vec_IntArray( vRes );
644 // prepare intermediate storage
645 Vec_IntFill( vTemp, 2 * nArgA, 0 );
646 pArgC = Vec_IntArray( vTemp );
647 pArgS = pArgC + nArgA;
648 // create matrix
649 for ( b = 0; b < nArgB; b++ )
650 for ( a = 0; a < nArgA; a++ )
651 Wlc_BlastFullAdderCtrl( pNew, pArgA[a], pArgB[b], pArgS[a], pArgC[a],
652 &pArgC[a], a ? &pArgS[a-1] : &pRes[b], fSigned && ((a+1 == nArgA) ^ (b+1 == nArgB)) );
653 // final addition
654 pArgS[nArgA-1] = fSigned;
655 for ( a = 0; a < nArgA; a++ )
656 Wlc_BlastFullAdderCtrl( pNew, 1, pArgC[a], pArgS[a], Carry, &Carry, &pRes[nArgB+a], 0 );
657 //Vec_IntWriteEntry( vRes, nArgA + nArgB, Carry );
658}
659void Wlc_BlastMultiplierC( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vTemp, Vec_Int_t * vRes, int fSigned )
660{
661 int * pRes, * pArgC, * pArgS, a, b, Carry = !fSigned; // change
662 assert( nArgA > 0 && nArgB > 0 );
663 assert( fSigned == 0 || fSigned == 1 );
664 Vec_IntFill( vRes, nArgA + nArgB, 0 );
665 pRes = Vec_IntArray( vRes );
666 Vec_IntFill( vTemp, 2 * nArgA, 1 ); // change
667 pArgC = Vec_IntArray( vTemp );
668 pArgS = pArgC + nArgA;
669 for ( b = 0; b < nArgB; b++ )
670 for ( a = 0; a < nArgA; a++ )
671 Wlc_BlastFullAdderCtrl( pNew, pArgA[a], pArgB[b], pArgS[a], pArgC[a],
672 &pArgC[a], a ? &pArgS[a-1] : &pRes[b], !(fSigned && ((a+1 == nArgA) ^ (b+1 == nArgB))) ); // change
673 pArgS[nArgA-1] = !fSigned; // change
674 for ( a = 0; a < nArgA; a++ )
675 Wlc_BlastFullAdderCtrl( pNew, 1, pArgC[a], pArgS[a], Carry, &Carry, &pRes[nArgB+a], 0 );
676 for ( b = 0; b < nArgA + nArgB; b++ ) // change
677 pRes[b] = Abc_LitNot(pRes[b]);
678}
679void Wlc_BlastDivider( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes )
680{
681 int * pRes = Wlc_VecCopy( vRes, pNum, nNum );
682 int * pQuo = ABC_ALLOC( int, nNum );
683 int * pTemp = ABC_ALLOC( int, nNum );
684 int i, j, known, borrow, y_bit, top_bit;
685 assert( nNum == nDiv );
686 for ( j = nNum - 1; j >= 0; j-- )
687 {
688 known = 0;
689 for ( i = nNum - 1; i > nNum - 1 - j; i-- )
690 {
691 known = Gia_ManHashOr( pNew, known, pDiv[i] );
692 if( known == 1 )
693 break;
694 }
695 pQuo[j] = known;
696 for ( i = nNum - 1; i >= 0; i-- )
697 {
698 if ( known == 1 )
699 break;
700 y_bit = (i >= j) ? pDiv[i-j] : 0;
701 pQuo[j] = Gia_ManHashMux( pNew, known, pQuo[j], Gia_ManHashAnd( pNew, y_bit, Abc_LitNot(pRes[i]) ) );
702 known = Gia_ManHashOr( pNew, known, Gia_ManHashXor(pNew, y_bit, pRes[i]));
703 }
704 pQuo[j] = Abc_LitNot(pQuo[j]);
705 if ( pQuo[j] == 0 )
706 continue;
707 borrow = 0;
708 for ( i = 0; i < nNum; i++ )
709 {
710 top_bit = Gia_ManHashMux( pNew, borrow, Abc_LitNot(pRes[i]), pRes[i] );
711 y_bit = (i >= j) ? pDiv[i-j] : 0;
712 borrow = Gia_ManHashMux( pNew, pRes[i], Gia_ManHashAnd(pNew, borrow, y_bit), Gia_ManHashOr(pNew, borrow, y_bit) );
713 pTemp[i] = Gia_ManHashXor( pNew, top_bit, y_bit );
714 }
715 if ( pQuo[j] == 1 )
716 Wlc_VecCopy( vRes, pTemp, nNum );
717 else
718 for( i = 0; i < nNum; i++ )
719 pRes[i] = Gia_ManHashMux( pNew, pQuo[j], pTemp[i], pRes[i] );
720 }
721 ABC_FREE( pTemp );
722 if ( fQuo )
723 Wlc_VecCopy( vRes, pQuo, nNum );
724 ABC_FREE( pQuo );
725}
726// non-restoring divider
727void Wlc_BlastDividerNR( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes )
728{
729 int i, * pRes = Vec_IntArray(vRes);
730 int k, * pQuo = ABC_ALLOC( int, nNum );
731 assert( nNum > 0 && nDiv > 0 );
732 assert( Vec_IntSize(vRes) < nNum + nDiv );
733 for ( i = 0; i < nNum + nDiv; i++ )
734 pRes[i] = i < nNum ? pNum[i] : 0;
735 for ( i = nNum-1; i >= 0; i-- )
736 {
737 int Cntrl = i == nNum-1 ? 1 : pQuo[i+1];
738 int Carry = Cntrl;
739 for ( k = 0; k <= nDiv; k++ )
740 Wlc_BlastFullAdderSubtr( pNew, k < nDiv ? pDiv[k] : 0, pRes[i+k], Carry, &Carry, &pRes[i+k], Cntrl );
741 pQuo[i] = Abc_LitNot(pRes[i+nDiv]);
742 }
743 if ( fQuo )
744 Wlc_VecCopy( vRes, pQuo, nNum );
745 else
746 {
747 int Carry = 0, Temp;
748 for ( k = 0; k < nDiv; k++ )
749 {
750 Wlc_BlastFullAdder( pNew, pDiv[k], pRes[k], Carry, &Carry, &Temp );
751 pRes[k] = Gia_ManHashMux( pNew, pQuo[0], pRes[k], Temp );
752 }
753 Vec_IntShrink( vRes, nDiv );
754 }
755 ABC_FREE( pQuo );
756}
757void Wlc_BlastDividerTop( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes, int fNonRest )
758{
759 if ( fNonRest )
760 Wlc_BlastDividerNR( pNew, pNum, nNum, pDiv, nDiv, fQuo, vRes );
761 else
762 Wlc_BlastDivider( pNew, pNum, nNum, pDiv, nDiv, fQuo, vRes );
763}
764void Wlc_BlastDividerSigned( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes, int fNonRest )
765{
766 Vec_Int_t * vNum = Vec_IntAlloc( nNum );
767 Vec_Int_t * vDiv = Vec_IntAlloc( nDiv );
768 Vec_Int_t * vRes00 = Vec_IntAlloc( nNum + nDiv );
769 Vec_Int_t * vRes01 = Vec_IntAlloc( nNum + nDiv );
770 Vec_Int_t * vRes10 = Vec_IntAlloc( nNum + nDiv );
771 Vec_Int_t * vRes11 = Vec_IntAlloc( nNum + nDiv );
772 Vec_Int_t * vRes2 = Vec_IntAlloc( nNum );
773 int k, iDiffSign = Gia_ManHashXor( pNew, pNum[nNum-1], pDiv[nDiv-1] );
774 Wlc_BlastMinus( pNew, pNum, nNum, vNum );
775 Wlc_BlastMinus( pNew, pDiv, nDiv, vDiv );
776 Wlc_BlastDividerTop( pNew, pNum, nNum, pDiv, nDiv, fQuo, vRes00, fNonRest );
777 Wlc_BlastDividerTop( pNew, pNum, nNum, Vec_IntArray(vDiv), nDiv, fQuo, vRes01, fNonRest );
778 Wlc_BlastDividerTop( pNew, Vec_IntArray(vNum), nNum, pDiv, nDiv, fQuo, vRes10, fNonRest );
779 Wlc_BlastDividerTop( pNew, Vec_IntArray(vNum), nNum, Vec_IntArray(vDiv), nDiv, fQuo, vRes11, fNonRest );
780 Vec_IntClear( vRes );
781 for ( k = 0; k < nNum; k++ )
782 {
783 int Data0 = Gia_ManHashMux( pNew, pDiv[nDiv-1], Vec_IntEntry(vRes01,k), Vec_IntEntry(vRes00,k) );
784 int Data1 = Gia_ManHashMux( pNew, pDiv[nDiv-1], Vec_IntEntry(vRes11,k), Vec_IntEntry(vRes10,k) );
785 Vec_IntPush( vRes, Gia_ManHashMux(pNew, pNum[nNum-1], Data1, Data0) );
786 }
787 Wlc_BlastMinus( pNew, Vec_IntArray(vRes), nNum, vRes2 );
788 for ( k = 0; k < nNum; k++ )
789 Vec_IntWriteEntry( vRes, k, Gia_ManHashMux(pNew, fQuo ? iDiffSign : pNum[nNum-1], Vec_IntEntry(vRes2,k), Vec_IntEntry(vRes,k)) );
790 Vec_IntFree( vNum );
791 Vec_IntFree( vDiv );
792 Vec_IntFree( vRes00 );
793 Vec_IntFree( vRes01 );
794 Vec_IntFree( vRes10 );
795 Vec_IntFree( vRes11 );
796 Vec_IntFree( vRes2 );
797 assert( Vec_IntSize(vRes) == nNum );
798}
799void Wlc_BlastZeroCondition( Gia_Man_t * pNew, int * pDiv, int nDiv, Vec_Int_t * vRes )
800{
801 int i, Entry, iLit = Wlc_BlastReduction( pNew, pDiv, nDiv, WLC_OBJ_REDUCT_OR );
802 Vec_IntForEachEntry( vRes, Entry, i )
803 Vec_IntWriteEntry( vRes, i, Gia_ManHashAnd(pNew, iLit, Entry) );
804}
805void Wlc_BlastTable( Gia_Man_t * pNew, word * pTable, int * pFans, int nFans, int nOuts, Vec_Int_t * vRes )
806{
807 extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
808 Vec_Int_t * vMemory = Vec_IntAlloc( 0 );
809 Vec_Int_t vLeaves = { nFans, nFans, pFans };
810 word * pTruth = ABC_ALLOC( word, Abc_TtWordNum(nFans) );
811 int o, i, m, iLit, nMints = (1 << nFans);
812 Vec_IntClear( vRes );
813 for ( o = 0; o < nOuts; o++ )
814 {
815 // derive truth table
816 memset( pTruth, 0, sizeof(word) * Abc_TtWordNum(nFans) );
817 for ( m = 0; m < nMints; m++ )
818 for ( i = 0; i < nFans; i++ )
819 if ( Abc_TtGetBit( pTable, m * nFans + i ) )
820 Abc_TtSetBit( pTruth, m );
821 // implement truth table
822 if ( nFans < 6 )
823 pTruth[0] = Abc_Tt6Stretch( pTruth[0], nFans );
824 iLit = Kit_TruthToGia( pNew, (unsigned *)pTruth, nFans, vMemory, &vLeaves, 1 );
825 Vec_IntPush( vRes, iLit );
826 }
827 Vec_IntFree( vMemory );
828 ABC_FREE( pTruth );
829}
830void Wlc_BlastLut( Gia_Man_t * pNew, word Truth, int * pFans, int nFans, int nOuts, Vec_Int_t * vRes )
831{
832 extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
833 Vec_Int_t * vMemory = Vec_IntAlloc( 0 );
834 Vec_Int_t vLeaves = { nFans, nFans, pFans };
835 int iLit;
836 Vec_IntClear( vRes );
837 assert( nOuts == 1 );
838 if ( nFans < 6 )
839 Truth = Abc_Tt6Stretch( Truth, nFans );
840 iLit = Kit_TruthToGia( pNew, (unsigned *)&Truth, nFans, vMemory, &vLeaves, 1 );
841 Vec_IntPush( vRes, iLit );
842 Vec_IntFree( vMemory );
843}
844void Wlc_BlastPower( Gia_Man_t * pNew, int * pNum, int nNum, int * pExp, int nExp, Vec_Int_t * vTemp, Vec_Int_t * vRes )
845{
846 Vec_Int_t * vDegrees = Vec_IntAlloc( 2*nNum );
847 Vec_Int_t * vResTemp = Vec_IntAlloc( 2*nNum );
848 int i, * pDegrees = NULL, * pRes = Vec_IntArray(vRes);
849 int k, * pResTemp = Vec_IntArray(vResTemp);
850 Vec_IntFill( vRes, nNum, 0 );
851 Vec_IntWriteEntry( vRes, 0, 1 );
852 for ( i = 0; i < nExp; i++ )
853 {
854 if ( i == 0 )
855 pDegrees = Wlc_VecCopy( vDegrees, pNum, nNum );
856 else
857 {
858 Wlc_BlastMultiplier2( pNew, pDegrees, pDegrees, nNum, vTemp, vResTemp );
859 pDegrees = Wlc_VecCopy( vDegrees, pResTemp, nNum );
860 }
861 Wlc_BlastMultiplier2( pNew, pRes, pDegrees, nNum, vTemp, vResTemp );
862 for ( k = 0; k < nNum; k++ )
863 pRes[k] = Gia_ManHashMux( pNew, pExp[i], pResTemp[k], pRes[k] );
864 }
865 Vec_IntFree( vResTemp );
866 Vec_IntFree( vDegrees );
867}
868void Wlc_BlastSqrt( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_Int_t * vRes )
869{
870 int * pRes, * pSum, * pSumP;
871 int i, k, Carry = -1;
872 assert( nNum % 2 == 0 );
873 Vec_IntFill( vRes, nNum/2, 0 );
874 Vec_IntFill( vTmp, 2*nNum, 0 );
875 pRes = Vec_IntArray( vRes );
876 pSum = Vec_IntArray( vTmp );
877 pSumP = pSum + nNum;
878 for ( i = 0; i < nNum/2; i++ )
879 {
880 pSumP[0] = pNum[nNum-2*i-2];
881 pSumP[1] = pNum[nNum-2*i-1];
882 for ( k = 0; k < i+1; k++ )
883 pSumP[k+2] = pSum[k];
884 for ( k = 0; k < i + 3; k++ )
885 {
886 if ( k >= 2 && k < i + 2 ) // middle ones
887 Wlc_BlastFullAdder( pNew, pSumP[k], Abc_LitNot(pRes[i-k+1]), Carry, &Carry, &pSum[k] );
888 else
889 Wlc_BlastFullAdder( pNew, pSumP[k], Abc_LitNot(k ? Carry:1), 1, &Carry, &pSum[k] );
890 if ( k == 0 || k > i )
891 Carry = Abc_LitNot(Carry);
892 }
893 pRes[i] = Abc_LitNot(Carry);
894 for ( k = 0; k < i + 3; k++ )
895 pSum[k] = Gia_ManHashMux( pNew, pRes[i], pSum[k], pSumP[k] );
896 }
897 Vec_IntReverseOrder( vRes );
898}
899void Wlc_BlastSqrtNR( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_Int_t * vRes )
900{
901 int * pSqr, * pRem, * pIn1;
902 int i, k, Carry = 1;
903 assert( nNum % 2 == 0 );
904 Vec_IntFill( vRes, nNum/2, 0 );
905 Vec_IntFill( vTmp, 2*nNum, 0 );
906 pSqr = Vec_IntArray( vRes );
907 pRem = Vec_IntArray( vTmp );
908 pIn1 = pRem + nNum;
909 for ( i = 0; i < nNum/2; i++ )
910 {
911 int SqrPrev = Carry;
912 assert( pIn1[0] == 0 );
913 for ( k = 1; k < i; k++ )
914 pIn1[k] = 0;
915 for ( k = i; k < 2*i; k++ )
916 pIn1[k] = pSqr[k-i];
917 pIn1[k++] = Abc_LitNot(Carry);
918 pIn1[k++] = 1;
919 assert( k == 2*i+2 );
920 pRem[2*i+0] = pNum[nNum-2*i-1];
921 pRem[2*i+1] = pNum[nNum-2*i-2];
922 for ( k = 2*i+1; k >= 0; k-- )
923 Wlc_BlastFullAdder( pNew, Gia_ManHashXor(pNew, SqrPrev, pIn1[k]), pRem[k], Carry, &Carry, &pRem[k] );
924 pSqr[i] = Carry;
925 }
926 Vec_IntReverseOrder( vRes );
927}
928void Wlc_IntInsert( Vec_Int_t * vProd, Vec_Int_t * vLevel, int Node, int Level )
929{
930 int i;
931 for ( i = Vec_IntSize(vLevel) - 1; i >= 0; i-- )
932 if ( Vec_IntEntry(vLevel, i) >= Level )
933 break;
934 Vec_IntInsert( vProd, i + 1, Node );
935 Vec_IntInsert( vLevel, i + 1, Level );
936}
937void Wlc_BlastPrintMatrix( Gia_Man_t * p, Vec_Wec_t * vProds, int fVerbose )
938{
939 Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
940 Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
941 Vec_Int_t * vLevel; word Truth;
942 int i, k, iLit;
943 Vec_WecForEachLevel( vProds, vLevel, i )
944 Vec_IntForEachEntry( vLevel, iLit, k )
945 if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) )
946 Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) );
947 printf( "Booth partial products: %d pps, %d unique, %d nodes.\n",
948 Vec_WecSizeSize(vProds), Vec_IntSize(vSupp), Gia_ManAndNum(p) );
949 Vec_IntPrint( vSupp );
950
951 if ( fVerbose )
952 Vec_WecForEachLevel( vProds, vLevel, i )
953 Vec_IntForEachEntry( vLevel, iLit, k )
954 {
955 printf( "Obj = %4d : ", Abc_Lit2Var(iLit) );
956 printf( "Compl = %d ", Abc_LitIsCompl(iLit) );
957 printf( "Rank = %2d ", i );
958 Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp );
959 Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
960 if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
961 if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
962 if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
963 printf( " " );
964 Vec_IntPrint( vSupp );
965 if ( k == Vec_IntSize(vLevel)-1 )
966 printf( "\n" );
967 }
968 Vec_IntFree( vSupp );
969 Vec_WrdFree( vTemp );
970}
971void Wlc_BlastReduceMatrix( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Wec_t * vLevels, Vec_Int_t * vRes, int fSigned, int fCla )
972{
973 Vec_Int_t * vLevel, * vProd;
974 int i, NodeS, NodeC, LevelS, LevelC, Node1, Node2, Node3, Level1, Level2, Level3;
975 int nSize = Vec_WecSize(vProds), nFAs = Vec_WecSize(vProds), nHAs = 0;
976 assert( nSize == Vec_WecSize(vLevels) );
977 for ( i = 0; i < nSize; i++ )
978 {
979 while ( 1 )
980 {
981 vProd = Vec_WecEntry( vProds, i );
982 if ( Vec_IntSize(vProd) < 3 )
983 break;
984
985 Node1 = Vec_IntPop( vProd );
986 Node2 = Vec_IntPop( vProd );
987 Node3 = Vec_IntPop( vProd );
988
989 vLevel = Vec_WecEntry( vLevels, i );
990
991 Level1 = Vec_IntPop( vLevel );
992 Level2 = Vec_IntPop( vLevel );
993 Level3 = Vec_IntPop( vLevel );
994
995 int nInputs = (Node1 > 1) + (Node2 > 1) + (Node3 > 1);
996 if ( nInputs == 3 )
997 nFAs++;
998 else if ( nInputs == 2 )
999 nHAs++;
1000
1001 Wlc_BlastFullAdder( pNew, Node1, Node2, Node3, &NodeC, &NodeS );
1002 LevelS = Abc_MaxInt( Abc_MaxInt(Level1, Level2), Level3 ) + 2;
1003 LevelC = LevelS - 1;
1004
1005 Wlc_IntInsert( vProd, vLevel, NodeS, LevelS );
1006
1007 vProd = Vec_WecEntry( vProds, i+1 );
1008 vLevel = Vec_WecEntry( vLevels, i+1 );
1009
1010 Wlc_IntInsert( vProd, vLevel, NodeC, LevelC );
1011 }
1012 }
1013
1014 // make all ranks have two products
1015 for ( i = 0; i < nSize; i++ )
1016 {
1017 vProd = Vec_WecEntry( vProds, i );
1018 while ( Vec_IntSize(vProd) < 2 )
1019 Vec_IntPush( vProd, 0 ), nFAs--, nHAs++;
1020 assert( Vec_IntSize(vProd) == 2 );
1021 }
1022// Vec_WecPrint( vProds, 0 );
1023
1024 vLevel = Vec_WecEntry( vLevels, 0 );
1025 Vec_IntClear( vRes );
1026 Vec_IntClear( vLevel );
1027 for ( i = 0; i < nSize; i++ )
1028 {
1029 vProd = Vec_WecEntry( vProds, i );
1030 Vec_IntPush( vRes, Vec_IntEntry(vProd, 0) );
1031 Vec_IntPush( vLevel, Vec_IntEntry(vProd, 1) );
1032 }
1033 Vec_IntPush( vRes, 0 );
1034 Vec_IntPush( vLevel, 0 );
1035
1036 if ( fCla )
1037 Wlc_BlastAdderCLA( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), fSigned, 0 );
1038 else
1039 Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vLevel), Vec_IntSize(vRes), 0 );
1040 //printf( "Created %d-bit %d-input AT with %d FAs and %d HAs.\n", Vec_WecSize(vProds), Vec_WecSizeSize(vProds), nFAs, nHAs );
1041}
1042
1043int Wlc_BlastAddLevel( Gia_Man_t * pNew, int Start )
1044{
1045 int i;
1046 if ( Start == 0 )
1047 Gia_ManCleanLevels( pNew, 5 * Gia_ManObjNum(pNew) );
1048 for ( i = Start; i < Gia_ManObjNum(pNew); i++ )
1049 {
1050 Gia_Obj_t * pObj = Gia_ManObj( pNew, i );
1051 if ( Gia_ObjIsAnd(pObj) )
1052 Gia_ObjSetAndLevel( pNew, pObj );
1053 }
1054 return Gia_ManObjNum(pNew);
1055}
1056void Wlc_IntInsert2( Gia_Man_t * pNew, Vec_Int_t * vProd, int iLit )
1057{
1058 int i, Entry, Level = Gia_ObjLevelId(pNew, Abc_Lit2Var(iLit));
1059 Vec_IntForEachEntryReverse( vProd, Entry, i )
1060 if ( Gia_ObjLevelId(pNew, Abc_Lit2Var(Entry)) >= Level )
1061 break;
1062 Vec_IntInsert( vProd, i + 1, iLit );
1063// Vec_IntForEachEntry( vProd, Entry, i )
1064// printf( "Obj=%d(%d) ", Abc_Lit2Var(Entry), Gia_ObjLevelId(pNew, Abc_Lit2Var(Entry)) );
1065// printf( "\n" );
1066}
1067void Wlc_IntSortCostReverse( Gia_Man_t * pNew, int * pArray, int nSize )
1068{
1069 int i, j, best_i;
1070 for ( i = 0; i < nSize-1; i++ )
1071 {
1072 best_i = i;
1073 for ( j = i+1; j < nSize; j++ )
1074 if ( Gia_ObjLevelId(pNew, Abc_Lit2Var(pArray[j])) > Gia_ObjLevelId(pNew, Abc_Lit2Var(pArray[best_i])) )
1075 best_i = j;
1076 ABC_SWAP( int, pArray[i], pArray[best_i] );
1077 }
1078}
1079void Wlc_BlastReduceMatrix2( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Int_t * vRes, int fSigned, int fCla )
1080{
1081 Vec_Int_t * vProd, * vTemp;
1082 int i, NodeS, NodeC, Node1, Node2, Node3;
1083 int Start = Wlc_BlastAddLevel( pNew, 0 );
1084 int nSize = Vec_WecSize(vProds);
1085 Vec_WecForEachLevel( vProds, vProd, i )
1086 Wlc_IntSortCostReverse( pNew, Vec_IntArray(vProd), Vec_IntSize(vProd) );
1087 for ( i = 0; i < nSize; i++ )
1088 {
1089 while ( 1 )
1090 {
1091 vProd = Vec_WecEntry( vProds, i );
1092 if ( Vec_IntSize(vProd) < 3 )
1093 break;
1094
1095 Node1 = Vec_IntPop( vProd );
1096 Node2 = Vec_IntPop( vProd );
1097 Node3 = Vec_IntPop( vProd );
1098
1099 assert( Gia_ObjLevelId(pNew, Abc_Lit2Var(Node3)) >= Gia_ObjLevelId(pNew, Abc_Lit2Var(Node2)) );
1100 assert( Gia_ObjLevelId(pNew, Abc_Lit2Var(Node2)) >= Gia_ObjLevelId(pNew, Abc_Lit2Var(Node1)) );
1101
1102 Wlc_BlastFullAdder( pNew, Node1, Node2, Node3, &NodeC, &NodeS );
1103 Start = Wlc_BlastAddLevel( pNew, Start );
1104
1105 Wlc_IntInsert2( pNew, vProd, NodeS );
1106
1107 vProd = Vec_WecEntry( vProds, i+1 );
1108 Wlc_IntInsert2( pNew, vProd, NodeC );
1109 }
1110 }
1111
1112 // make all ranks have two products
1113 for ( i = 0; i < nSize; i++ )
1114 {
1115 vProd = Vec_WecEntry( vProds, i );
1116 while ( Vec_IntSize(vProd) < 2 )
1117 Vec_IntPush( vProd, 0 );
1118 assert( Vec_IntSize(vProd) == 2 );
1119 }
1120// Vec_WecPrint( vProds, 0 );
1121
1122 Vec_IntClear( vRes );
1123 vTemp = Vec_IntAlloc( 100 );
1124 for ( i = 0; i < nSize; i++ )
1125 {
1126 vProd = Vec_WecEntry( vProds, i );
1127 Vec_IntPush( vRes, Vec_IntEntry(vProd, 0) );
1128 Vec_IntPush( vTemp, Vec_IntEntry(vProd, 1) );
1129 }
1130 Vec_IntPush( vRes, 0 );
1131 Vec_IntPush( vTemp, 0 );
1132
1133 if ( fCla )
1134 Wlc_BlastAdderCLA( pNew, Vec_IntArray(vRes), Vec_IntArray(vTemp), Vec_IntSize(vRes), fSigned, 0 );
1135 else
1136 Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vTemp), Vec_IntSize(vRes), 0 );
1137 Vec_IntFree( vTemp );
1138}
1139
1140void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds, int fVerbose )
1141{
1142 Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB );
1143 Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB );
1144 int i, k;
1145 for ( i = 0; i < nArgA; i++ )
1146 for ( k = 0; k < nArgB; k++ )
1147 {
1148 int fCompl = fSigned && ((i == nArgA-1) ^ (k == nArgB-1));
1149 Vec_WecPush( vProds, i+k, Abc_LitNotCond(Gia_ManHashAnd(pNew, pArgA[i], pArgB[k]), fCompl) );
1150 Vec_WecPush( vLevels, i+k, 0 );
1151 }
1152 if ( fSigned )
1153 {
1154 Vec_WecPush( vProds, nArgB-1, 1 );
1155 Vec_WecPush( vLevels, nArgB-1, 0 );
1156
1157 Vec_WecPush( vProds, nArgA-1, 1 );
1158 Vec_WecPush( vLevels, nArgA-1, 0 );
1159
1160 Vec_WecPush( vProds, nArgA+nArgB-1, 1 );
1161 Vec_WecPush( vLevels, nArgA+nArgB-1, 0 );
1162 }
1163 if ( fVerbose )
1164 Vec_WecPrint( vProds, 0 );
1165 if ( pvProds )
1166 *pvProds = Vec_WecDup(vProds);
1167 else
1168 Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla );
1169// Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla );
1170
1171 Vec_WecFree( vProds );
1172 Vec_WecFree( vLevels );
1173}
1174void Wlc_BlastSquare( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_Int_t * vRes )
1175{
1176 Vec_Wec_t * vProds = Vec_WecStart( 2*nNum );
1177 Vec_Wec_t * vLevels = Vec_WecStart( 2*nNum );
1178 int i, k;
1179 for ( i = 0; i < nNum; i++ )
1180 for ( k = 0; k < nNum; k++ )
1181 {
1182 if ( i == k )
1183 {
1184 Vec_WecPush( vProds, i+k, pNum[i] );
1185 Vec_WecPush( vLevels, i+k, 0 );
1186 }
1187 else if ( i < k )
1188 {
1189 Vec_WecPush( vProds, i+k+1, Gia_ManHashAnd(pNew, pNum[i], pNum[k]) );
1190 Vec_WecPush( vLevels, i+k+1, 0 );
1191 }
1192 }
1193
1194 Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, 0, 0 );
1195
1196 Vec_WecFree( vProds );
1197 Vec_WecFree( vLevels );
1198}
1199void Wlc_BlastDecoder( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_Int_t * vRes )
1200{
1201 int i, k, nMints = 1 << nNum;
1202 Vec_IntClear( vRes );
1203 for ( i = 0; i < nMints; i++ )
1204 {
1205 int iMint = 1;
1206 for ( k = 0; k < nNum; k++ )
1207 iMint = Gia_ManHashAnd( pNew, iMint, Abc_LitNotCond(pNum[k], !((i >> k) & 1)) );
1208 Vec_IntPush( vRes, iMint );
1209 }
1210}
1211Vec_Int_t * Wlc_BlastDecoder2_rec( Gia_Man_t * p, int * pLits, int nLits )
1212{
1213 if ( nLits == 1 )
1214 {
1215 Vec_Int_t * vRes = Vec_IntAlloc( 2 );
1216 Vec_IntPush( vRes, Abc_LitNot(pLits[0]) );
1217 Vec_IntPush( vRes, pLits[0] );
1218 return vRes;
1219 }
1220 assert( nLits > 1 );
1221 int nPart1 = nLits / 2;
1222 int nPart2 = nLits - nPart1;
1223 Vec_Int_t * vRes1 = Wlc_BlastDecoder2_rec( p, pLits, nPart1 );
1224 Vec_Int_t * vRes2 = Wlc_BlastDecoder2_rec( p, pLits+nPart1, nPart2 );
1225 Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vRes1) * Vec_IntSize(vRes2) );
1226 int i, k, Lit1, Lit2;
1227 Vec_IntForEachEntry( vRes2, Lit2, k )
1228 Vec_IntForEachEntry( vRes1, Lit1, i )
1229 Vec_IntPush( vRes, Gia_ManHashAnd(p, Lit1, Lit2) );
1230 Vec_IntFree( vRes1 );
1231 Vec_IntFree( vRes2 );
1232 return vRes;
1233}
1234Vec_Int_t * Wlc_BlastDecoder2( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_Int_t * vRes )
1235{
1236 Vec_Int_t * vRes2 = Wlc_BlastDecoder2_rec( pNew, pNum, nNum );
1237 Vec_IntClear( vRes );
1238 Vec_IntAppend( vRes, vRes2 );
1239 Vec_IntFree( vRes2 );
1240 return vRes;
1241}
1242void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds, int fVerbose )
1243{
1244 Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB + 3 );
1245 Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB + 3 );
1246 int FillA = fSigned ? pArgA[nArgA-1] : 0;
1247 int FillB = fSigned ? pArgB[nArgB-1] : 0;
1248 int i, k, Sign;
1249
1250 // extend argument B
1251 Vec_Int_t * vArgB = Vec_IntAlloc( nArgB + 2 );
1252 Vec_IntPush( vArgB, 0 );
1253 for ( i = 0; i < nArgB; i++ )
1254 Vec_IntPush( vArgB, pArgB[i] );
1255 if ( !fSigned )
1256 Vec_IntPushTwo( vArgB, FillB, FillB );
1257 if ( Vec_IntSize(vArgB) % 2 == 0 )
1258 Vec_IntPush( vArgB, FillB );
1259 assert( Vec_IntSize(vArgB) % 2 == 1 );
1260
1261 // iterate through bit-pairs of B
1262 for ( k = 0; k+2 < Vec_IntSize(vArgB); k+=2 )
1263 {
1264 int pp = -1;
1265 int Q2jM1 = Vec_IntEntry(vArgB, k); // q(2*j-1)
1266 int Q2j = Vec_IntEntry(vArgB, k+1); // q(2*j+0)
1267 int Q2jP1 = Vec_IntEntry(vArgB, k+2); // q(2*j+1)
1268 int Neg = Q2jP1;
1269 int One = Gia_ManHashXor( pNew, Q2j, Q2jM1 );
1270 int Two = Gia_ManHashMux( pNew, Neg, Gia_ManHashAnd(pNew, Abc_LitNot(Q2j), Abc_LitNot(Q2jM1)), Gia_ManHashAnd(pNew, Q2j, Q2jM1) );
1271 for ( i = 0; i <= nArgA; i++ )
1272 {
1273 int This = i == nArgA ? FillA : pArgA[i];
1274 int Prev = i ? pArgA[i-1] : 0;
1275 int Part = Gia_ManHashOr( pNew, Gia_ManHashAnd(pNew, One, This), Gia_ManHashAnd(pNew, Two, Prev) );
1276 pp = Gia_ManHashXor( pNew, Part, Neg );
1277 if ( fVerbose ) printf( "%4d = PP(%5d %5d %5d %5d %5d)\n", pp, Prev, This, Q2jM1, Q2j, Q2jP1 );
1278 if ( pp == 0 || (fSigned && i == nArgA) )
1279 continue;
1280 if ( pp )
1281 {
1282 Vec_WecPush( vProds, k+i, pp );
1283 Vec_WecPush( vLevels, k+i, 0 );
1284 }
1285 }
1286 if ( fSigned ) i--;
1287 // perform sign extension
1288 Sign = fSigned ? pp : Neg;
1289 if ( k == 0 )
1290 {
1291 Vec_WecPush( vProds, k+i, Sign );
1292 Vec_WecPush( vLevels, k+i, 0 );
1293
1294 Vec_WecPush( vProds, k+i+1, Sign );
1295 Vec_WecPush( vLevels, k+i+1, 0 );
1296
1297 if ( Sign != 1 )
1298 {
1299 Vec_WecPush( vProds, k+i+2, Abc_LitNot(Sign) );
1300 Vec_WecPush( vLevels, k+i+2, 0 );
1301 }
1302 }
1303 else
1304 {
1305 if ( Sign != 1 )
1306 {
1307 Vec_WecPush( vProds, k+i, Abc_LitNot(Sign) );
1308 Vec_WecPush( vLevels, k+i, 0 );
1309 }
1310
1311 Vec_WecPush( vProds, k+i+1, 1 );
1312 Vec_WecPush( vLevels, k+i+1, 0 );
1313 }
1314 // add neg to the first column
1315 if ( Neg == 0 )
1316 continue;
1317 Vec_WecPush( vProds, k, Neg );
1318 Vec_WecPush( vLevels, k, 0 );
1319 }
1320 //Vec_WecShrink( vProds, nArgA + nArgB );
1321 //Vec_WecShrink( vLevels, nArgA + nArgB );
1322 if ( fVerbose )
1323 Vec_WecPrint( vProds, 0 );
1324 if ( fVerbose )
1325 printf( "Total PPs = %d.\n", Vec_WecSizeSize(vProds) );
1326 //Wlc_BlastPrintMatrix( pNew, vProds, 1 );
1327 //printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) );
1328 if ( pvProds )
1329 *pvProds = Vec_WecDup(vProds);
1330 else
1331 Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla );
1332 // Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla );
1333 Vec_WecFree( vProds );
1334 Vec_WecFree( vLevels );
1335 Vec_IntFree( vArgB );
1336}
1337
1350{
1351 int fVerbose = 0;
1352 int fUseOldMultiplierBlasting = 0;
1353 int fSkipBitRange = 0;
1354 Tim_Man_t * pManTime = NULL;
1355 If_LibBox_t * pBoxLib = NULL;
1356 Vec_Ptr_t * vTables = NULL;
1357 Vec_Int_t * vFf2Ci = Vec_IntAlloc( 100 );
1358 Vec_Int_t * vRegClasses = NULL;
1359 Gia_Man_t * pTemp, * pNew, * pExtra = NULL;
1360 Wlc_Obj_t * pObj, * pObj2;
1361 Vec_Int_t * vBits = &p->vBits, * vTemp0, * vTemp1, * vTemp2, * vRes, * vAddOutputs = NULL, * vAddObjs = NULL;
1362 int nBits = Wlc_NtkPrepareBits( p );
1363 int nRange, nRange0, nRange1, nRange2, nRange3;
1364 int i, k, b, iFanin, iLit, nAndPrev, * pFans0, * pFans1, * pFans2, * pFans3;
1365 int nFFins = 0, nFFouts = 0, curPi = 0, curPo = 0, nFf2Regs = 0;
1366 int nBitCis = 0, nBitCos = 0, fAdded = 0;
1367 Wlc_BstPar_t Par, * pPar = &Par;
1368 Wlc_BstParDefault( pPar );
1369 pPar = pParIn ? pParIn : pPar;
1370 Vec_IntClear( vBits );
1371 Vec_IntGrow( vBits, nBits );
1372 vTemp0 = Vec_IntAlloc( 1000 );
1373 vTemp1 = Vec_IntAlloc( 1000 );
1374 vTemp2 = Vec_IntAlloc( 1000 );
1375 vRes = Vec_IntAlloc( 1000 );
1376 // clean AND-gate counters
1377 memset( p->nAnds, 0, sizeof(int) * WLC_OBJ_NUMBER );
1378 // create AIG manager
1379 pNew = Gia_ManStart( 5 * Wlc_NtkObjNum(p) + 1000 );
1380 pNew->pName = Abc_UtilStrsav( p->pName );
1381 pNew->fGiaSimple = pPar->fGiaSimple;
1382 if ( !pPar->fGiaSimple )
1383 Gia_ManHashAlloc( pNew );
1384 if ( pPar->fAddOutputs )
1385 vAddOutputs = Vec_IntAlloc( 100 );
1386 if ( pPar->fAddOutputs )
1387 vAddObjs = Vec_IntAlloc( 100 );
1388 // prepare for AIG with boxes
1389 if ( pPar->vBoxIds )
1390 {
1391 int nNewCis = 0, nNewCos = 0;
1392 assert( Vec_IntSize(&p->vFfs2) == 0 );
1393 Wlc_NtkForEachObj( p, pObj, i )
1394 pObj->Mark = 0;
1395 // count bit-width of regular CIs/COs
1396 Wlc_NtkForEachCi( p, pObj, i )
1397 nBitCis += Wlc_ObjRange( pObj );
1398 Wlc_NtkForEachCo( p, pObj, i )
1399 nBitCos += Wlc_ObjRange( pObj );
1400 // count bit-width of additional CIs/COs due to selected multipliers
1401 assert( Vec_IntSize(pPar->vBoxIds) > 0 );
1402 Wlc_NtkForEachObjVec( pPar->vBoxIds, p, pObj, i )
1403 {
1404 // currently works only for multipliers
1405 assert( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_ADD );
1406 nNewCis += Wlc_ObjRange( pObj );
1407 nNewCos += Wlc_ObjRange( Wlc_ObjFanin0(p, pObj) );
1408 nNewCos += Wlc_ObjRange( Wlc_ObjFanin1(p, pObj) );
1409 if ( Wlc_ObjFaninNum(pObj) > 2 )
1410 nNewCos += Wlc_ObjRange( Wlc_ObjFanin2(p, pObj) );
1411 pObj->Mark = 1;
1412 }
1413 // create hierarchy manager
1414 pManTime = Tim_ManStart( nBitCis + nNewCis, nBitCos + nNewCos );
1415 curPi = nBitCis;
1416 curPo = 0;
1417 // create AIG manager for logic of the boxes
1418 pExtra = Gia_ManStart( Wlc_NtkObjNum(p) );
1419 Gia_ManHashAlloc( pExtra );
1420 assert( !pPar->fGiaSimple );
1421 // create box library
1422 pBoxLib = If_LibBoxStart();
1423 }
1424 if ( Vec_IntSize(&p->vFfs2) > 0 )
1425 {
1426 Vec_Int_t * vSignature;
1427 int nNewCis = 0, nNewCos = 0;
1428 assert( pPar->vBoxIds == 0 );
1429 // count bit-width of regular CIs/COs
1430 Wlc_NtkForEachCi( p, pObj, i )
1431 nBitCis += Wlc_ObjRange( pObj );
1432 Wlc_NtkForEachCo( p, pObj, i )
1433 nBitCos += Wlc_ObjRange( pObj );
1434 // count bit-width of additional CIs/COs due to selected multipliers
1435 Wlc_NtkForEachFf2( p, pObj, i )
1436 {
1437 // currently works only for multipliers
1438 assert( pObj->Type == WLC_OBJ_FF );
1439 assert( Wlc_ObjRange(pObj) == Wlc_ObjRange(Wlc_ObjFanin0(p, pObj)) );
1440 nNewCis += Wlc_ObjRange(pObj);
1441 nNewCos += 2*Wlc_ObjRange(pObj) + 3;
1442 nFf2Regs+= Wlc_ObjRange(pObj);
1443 }
1444 // create hierarchy manager
1445 pManTime = Tim_ManStart( nBitCis + nNewCis + nFf2Regs, nBitCos + nNewCos + nFf2Regs );
1446 curPi = nBitCis + nFf2Regs;
1447 curPo = 0;
1448 // create AIG manager for logic of the boxes
1449 pExtra = Gia_ManStart( Wlc_NtkObjNum(p) );
1450 Gia_ManHashAlloc( pExtra );
1451 assert( !pPar->fGiaSimple );
1452 // create register classes
1453 vRegClasses = Vec_IntAlloc(0);
1454 vSignature = Vec_IntAlloc( 100 );
1455 Vec_IntPushTwo( vSignature, -1, -1 );
1456 Wlc_NtkForEachFf2( p, pObj, i )
1457 {
1458 int iClk0, iClk = Wlc_ObjFaninId( pObj, 1 );
1459 int iAsyn0, iAsyn = Wlc_ObjFaninId( pObj, 5 );
1460 nRange = Wlc_ObjRange(pObj);
1461 Vec_IntForEachEntryDouble( vSignature, iClk0, iAsyn0, k )
1462 if ( iClk == iClk0 && iAsyn == iAsyn0 )
1463 {
1464 for ( b = 0; b < nRange; b++ )
1465 Vec_IntPush( vRegClasses, k/2 );
1466 break;
1467 }
1468 if ( k < Vec_IntSize(vSignature) )
1469 continue;
1470 for ( b = 0; b < nRange; b++ )
1471 Vec_IntPush( vRegClasses, k/2 );
1472 Vec_IntPushTwo( vSignature, iClk, iAsyn );
1473 }
1474 assert( Vec_IntSize(vRegClasses) == nFf2Regs );
1475 Vec_IntFree( vSignature );
1476 // create box library
1477 pBoxLib = If_LibBoxStart();
1478 }
1479 //printf( "Init state: %s\n", p->pInits );
1480
1481 // blast in the topological order
1482 Wlc_NtkForEachObj( p, pObj, i )
1483 {
1484 //char * pName1 = Wlc_ObjName(p, i);
1485 //char * pName2 = Wlc_ObjFaninNum(pObj) ? Wlc_ObjName(p, Wlc_ObjFaninId0(pObj)) : NULL;
1486
1487 nAndPrev = Gia_ManAndNum(pNew);
1488 nRange = Wlc_ObjRange( pObj );
1489 nRange0 = Wlc_ObjFaninNum(pObj) > 0 ? Wlc_ObjRange( Wlc_ObjFanin0(p, pObj) ) : -1;
1490 nRange1 = Wlc_ObjFaninNum(pObj) > 1 ? Wlc_ObjRange( Wlc_ObjFanin1(p, pObj) ) : -1;
1491 nRange2 = Wlc_ObjFaninNum(pObj) > 2 ? Wlc_ObjRange( Wlc_ObjFanin2(p, pObj) ) : -1;
1492 nRange3 = Wlc_ObjFaninNum(pObj) > 3 ? Wlc_ObjRange( Wlc_ObjFanin(p, pObj, 3) ) : -1;
1493 pFans0 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL;
1494 pFans1 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL;
1495 pFans2 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL;
1496 pFans3 = pObj->Type != WLC_OBJ_FF && Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL;
1497 Vec_IntClear( vRes );
1498 assert( nRange > 0 );
1499 if ( pPar->vBoxIds && pObj->Mark )
1500 {
1501 If_Box_t * pBox;
1502 char Buffer[100];
1503 float * pTable;
1504 int CarryIn = 0;
1505
1506 pObj->Mark = 0;
1507 assert( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB );
1508
1509 // account for carry-in
1510 if ( Wlc_ObjFaninNum(pObj) == 3 )
1511 assert( nRange2 == 1 );
1512 else
1513 nRange2 = 0;
1514
1515 // create new box
1516 if ( vTables == NULL ) {
1517 Tim_ManSetDelayTables( pManTime, (vTables = Vec_PtrAlloc(100)) );
1518 Vec_PtrPush( vTables, NULL );
1519 }
1520 Tim_ManCreateBox( pManTime, curPo, nRange0 + nRange1 + nRange2, curPi, nRange, Vec_PtrSize(vTables), 0 );
1521 Tim_ManBoxSetCopy( pManTime, Tim_ManBoxNum(pManTime)-1, Tim_ManBoxNum(pManTime)-1 );
1522 curPi += nRange;
1523 curPo += nRange0 + nRange1 + nRange2;
1524
1525 // create delay table
1526 pTable = ABC_ALLOC( float, 3 + nRange * (nRange0 + nRange1 + nRange2) );
1527 pTable[0] = Vec_PtrSize(vTables);
1528 pTable[1] = nRange0 + nRange1 + nRange2;
1529 pTable[2] = nRange;
1530 for ( k = 0; k < nRange * (nRange0 + nRange1 + nRange2); k++ )
1531 pTable[3 + k] = 1.0;
1532 Vec_PtrPush( vTables, pTable );
1533
1534 // create combinational outputs in the normal manager
1535 for ( k = 0; k < nRange0; k++ )
1536 Gia_ManAppendCo( pNew, pFans0[k] );
1537 for ( k = 0; k < nRange1; k++ )
1538 Gia_ManAppendCo( pNew, pFans1[k] );
1539 for ( k = 0; k < nRange2; k++ )
1540 Gia_ManAppendCo( pNew, pFans2[0] );
1541
1542 // make sure there is enough primary inputs in the manager
1543 for ( k = Gia_ManPiNum(pExtra); k < nRange0 + nRange1 + nRange2; k++ )
1544 Gia_ManAppendCi( pExtra );
1545 // create combinational inputs
1546 Vec_IntClear( vTemp0 );
1547 for ( k = 0; k < nRange0; k++ )
1548 Vec_IntPush( vTemp0, Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, k)) );
1549 Vec_IntClear( vTemp1 );
1550 for ( k = 0; k < nRange1; k++ )
1551 Vec_IntPush( vTemp1, Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange0+k)) );
1552 if ( nRange2 == 1 )
1553 CarryIn = Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange0+nRange1));
1554
1555 // get new fanin arrays
1556 pFans0 = Vec_IntArray( vTemp0 );
1557 pFans1 = Vec_IntArray( vTemp1 );
1558
1559 // bit-blast in the external manager
1560 if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB )
1561 {
1562 int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
1563 int * pArg0 = Wlc_VecLoadFanins( vRes, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1564 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1565 if ( pObj->Type == WLC_OBJ_ARI_ADD )
1566 Wlc_BlastAdder( pExtra, pArg0, pArg1, nRange, CarryIn ); // result is in pFan0 (vRes)
1567 else
1568 Wlc_BlastSubtract( pExtra, pArg0, pArg1, nRange, 1 ); // result is in pFan0 (vRes)
1569 Vec_IntShrink( vRes, nRange );
1570 }
1571 else if ( fUseOldMultiplierBlasting )
1572 {
1573 int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
1574 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1575 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1576 Wlc_BlastMultiplier2( pExtra, pArg0, pArg1, nRange, vTemp2, vRes );
1577 Vec_IntShrink( vRes, nRange );
1578 }
1579 else
1580 {
1581 int fSigned = Wlc_ObjIsSignedFanin01(p, pObj);
1582 int nRangeMax = Abc_MaxInt(nRange0, nRange1);
1583 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, fSigned );
1584 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, fSigned );
1585 Wlc_BlastMultiplier( pExtra, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned );
1586 if ( nRange > nRangeMax + nRangeMax )
1587 Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 );
1588 else
1589 Vec_IntShrink( vRes, nRange );
1590 assert( Vec_IntSize(vRes) == nRange );
1591 }
1592 // create outputs in the external manager
1593 for ( k = 0; k < nRange; k++ )
1594 Gia_ManAppendCo( pExtra, Vec_IntEntry(vRes, k) );
1595
1596 // create combinational inputs in the normal manager
1597 Vec_IntClear( vRes );
1598 for ( k = 0; k < nRange; k++ )
1599 Vec_IntPush( vRes, Gia_ManAppendCi(pNew) );
1600
1601 // add box to the library
1602 sprintf( Buffer, "%s%03d", pObj->Type == WLC_OBJ_ARI_ADD ? "add":"mul", 1+If_LibBoxNum(pBoxLib) );
1603 pBox = If_BoxStart( Abc_UtilStrsav(Buffer), 1+If_LibBoxNum(pBoxLib), nRange0 + nRange1 + nRange2, nRange, 0, 0, 0 );
1604 If_LibBoxAdd( pBoxLib, pBox );
1605 for ( k = 0; k < pBox->nPis * pBox->nPos; k++ )
1606 pBox->pDelays[k] = 1;
1607 }
1608 else if ( Wlc_ObjIsCi(pObj) || pObj->Type == WLC_OBJ_FF ) // assuming that FFs are ordered immediately after PIs
1609 {
1610 if ( pObj->Type == WLC_OBJ_FF )
1611 Vec_IntPush( vFf2Ci, Gia_ManCiNum(pNew) );
1612 if ( Wlc_ObjRangeIsReversed(pObj) )
1613 {
1614 for ( k = 0; k < nRange; k++ )
1615 Vec_IntPush( vRes, -1 );
1616 for ( k = 0; k < nRange; k++ )
1617 Vec_IntWriteEntry( vRes, Vec_IntSize(vRes)-1-k, Gia_ManAppendCi(pNew) );
1618 }
1619 else
1620 {
1621 for ( k = 0; k < nRange; k++ )
1622 Vec_IntPush( vRes, Gia_ManAppendCi(pNew) );
1623 }
1624 if ( pObj->Type == WLC_OBJ_FO )
1625 nFFouts += Vec_IntSize(vRes);
1626 if ( pObj->Type == WLC_OBJ_FF )
1627 {
1628 // complement flop output whose init state is 1
1629 }
1630 }
1631 else if ( pObj->Type == WLC_OBJ_BUF )
1632 {
1633 int nRangeMax = Abc_MaxInt( nRange0, nRange );
1634 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin0(p, pObj) );
1635 for ( k = 0; k < nRange; k++ )
1636 Vec_IntPush( vRes, pArg0[k] );
1637 }
1638 else if ( pObj->Type == WLC_OBJ_CONST )
1639 {
1640 word * pTruth = (word *)Wlc_ObjFanins(pObj);
1641 for ( k = 0; k < nRange; k++ )
1642 Vec_IntPush( vRes, Abc_TtGetBit(pTruth, k) );
1643 }
1644 else if ( pObj->Type == WLC_OBJ_MUX )
1645 {
1646 // It is strange and disturbing that Verilog standard treats these statements differently:
1647 // Statement 1:
1648 // assign o = i ? b : a;
1649 // Statement 2:
1650 // always @( i or a or b )
1651 // begin
1652 // case ( i )
1653 // 0 : o = a ;
1654 // 1 : o = b ;
1655 // endcase
1656 // end
1657 // If a is signed and b is unsigned, Statement 1 does not sign-extend a, while Statement 2 does.
1658 // The signedness of o does not matter.
1659 //
1660 // Below we (somewhat arbitrarily) distinguish these two by assuming that
1661 // Statement 1 has three fanins, while Statement 2 has more than three fanins.
1662 //
1663 int fSigned = 1;
1664 assert( nRange0 >= 1 && Wlc_ObjFaninNum(pObj) >= 3 );
1665 assert( 1 + (1 << nRange0) == Wlc_ObjFaninNum(pObj) );
1666 Wlc_ObjForEachFanin( pObj, iFanin, k )
1667 if ( k > 0 )
1668 fSigned &= Wlc_NtkObj(p, iFanin)->Signed;
1669 if ( pParIn->fBlastNew && nRange0 <= 16 )
1670 {
1671 char * pNums = Wlc_NtkMuxTreeString( nRange0 );
1672 Vec_Int_t ** pvDecs = Wlc_NtkMuxTree3DecsDerive( pNew, pFans0, nRange0, pNums );
1673 for ( b = 0; b < nRange; b++ )
1674 {
1675 Vec_IntClear( vTemp0 );
1676 Wlc_ObjForEachFanin( pObj, iFanin, k ) {
1677 if ( k > 0 )
1678 {
1679 nRange1 = Wlc_ObjRange( Wlc_NtkObj(p, iFanin) );
1680 pFans1 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, iFanin) );
1681 if ( Wlc_ObjFaninNum(pObj) == 3 ) // Statement 1
1682 Vec_IntPush( vTemp0, b < nRange1 ? pFans1[b] : (fSigned? pFans1[nRange1-1] : 0) );
1683 else // Statement 2
1684 Vec_IntPush( vTemp0, b < nRange1 ? pFans1[b] : (Wlc_NtkObj(p, iFanin)->Signed? pFans1[nRange1-1] : 0) );
1685 }
1686 }
1687 assert( (1 << nRange0) == Vec_IntSize(vTemp0) );
1688 Vec_IntPush( vRes, Wlc_NtkMuxTree3(pNew, vTemp0, pNums, pvDecs) );
1689 }
1690 Wlc_NtkMuxTree3DecsFree( pvDecs, pNums );
1691 }
1692 else
1693 {
1694 Vec_IntClear( vTemp1 );
1695 if ( pPar->fDecMuxes )
1696 {
1697 for ( k = 0; k < (1 << nRange0); k++ )
1698 {
1699 int iLitAnd = 1;
1700 for ( b = 0; b < nRange0; b++ )
1701 iLitAnd = Gia_ManHashAnd( pNew, iLitAnd, Abc_LitNotCond(pFans0[b], ((k >> b) & 1) == 0) );
1702 Vec_IntPush( vTemp1, iLitAnd );
1703 }
1704 }
1705 for ( b = 0; b < nRange; b++ )
1706 {
1707 Vec_IntClear( vTemp0 );
1708 Wlc_ObjForEachFanin( pObj, iFanin, k )
1709 if ( k > 0 )
1710 {
1711 nRange1 = Wlc_ObjRange( Wlc_NtkObj(p, iFanin) );
1712 pFans1 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, iFanin) );
1713 if ( Wlc_ObjFaninNum(pObj) == 3 ) // Statement 1
1714 Vec_IntPush( vTemp0, b < nRange1 ? pFans1[b] : (fSigned? pFans1[nRange1-1] : 0) );
1715 else // Statement 2
1716 Vec_IntPush( vTemp0, b < nRange1 ? pFans1[b] : (Wlc_NtkObj(p, iFanin)->Signed? pFans1[nRange1-1] : 0) );
1717 }
1718 if ( pPar->fDecMuxes )
1719 Vec_IntPush( vRes, Wlc_NtkMuxTree2(pNew, pFans0, nRange0, vTemp0, vTemp1, vTemp2) );
1720 else
1721 Vec_IntPush( vRes, Wlc_NtkMuxTree_rec(pNew, pFans0, nRange0, vTemp0, 0) );
1722 }
1723 }
1724 }
1725 else if ( pObj->Type == WLC_OBJ_SEL )
1726 {
1727 assert( nRange0 == Wlc_ObjFaninNum(pObj)-1 );
1728 Vec_IntClear( vTemp1 );
1729 for ( k = 0; k < nRange0; k++ )
1730 Vec_IntPush( vTemp1, pFans0[k] );
1731 for ( b = 0; b < nRange; b++ )
1732 {
1733 Vec_IntClear( vTemp0 );
1734 Wlc_ObjForEachFanin( pObj, iFanin, k )
1735 if ( k > 0 )
1736 {
1737 Wlc_Obj_t * pFanin = Wlc_NtkObj(p, iFanin);
1738 assert( nRange == Wlc_ObjRange(pFanin) );
1739 pFans1 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, iFanin) );
1740 Vec_IntPush( vTemp0, pFans1[b] );
1741 }
1742 Vec_IntPush( vRes, Wlc_NtkMuxTree2(pNew, NULL, 0, vTemp0, vTemp1, vTemp2) );
1743 }
1744 }
1745 else if ( pObj->Type == WLC_OBJ_SHIFT_R || pObj->Type == WLC_OBJ_SHIFT_RA ||
1746 pObj->Type == WLC_OBJ_SHIFT_L || pObj->Type == WLC_OBJ_SHIFT_LA )
1747 {
1748 int nRangeMax = Abc_MaxInt( nRange, nRange0 );
1749 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin0(p, pObj) );
1750 if ( pObj->Type == WLC_OBJ_SHIFT_R || pObj->Type == WLC_OBJ_SHIFT_RA )
1751 Wlc_BlastShiftRight( pNew, pArg0, nRangeMax, pFans1, nRange1, Wlc_ObjIsSignedFanin0(p, pObj) && pObj->Type == WLC_OBJ_SHIFT_RA, vRes );
1752 else
1753 Wlc_BlastShiftLeft( pNew, pArg0, nRangeMax, pFans1, nRange1, 0, vRes );
1754 Vec_IntShrink( vRes, nRange );
1755 }
1756 else if ( pObj->Type == WLC_OBJ_ROTATE_R )
1757 {
1758 assert( nRange0 == nRange );
1759 Wlc_BlastRotateRight( pNew, pFans0, nRange0, pFans1, nRange1, vRes );
1760 }
1761 else if ( pObj->Type == WLC_OBJ_ROTATE_L )
1762 {
1763 assert( nRange0 == nRange );
1764 Wlc_BlastRotateLeft( pNew, pFans0, nRange0, pFans1, nRange1, vRes );
1765 }
1766 else if ( pObj->Type == WLC_OBJ_BIT_NOT )
1767 {
1768 int nRangeMax = Abc_MaxInt( nRange, nRange0 );
1769 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin0(p, pObj) );
1770 for ( k = 0; k < nRange; k++ )
1771 Vec_IntPush( vRes, Abc_LitNot(pArg0[k]) );
1772 }
1773 else if ( pObj->Type == WLC_OBJ_BIT_AND || pObj->Type == WLC_OBJ_BIT_NAND )
1774 {
1775 int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
1776 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1777 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1778 for ( k = 0; k < nRange; k++ )
1779 Vec_IntPush( vRes, Abc_LitNotCond(Gia_ManHashAnd(pNew, pArg0[k], pArg1[k]), pObj->Type == WLC_OBJ_BIT_NAND) );
1780 }
1781 else if ( pObj->Type == WLC_OBJ_BIT_OR || pObj->Type == WLC_OBJ_BIT_NOR )
1782 {
1783 int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
1784 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1785 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1786 for ( k = 0; k < nRange; k++ )
1787 Vec_IntPush( vRes, Abc_LitNotCond(Gia_ManHashOr(pNew, pArg0[k], pArg1[k]), pObj->Type == WLC_OBJ_BIT_NOR) );
1788 }
1789 else if ( pObj->Type == WLC_OBJ_BIT_XOR || pObj->Type == WLC_OBJ_BIT_NXOR )
1790 {
1791 int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
1792 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1793 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1794 for ( k = 0; k < nRange; k++ )
1795 Vec_IntPush( vRes, Abc_LitNotCond(Gia_ManHashXor(pNew, pArg0[k], pArg1[k]), pObj->Type == WLC_OBJ_BIT_NXOR) );
1796 }
1797 else if ( pObj->Type == WLC_OBJ_BIT_SELECT )
1798 {
1799 Wlc_Obj_t * pFanin = Wlc_ObjFanin0(p, pObj);
1800 int End = Wlc_ObjRangeEnd(pObj);
1801 int Beg = Wlc_ObjRangeBeg(pObj);
1802 if ( End >= Beg )
1803 {
1804 assert( nRange == End - Beg + 1 );
1805 assert( pFanin->Beg <= Beg && End <= pFanin->End );
1806 for ( k = Beg; k <= End; k++ )
1807 Vec_IntPush( vRes, pFans0[k - pFanin->Beg] );
1808 }
1809 else
1810 {
1811 assert( nRange == Beg - End + 1 );
1812 assert( pFanin->End <= End && Beg <= pFanin->Beg );
1813 for ( k = End; k <= Beg; k++ )
1814 Vec_IntPush( vRes, pFans0[k - pFanin->End] );
1815 }
1816 }
1817 else if ( pObj->Type == WLC_OBJ_BIT_CONCAT )
1818 {
1819 int iFanin, nTotal = 0;
1820 Wlc_ObjForEachFanin( pObj, iFanin, k )
1821 nTotal += Wlc_ObjRange( Wlc_NtkObj(p, iFanin) );
1822 assert( nRange == nTotal );
1823 Wlc_ObjForEachFaninReverse( pObj, iFanin, k )
1824 {
1825 nRange0 = Wlc_ObjRange( Wlc_NtkObj(p, iFanin) );
1826 pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, iFanin) );
1827 for ( b = 0; b < nRange0; b++ )
1828 Vec_IntPush( vRes, pFans0[b] );
1829 }
1830 }
1831 else if ( pObj->Type == WLC_OBJ_BIT_ZEROPAD || pObj->Type == WLC_OBJ_BIT_SIGNEXT )
1832 {
1833 int Pad = pObj->Type == WLC_OBJ_BIT_ZEROPAD ? 0 : pFans0[nRange0-1];
1834 assert( nRange0 <= nRange );
1835 for ( k = 0; k < nRange0; k++ )
1836 Vec_IntPush( vRes, pFans0[k] );
1837 for ( ; k < nRange; k++ )
1838 Vec_IntPush( vRes, Pad );
1839 }
1840 else if ( pObj->Type == WLC_OBJ_LOGIC_NOT )
1841 {
1842 iLit = Wlc_BlastReduction( pNew, pFans0, nRange0, WLC_OBJ_REDUCT_OR );
1843 Vec_IntFill( vRes, 1, Abc_LitNot(iLit) );
1844 for ( k = 1; k < nRange; k++ )
1845 Vec_IntPush( vRes, 0 );
1846 }
1847 else if ( pObj->Type == WLC_OBJ_LOGIC_IMPL )
1848 {
1849 int iLit0 = Wlc_BlastReduction( pNew, pFans0, nRange0, WLC_OBJ_REDUCT_OR );
1850 int iLit1 = Wlc_BlastReduction( pNew, pFans1, nRange1, WLC_OBJ_REDUCT_OR );
1851 Vec_IntFill( vRes, 1, Gia_ManHashOr(pNew, Abc_LitNot(iLit0), iLit1) );
1852 for ( k = 1; k < nRange; k++ )
1853 Vec_IntPush( vRes, 0 );
1854 }
1855 else if ( pObj->Type == WLC_OBJ_LOGIC_AND )
1856 {
1857 int iLit0 = Wlc_BlastReduction( pNew, pFans0, nRange0, WLC_OBJ_REDUCT_OR );
1858 int iLit1 = Wlc_BlastReduction( pNew, pFans1, nRange1, WLC_OBJ_REDUCT_OR );
1859 Vec_IntFill( vRes, 1, Gia_ManHashAnd(pNew, iLit0, iLit1) );
1860 for ( k = 1; k < nRange; k++ )
1861 Vec_IntPush( vRes, 0 );
1862 }
1863 else if ( pObj->Type == WLC_OBJ_LOGIC_OR )
1864 {
1865 int iLit0 = Wlc_BlastReduction( pNew, pFans0, nRange0, WLC_OBJ_REDUCT_OR );
1866 int iLit1 = Wlc_BlastReduction( pNew, pFans1, nRange1, WLC_OBJ_REDUCT_OR );
1867 Vec_IntFill( vRes, 1, Gia_ManHashOr(pNew, iLit0, iLit1) );
1868 for ( k = 1; k < nRange; k++ )
1869 Vec_IntPush( vRes, 0 );
1870 }
1871 else if ( pObj->Type == WLC_OBJ_LOGIC_XOR )
1872 {
1873 int iLit0 = Wlc_BlastReduction( pNew, pFans0, nRange0, WLC_OBJ_REDUCT_OR );
1874 int iLit1 = Wlc_BlastReduction( pNew, pFans1, nRange1, WLC_OBJ_REDUCT_OR );
1875 Vec_IntFill( vRes, 1, Gia_ManHashXor(pNew, iLit0, iLit1) );
1876 for ( k = 1; k < nRange; k++ )
1877 Vec_IntPush( vRes, 0 );
1878 }
1879 else if ( pObj->Type == WLC_OBJ_COMP_NOTEQU && Wlc_ObjFaninNum(pObj) > 2 )
1880 {
1881 // find the max range
1882 int a, b, iRes = 1, nRangeMax = Abc_MaxInt( nRange0, nRange1 );
1883 for ( k = 2; k < Wlc_ObjFaninNum(pObj); k++ )
1884 nRangeMax = Abc_MaxInt( nRangeMax, Wlc_ObjRange( Wlc_NtkObj(p, Wlc_ObjFaninId(pObj, k)) ) );
1885 // create pairwise distinct
1886 for ( a = 0; a < Wlc_ObjFaninNum(pObj); a++ )
1887 for ( b = a+1; b < Wlc_ObjFaninNum(pObj); b++ )
1888 {
1889 int nRange0 = Wlc_ObjRange( Wlc_NtkObj(p, Wlc_ObjFaninId(pObj, a)) );
1890 int nRange1 = Wlc_ObjRange( Wlc_NtkObj(p, Wlc_ObjFaninId(pObj, b)) );
1891 int * pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj, a)) );
1892 int * pFans1 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj, b)) );
1893 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, 0 );
1894 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, 0 );
1895 int iLit = 0;
1896 for ( k = 0; k < nRangeMax; k++ )
1897 iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, pArg0[k], pArg1[k]) );
1898 iRes = Gia_ManHashAnd( pNew, iRes, iLit );
1899 }
1900 Vec_IntFill( vRes, 1, iRes );
1901 for ( k = 1; k < nRange; k++ )
1902 Vec_IntPush( vRes, 0 );
1903 }
1904 else if ( pObj->Type == WLC_OBJ_COMP_EQU || pObj->Type == WLC_OBJ_COMP_NOTEQU )
1905 {
1906 int iLit = 0, nRangeMax = Abc_MaxInt( nRange0, nRange1 );
1907 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1908 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1909 for ( k = 0; k < nRangeMax; k++ )
1910 iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, pArg0[k], pArg1[k]) );
1911 Vec_IntFill( vRes, 1, Abc_LitNotCond(iLit, pObj->Type == WLC_OBJ_COMP_EQU) );
1912 for ( k = 1; k < nRange; k++ )
1913 Vec_IntPush( vRes, 0 );
1914 }
1915 else if ( pObj->Type == WLC_OBJ_COMP_LESS || pObj->Type == WLC_OBJ_COMP_MOREEQU ||
1916 pObj->Type == WLC_OBJ_COMP_MORE || pObj->Type == WLC_OBJ_COMP_LESSEQU )
1917 {
1918 int nRangeMax = Abc_MaxInt( nRange0, nRange1 );
1919 int fSigned = Wlc_ObjIsSignedFanin01(p, pObj);
1920 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, fSigned );
1921 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, fSigned );
1922 int fSwap = (pObj->Type == WLC_OBJ_COMP_MORE || pObj->Type == WLC_OBJ_COMP_LESSEQU);
1923 int fCompl = (pObj->Type == WLC_OBJ_COMP_MOREEQU || pObj->Type == WLC_OBJ_COMP_LESSEQU);
1924 if ( fSwap ) ABC_SWAP( int *, pArg0, pArg1 );
1925 if ( fSigned )
1926 iLit = pParIn->fBlastNew ? Wlc_BlastLessSigned3( pNew, pArg0, pArg1, nRangeMax ) : Wlc_BlastLessSigned( pNew, pArg0, pArg1, nRangeMax );
1927 else
1928 iLit = pParIn->fBlastNew ? Wlc_BlastLess3( pNew, pArg0, pArg1, nRangeMax ) : Wlc_BlastLess( pNew, pArg0, pArg1, nRangeMax );
1929 iLit = Abc_LitNotCond( iLit, fCompl );
1930 Vec_IntFill( vRes, 1, iLit );
1931 for ( k = 1; k < nRange; k++ )
1932 Vec_IntPush( vRes, 0 );
1933 }
1934 else if ( pObj->Type == WLC_OBJ_REDUCT_AND || pObj->Type == WLC_OBJ_REDUCT_OR || pObj->Type == WLC_OBJ_REDUCT_XOR ||
1935 pObj->Type == WLC_OBJ_REDUCT_NAND || pObj->Type == WLC_OBJ_REDUCT_NOR || pObj->Type == WLC_OBJ_REDUCT_NXOR )
1936 {
1937 Vec_IntPush( vRes, Wlc_BlastReduction( pNew, pFans0, nRange0, pObj->Type ) );
1938 for ( k = 1; k < nRange; k++ )
1939 Vec_IntPush( vRes, 0 );
1940 }
1941 else if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB )
1942 {
1943 int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
1944 int * pArg0 = Wlc_VecLoadFanins( vRes, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1945 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1946 int CarryIn = Wlc_ObjFaninNum(pObj) == 3 ? pFans2[0] : 0;
1947 if ( pObj->Type == WLC_OBJ_ARI_ADD )
1948 {
1949 if ( pPar->fCla )
1950 Wlc_BlastAdderCLA( pNew, pArg0, pArg1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj), CarryIn ); // result is in pFan0 (vRes)
1951 //Wlc_BlastAdderFast( pNew, pArg0, pArg1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj), CarryIn ); // result is in pFan0 (vRes)
1952 else
1953 Wlc_BlastAdder( pNew, pArg0, pArg1, nRangeMax, CarryIn ); // result is in pFan0 (vRes)
1954 }
1955 else
1956 Wlc_BlastSubtract( pNew, pArg0, pArg1, nRange, 1 ); // result is in pFan0 (vRes)
1957 Vec_IntShrink( vRes, nRange );
1958 }
1959 else if ( pObj->Type == WLC_OBJ_ARI_ADDSUB )
1960 {
1961 int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange2, nRange3) );
1962 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans2, nRange2, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1963 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans2, nRange2, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1964 int * pArg2 = Wlc_VecLoadFanins( vTemp2, pFans3, nRange3, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1965 int ModeIn = pFans0[0];
1966 int CarryIn = pFans1[0]; int j;
1967 Wlc_BlastAdder ( pNew, pArg0, pArg2, nRangeMax, CarryIn ); // result is in pArg0 (vTemp0)
1968 Wlc_BlastSubtract( pNew, pArg1, pArg2, nRangeMax, Abc_LitNot(CarryIn) ); // result is in pArg1 (vTemp1)
1969 Vec_IntClear( vRes );
1970 for ( j = 0; j < nRange; j++ )
1971 Vec_IntPush( vRes, Gia_ManHashMux(pNew, ModeIn, pArg0[j], pArg1[j]) );
1972 }
1973 else if ( pObj->Type == WLC_OBJ_ARI_MULTI )
1974 {
1975 if ( fUseOldMultiplierBlasting )
1976 {
1977 int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
1978 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1979 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjIsSignedFanin01(p, pObj) );
1980 Wlc_BlastMultiplier2( pNew, pArg0, pArg1, nRange, vTemp2, vRes );
1981 Vec_IntShrink( vRes, nRange );
1982 }
1983 else
1984 {
1985 int fSigned = Wlc_ObjIsSignedFanin01(p, pObj);
1986 int nRangeMax = Abc_MaxInt(nRange0, nRange1);
1987 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, fSigned );
1988 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, fSigned );
1989 if ( nRange0 == nRange1 && Wlc_NtkCountConstBits(pArg0, nRangeMax) < Wlc_NtkCountConstBits(pArg1, nRangeMax) )
1990 ABC_SWAP( int *, pArg0, pArg1 );
1991 if ( pPar->fBooth )
1992 Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned, pPar->fCla, NULL, pParIn->fVerbose );
1993 else if ( pPar->fCla )
1994 Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla, NULL, pParIn->fVerbose );
1995 else
1996 Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned );
1997 //Wlc_BlastMultiplierC( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned );
1998 if ( nRange > Vec_IntSize(vRes) )
1999 Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 );
2000 else
2001 Vec_IntShrink( vRes, nRange );
2002 assert( Vec_IntSize(vRes) == nRange );
2003 }
2004 }
2005 else if ( pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
2006 {
2007 int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) );
2008 int fSigned = Wlc_ObjIsSignedFanin01(p, pObj);
2009 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, fSigned );
2010 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, fSigned );
2011 if ( fSigned )
2012 Wlc_BlastDividerSigned( pNew, pArg0, nRangeMax, pArg1, nRangeMax, pObj->Type == WLC_OBJ_ARI_DIVIDE, vRes, pPar->fNonRest );
2013 else
2014 Wlc_BlastDividerTop( pNew, pArg0, nRangeMax, pArg1, nRangeMax, pObj->Type == WLC_OBJ_ARI_DIVIDE, vRes, pPar->fNonRest );
2015 Vec_IntShrink( vRes, nRange );
2016 if ( !pPar->fDivBy0 )
2017 Wlc_BlastZeroCondition( pNew, pFans1, nRange1, vRes );
2018 }
2019 else if ( pObj->Type == WLC_OBJ_ARI_MINUS )
2020 {
2021 int nRangeMax = Abc_MaxInt( nRange0, nRange );
2022 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin0(p, pObj) );
2023 Wlc_BlastMinus( pNew, pArg0, nRangeMax, vRes );
2024 Vec_IntShrink( vRes, nRange );
2025 }
2026 else if ( pObj->Type == WLC_OBJ_ARI_POWER )
2027 {
2028 int nRangeMax = Abc_MaxInt(nRange0, nRange);
2029 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjIsSignedFanin0(p, pObj) );
2030 int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRange1, Wlc_ObjIsSignedFanin1(p, pObj) );
2031 Wlc_BlastPower( pNew, pArg0, nRangeMax, pArg1, nRange1, vTemp2, vRes );
2032 Vec_IntShrink( vRes, nRange );
2033 }
2034 else if ( pObj->Type == WLC_OBJ_ARI_SQRT )
2035 {
2036 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange0 + (nRange0 & 1), 0 );
2037 nRange0 += (nRange0 & 1);
2038 if ( pPar->fNonRest )
2039 Wlc_BlastSqrtNR( pNew, pArg0, nRange0, vTemp2, vRes );
2040 else
2041 Wlc_BlastSqrt( pNew, pArg0, nRange0, vTemp2, vRes );
2042 if ( nRange > Vec_IntSize(vRes) )
2043 Vec_IntFillExtra( vRes, nRange, 0 );
2044 else
2045 Vec_IntShrink( vRes, nRange );
2046 }
2047 else if ( pObj->Type == WLC_OBJ_ARI_SQUARE )
2048 {
2049 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange0, 0 );
2050 Wlc_BlastSquare( pNew, pArg0, nRange0, vTemp2, vRes );
2051 if ( nRange > Vec_IntSize(vRes) )
2052 Vec_IntFillExtra( vRes, nRange, 0 );
2053 else
2054 Vec_IntShrink( vRes, nRange );
2055 }
2056 else if ( pObj->Type == WLC_OBJ_DEC )
2057 {
2058 int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange0, 0 );
2059 if ( pParIn->fBlastNew )
2060 Wlc_BlastDecoder2( pNew, pArg0, nRange0, vTemp2, vRes );
2061 else
2062 Wlc_BlastDecoder( pNew, pArg0, nRange0, vTemp2, vRes );
2063 if ( nRange > Vec_IntSize(vRes) )
2064 Vec_IntFillExtra( vRes, nRange, 0 );
2065 else
2066 Vec_IntShrink( vRes, nRange );
2067 }
2068 else if ( pObj->Type == WLC_OBJ_TABLE )
2069 Wlc_BlastTable( pNew, Wlc_ObjTable(p, pObj), pFans0, nRange0, nRange, vRes );
2070 else if ( pObj->Type == WLC_OBJ_LUT && p->vLutTruths )
2071 Wlc_BlastLut( pNew, Vec_WrdEntry(p->vLutTruths, Wlc_ObjId(p, pObj)), pFans0, nRange0, nRange, vRes );
2072 else assert( 0 );
2073 assert( Vec_IntSize(vBits) == Wlc_ObjCopy(p, i) );
2074 Vec_IntAppend( vBits, vRes );
2075 if ( vAddOutputs && !Wlc_ObjIsCo(pObj) &&
2076 (
2077 (pObj->Type >= WLC_OBJ_MUX && pObj->Type <= WLC_OBJ_ROTATE_L) ||
2078 (pObj->Type >= WLC_OBJ_COMP_EQU && pObj->Type <= WLC_OBJ_COMP_MOREEQU) ||
2079 (pObj->Type >= WLC_OBJ_ARI_ADD && pObj->Type <= WLC_OBJ_ARI_SQUARE)
2080 )
2081 )
2082 {
2083 Vec_IntAppend( vAddOutputs, vRes );
2084 Vec_IntPush( vAddObjs, Wlc_ObjId(p, pObj) );
2085 }
2086 p->nAnds[pObj->Type] += Gia_ManAndNum(pNew) - nAndPrev;
2087 }
2088 p->nAnds[0] = Gia_ManAndNum(pNew);
2089 assert( nBits == Vec_IntSize(vBits) );
2090 Vec_IntFree( vTemp0 );
2091 Vec_IntFree( vTemp1 );
2092 Vec_IntFree( vTemp2 );
2093 Vec_IntFree( vRes );
2094 // create flop boxes
2095 Wlc_NtkForEachFf2( p, pObj, i )
2096 {
2097 If_Box_t * pBox;
2098 char Buffer[100];
2099 float * pTable;
2100 Vec_Int_t * vTemp0 = Vec_IntAlloc( 100 );
2101 Vec_Int_t * vTemp1 = Vec_IntAlloc( 100 );
2102 int iLit, nRange = Wlc_ObjRange(pObj);
2103 int * pFans0, * pFans1, * pFans2, * pFans3;
2104 int iReset, iSet, iEnable;
2105 int nRangeIn = 2*nRange + 3; // D, reset, set, enable, Q
2106 int iSre = Wlc_ObjFaninId(pObj, 6);
2107
2108 assert( pObj->Type == WLC_OBJ_FF );
2109
2110 // create new box
2111 if ( vTables == NULL ) {
2112 Tim_ManSetDelayTables( pManTime, (vTables = Vec_PtrAlloc(100)) );
2113 Vec_PtrPush( vTables, NULL );
2114 }
2115 Tim_ManCreateBox( pManTime, curPo, nRangeIn, curPi, nRange, Vec_PtrSize(vTables), 0 );
2116 curPi += nRange;
2117 curPo += nRangeIn;
2118
2119 // create delay table
2120 pTable = ABC_ALLOC( float, 3 + nRange * nRangeIn );
2121 pTable[0] = Vec_PtrSize(vTables);
2122 pTable[1] = nRangeIn;
2123 pTable[2] = nRange;
2124 for ( k = 0; k < nRange * nRangeIn; k++ )
2125 pTable[3 + k] = 1.0;
2126 Vec_PtrPush( vTables, pTable );
2127
2128 // create combinational outputs in the normal manager
2129 pFans0 = Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL;
2130 pFans1 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,2)) ) : NULL; // reset
2131 pFans2 = Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL; // set
2132 pFans3 = Wlc_ObjFaninNum(pObj) > 4 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,4)) ) : NULL; // enable
2133 for ( k = 0; k < nRange; k++ )
2134 Gia_ManAppendCo( pNew, pFans0[k] );
2135 Gia_ManAppendCo( pNew, pFans1[0] );
2136 Gia_ManAppendCo( pNew, pFans2[0] );
2137 Gia_ManAppendCo( pNew, pFans3[0] );
2138 for ( k = 0; k < nRange; k++ )
2139 Gia_ManAppendCo( pNew, Gia_Obj2Lit(pNew, Gia_ManCi(pNew, Vec_IntEntry(vFf2Ci, i)+k)) );
2140
2141 // make sure there is enough primary inputs in the manager
2142 for ( k = Gia_ManPiNum(pExtra); k < nRangeIn; k++ )
2143 Gia_ManAppendCi( pExtra );
2144 // create combinational inputs
2145 for ( k = 0; k < nRange; k++ )
2146 Vec_IntPush( vTemp0, Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, k)) );
2147 iReset = Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange+0));
2148 iSet = Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange+1));
2149 iEnable = Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRange+2));
2150 for ( k = 0; k < nRange; k++ )
2151 Vec_IntPush( vTemp1, Gia_Obj2Lit(pExtra, Gia_ManPi(pExtra, nRangeIn-nRange+k)) );
2152
2153 // bit-blast in the external manager
2154 for ( k = 0; k < nRange; k++ )
2155 {
2156 // enable
2157 //iLitFlop = Gia_LitNotCond( Gia_ObjCopy(pObj), Gia_FlopIsOne(pObj) );
2158 //iLit = Gia_ManHashMux( Gia_ObjGia(pObj), Gia_FlopEnableCopy(pObj), iLit, iLitFlop );
2159 iLit = Gia_ManHashMux( pExtra, iEnable, Vec_IntEntry(vTemp0, k), Vec_IntEntry(vTemp1, k) );
2160 if ( iSre )
2161 {
2162 // reset
2163 //iLit = Gia_ManHashAnd( Gia_ObjGia(pObj), iLit, Gia_LitNot(Gia_FlopResetCopy(pObj)) );
2164 iLit = Gia_ManHashAnd( pExtra, iLit, Abc_LitNot(iReset) );
2165 // set
2166 //iLit = Gia_ManHashOr( Gia_ObjGia(pObj), iLit, Gia_FlopSetCopy(pObj) );
2167 iLit = Gia_ManHashOr( pExtra, iLit, iSet );
2168 }
2169 else
2170 {
2171 // set
2172 //iLit = Gia_ManHashOr( Gia_ObjGia(pObj), iLit, Gia_FlopSetCopy(pObj) );
2173 iLit = Gia_ManHashOr( pExtra, iLit, iSet );
2174 // reset
2175 //iLit = Gia_ManHashAnd( Gia_ObjGia(pObj), iLit, Gia_LitNot(Gia_FlopResetCopy(pObj)) );
2176 iLit = Gia_ManHashAnd( pExtra, iLit, Abc_LitNot(iReset) );
2177 }
2178 // create outputs in the external manager
2179 Gia_ManAppendCo( pExtra, iLit );
2180 }
2181
2182 // add box to the library
2183 sprintf( Buffer, "%s%03d", "ff_comb", 1+If_LibBoxNum(pBoxLib) );
2184 pBox = If_BoxStart( Abc_UtilStrsav(Buffer), 1+If_LibBoxNum(pBoxLib), nRangeIn, nRange, 0, 0, 0 );
2185 If_LibBoxAdd( pBoxLib, pBox );
2186 for ( k = 0; k < pBox->nPis * pBox->nPos; k++ )
2187 pBox->pDelays[k] = 1;
2188 Vec_IntFree( vTemp0 );
2189 Vec_IntFree( vTemp1 );
2190 }
2191 Vec_IntFree( vFf2Ci );
2192 // create COs
2193 if ( pPar->fCreateMiter || pPar->fCreateWordMiter )
2194 {
2195 int nPairs = 0, nBits = 0;
2196 Vec_Int_t * vOuts = Vec_IntAlloc( 100 );
2197 assert( Wlc_NtkPoNum(p) % 2 == 0 );
2198 Wlc_NtkForEachCo( p, pObj, i )
2199 {
2200 if ( pObj->fIsFi )
2201 {
2202 nRange = Wlc_ObjRange( pObj );
2203 pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)) );
2204 if ( Wlc_ObjRangeIsReversed(pObj) )
2205 {
2206 for ( k = 0; k < nRange; k++ )
2207 Gia_ManAppendCo( pNew, pFans0[nRange-1-k] );
2208 }
2209 else
2210 {
2211 for ( k = 0; k < nRange; k++ )
2212 Gia_ManAppendCo( pNew, pFans0[k] );
2213 }
2214 nFFins += nRange;
2215 continue;
2216 }
2217 pObj2 = Wlc_NtkCo( p, ++i );
2218 nRange1 = Wlc_ObjRange( pObj );
2219 nRange2 = Wlc_ObjRange( pObj2 );
2220 assert( nRange1 == nRange2 );
2221 pFans1 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)) );
2222 pFans2 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj2)) );
2223 if ( pPar->fCreateWordMiter )
2224 {
2225 Vec_IntClear( vOuts );
2226 if ( Wlc_ObjRangeIsReversed(pObj) )
2227 {
2228 for ( k = 0; k < nRange1; k++ )
2229 Vec_IntPushTwo( vOuts, pFans1[nRange1-1-k], pFans2[nRange2-1-k] );
2230 }
2231 else
2232 {
2233 for ( k = 0; k < nRange1; k++ )
2234 Vec_IntPushTwo( vOuts, pFans1[k], pFans2[k] );
2235 }
2236 Gia_ManAppendCo( pNew, Gia_ManHashDualMiter(pNew, vOuts) );
2237 }
2238 else
2239 {
2240 if ( Wlc_ObjRangeIsReversed(pObj) )
2241 {
2242 for ( k = 0; k < nRange1; k++ )
2243 {
2244 Gia_ManAppendCo( pNew, pFans1[nRange1-1-k] );
2245 Gia_ManAppendCo( pNew, pFans2[nRange2-1-k] );
2246 }
2247 }
2248 else
2249 {
2250 for ( k = 0; k < nRange1; k++ )
2251 {
2252 Gia_ManAppendCo( pNew, pFans1[k] );
2253 Gia_ManAppendCo( pNew, pFans2[k] );
2254 }
2255 }
2256 }
2257 nPairs++;
2258 nBits += nRange1;
2259 }
2260 Vec_IntFree( vOuts );
2261 if ( pPar->fCreateWordMiter )
2262 printf( "Derived an ordinary miter with %d bit-level outputs, one for each pair of word-level outputs.\n", nPairs );
2263 else
2264 printf( "Derived a dual-output miter with %d pairs of bits belonging to %d pairs of word-level outputs.\n", nBits, nPairs );
2265 }
2266 else
2267 {
2268 Wlc_NtkForEachCo( p, pObj, i )
2269 {
2270 // skip all outputs except the given ones
2271 if ( pPar->iOutput >= 0 && (i < pPar->iOutput || i >= pPar->iOutput + pPar->nOutputRange) )
2272 continue;
2273 // create additional PO literals
2274 if ( vAddOutputs && pObj->fIsFi )
2275 {
2276 Vec_IntForEachEntry( vAddOutputs, iLit, k )
2277 Gia_ManAppendCo( pNew, iLit );
2278 printf( "Created %d additional POs for %d interesting internal word-level variables.\n", Vec_IntSize(vAddOutputs), Vec_IntSize(vAddObjs) );
2279 Vec_IntFreeP( &vAddOutputs );
2280 }
2281 nRange = Wlc_ObjRange( pObj );
2282 pFans0 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjId(p, pObj)) );
2283 if ( fVerbose )
2284 printf( "%s(%d) ", Wlc_ObjName(p, Wlc_ObjId(p, pObj)), Gia_ManCoNum(pNew) );
2285 if ( Wlc_ObjRangeIsReversed(pObj) )
2286 {
2287 for ( k = 0; k < nRange; k++ )
2288 Gia_ManAppendCo( pNew, pFans0[nRange-1-k] );
2289 }
2290 else
2291 {
2292 for ( k = 0; k < nRange; k++ )
2293 Gia_ManAppendCo( pNew, pFans0[k] );
2294 }
2295 if ( pObj->fIsFi )
2296 nFFins += nRange;
2297 }
2298 if ( fVerbose )
2299 printf( "\n" );
2300 }
2301 //Vec_IntErase( vBits );
2302 //Vec_IntErase( &p->vCopies );
2303 // set the number of registers
2304 if ( Vec_IntSize(&p->vFfs2) > 0 )
2305 {
2306 assert( nFFins == 0 && nFFouts == 0 );
2307 // complement flop inputs whose init state is 1
2308 for ( i = 0; i < nFf2Regs; i++ )
2309 Gia_ManAppendCo( pNew, Gia_ManAppendCi(pNew) );
2310 Gia_ManSetRegNum( pNew, nFf2Regs );
2311 }
2312 else
2313 {
2314 assert( nFFins == nFFouts );
2315 Gia_ManSetRegNum( pNew, nFFins );
2316 }
2317 // finalize AIG
2318 if ( !pPar->fGiaSimple && !pPar->fNoCleanup )
2319 {
2320 pNew = Gia_ManCleanup( pTemp = pNew );
2321 Gia_ManDupRemapLiterals( vBits, pTemp );
2322 //printf( "Cutoff ID %d became %d.\n", 75, Abc_Lit2Var(Gia_ManObj(pTemp, 73)->Value) );
2323 Gia_ManStop( pTemp );
2324 }
2325 // transform AIG with init state
2326 if ( p->pInits )
2327 {
2328 if ( (int)strlen(p->pInits) != Gia_ManRegNum(pNew) )
2329 {
2330 printf( "The number of init values (%d) does not match the number of flops (%d).\n", (int)strlen(p->pInits), Gia_ManRegNum(pNew) );
2331 printf( "It is assumed that the AIG has constant 0 initial state.\n" );
2332 }
2333 else
2334 {
2335 pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, pPar->fSaveFfNames ? 1+Gia_ManRegNum(pNew) : 0, pPar->fGiaSimple, pPar->fVerbose );
2336 Gia_ManDupRemapLiterals( vBits, pTemp );
2337 Gia_ManStop( pTemp );
2338 }
2339 }
2340 // finalize AIG with boxes
2341 if ( Vec_IntSize(&p->vFfs2) > 0 )
2342 {
2343 curPo += nBitCos + nFf2Regs;
2344 assert( curPi == Tim_ManCiNum(pManTime) );
2345 assert( curPo == Tim_ManCoNum(pManTime) );
2346 // finalize the extra AIG
2347 pExtra = Gia_ManCleanup( pTemp = pExtra );
2348 Gia_ManStop( pTemp );
2349 assert( Gia_ManPoNum(pExtra) == Gia_ManCiNum(pNew) - nBitCis - nFf2Regs );
2350 // attach
2351 pNew->pAigExtra = pExtra;
2352 pNew->pManTime = pManTime;
2353 // normalize AIG
2354 pNew = Gia_ManDupNormalize( pTemp = pNew, 0 );
2355 Gia_ManTransferTiming( pNew, pTemp );
2356 Gia_ManStop( pTemp );
2357 //Tim_ManPrint( pManTime );
2358 }
2359 if ( pPar->vBoxIds )
2360 {
2361 curPo += nBitCos;
2362 assert( curPi == Tim_ManCiNum(pManTime) );
2363 assert( curPo == Tim_ManCoNum(pManTime) );
2364 // finalize the extra AIG
2365 pExtra = Gia_ManCleanup( pTemp = pExtra );
2366 Gia_ManStop( pTemp );
2367 assert( Gia_ManPoNum(pExtra) == Gia_ManCiNum(pNew) - nBitCis - nFf2Regs );
2368 // attach
2369 pNew->pAigExtra = pExtra;
2370 pNew->pManTime = pManTime;
2371 // normalize AIG
2372 pNew = Gia_ManDupNormalize( pTemp = pNew, 0 );
2373 Gia_ManTransferTiming( pNew, pTemp );
2374 Gia_ManStop( pTemp );
2375 //Tim_ManPrint( pManTime );
2376 }
2377 // create input names
2378 pNew->vNamesIn = Vec_PtrAlloc( Gia_ManCiNum(pNew) );
2379 Wlc_NtkForEachCi( p, pObj, i )
2380 if ( Wlc_ObjIsPi(pObj) )
2381 {
2382 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2383 nRange = Wlc_ObjRange( pObj );
2384 if ( fSkipBitRange && nRange == 1 )
2385 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
2386 else
2387 for ( k = 0; k < nRange; k++ )
2388 {
2389 char Buffer[1000];
2390 sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2391 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
2392 //printf( "Writing %s\n", Buffer );
2393 }
2394 }
2395 if ( p->pInits )
2396 {
2397 int Length = strlen(p->pInits);
2398 for ( i = 0; i < Length; i++ )
2399 if ( p->pInits[i] == 'x' || p->pInits[i] == 'X' )
2400 {
2401 char Buffer[100];
2402 sprintf( Buffer, "_%s_abc_%d_", "init", i );
2403 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
2404 fAdded = 1;
2405 }
2406 if ( pPar->fSaveFfNames )
2407 for ( i = 0; i < 1+Length; i++ )
2408 Vec_PtrPush( pNew->vNamesIn, NULL );
2409 }
2410 Wlc_NtkForEachCi( p, pObj, i )
2411 if ( !Wlc_ObjIsPi(pObj) )
2412 {
2413 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2414 nRange = Wlc_ObjRange( pObj );
2415 if ( fSkipBitRange && nRange == 1 )
2416 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
2417 else
2418 for ( k = 0; k < nRange; k++ )
2419 {
2420 char Buffer[1000];
2421 sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2422 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
2423 }
2424 }
2425 Wlc_NtkForEachFf2( p, pObj, i )
2426 {
2427 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2428 nRange = Wlc_ObjRange( pObj );
2429 if ( fSkipBitRange && nRange == 1 )
2430 {
2431 char Buffer[1000];
2432 sprintf( Buffer, "%s_fo", pName );
2433 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
2434 }
2435 else
2436 for ( k = 0; k < nRange; k++ )
2437 {
2438 char Buffer[1000];
2439 sprintf( Buffer, "%s_fo[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2440 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
2441 }
2442 }
2443 Wlc_NtkForEachFf2( p, pObj, i )
2444 {
2445 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2446 nRange = Wlc_ObjRange( pObj );
2447 if ( fSkipBitRange && nRange == 1 )
2448 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
2449 else
2450 for ( k = 0; k < nRange; k++ )
2451 {
2452 char Buffer[1000];
2453 sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2454 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
2455 }
2456 }
2457 if ( p->pInits && pPar->fSaveFfNames )
2458 {
2459 char * pName;
2460 int Length = (int)strlen(p->pInits);
2461 int NameStart = Vec_PtrSize(pNew->vNamesIn)-Length;
2462 int NullStart = Vec_PtrSize(pNew->vNamesIn)-2*Length;
2463 int SepStart = Vec_PtrSize(pNew->vNamesIn)-2*Length-1;
2464 assert( Vec_PtrEntry(pNew->vNamesIn, SepStart) == NULL );
2465 Vec_PtrWriteEntry( pNew->vNamesIn, SepStart, Abc_UtilStrsav("_abc_190121_abc_") );
2466 for ( i = 0; i < Length; i++ )
2467 {
2468 char Buffer[100];
2469 sprintf( Buffer, "%c%s", p->pInits[i], (char *)Vec_PtrEntry(pNew->vNamesIn, NameStart+i) );
2470 assert( Vec_PtrEntry(pNew->vNamesIn, NullStart+i) == NULL );
2471 Vec_PtrWriteEntry( pNew->vNamesIn, NullStart+i, Abc_UtilStrsav(Buffer) );
2472 }
2473 Vec_PtrForEachEntry( char *, pNew->vNamesIn, pName, i )
2474 assert( pName != NULL );
2475 }
2476 if ( p->pInits && fAdded )
2477 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav("abc_reset_flop") );
2478 if ( pPar->vBoxIds )
2479 {
2480 Wlc_NtkForEachObjVec( pPar->vBoxIds, p, pObj, i )
2481 {
2482 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2483 nRange = Wlc_ObjRange( pObj );
2484 assert( nRange > 1 );
2485 for ( k = 0; k < nRange; k++ )
2486 {
2487 char Buffer[1000];
2488 sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2489 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
2490 }
2491 }
2492 }
2493 assert( Vec_PtrSize(pNew->vNamesIn) == Gia_ManCiNum(pNew) );
2494 // create output names
2495 pNew->vNamesOut = Vec_PtrAlloc( Gia_ManCoNum(pNew) );
2496 Wlc_NtkForEachFf2( p, pObj, i )
2497 {
2498 int iFanin;
2499 Wlc_ObjForEachFanin( pObj, iFanin, b )
2500 {
2501 char * pName = Wlc_ObjName(p, iFanin);
2502 nRange = Wlc_ObjRange( Wlc_NtkObj(p, iFanin) );
2503 if ( fSkipBitRange && nRange == 1 )
2504 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
2505 else
2506 for ( k = 0; k < nRange; k++ )
2507 {
2508 char Buffer[1000];
2509 Wlc_Obj_t * pFanin = Wlc_NtkObj(p, iFanin);
2510 sprintf( Buffer, "%s[%d]", pName, pFanin->Beg < pFanin->End ? pFanin->Beg+k : pFanin->Beg-k );
2511 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2512 }
2513 if ( b == 3 )
2514 break;
2515 }
2516 {
2517 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2518 nRange = Wlc_ObjRange( pObj );
2519 if ( fSkipBitRange && nRange == 1 )
2520 {
2521 char Buffer[1000];
2522 sprintf( Buffer, "%s_in", pName );
2523 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2524 }
2525 else
2526 for ( k = 0; k < nRange; k++ )
2527 {
2528 char Buffer[1000];
2529 sprintf( Buffer, "%s_in[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2530 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2531 }
2532 }
2533 }
2534 if ( pPar->vBoxIds )
2535 {
2536 Wlc_NtkForEachObjVec( pPar->vBoxIds, p, pObj, i )
2537 {
2538 int iFanin, f;
2539 Wlc_ObjForEachFanin( pObj, iFanin, f )
2540 {
2541 char * pName = Wlc_ObjName(p, iFanin);
2542 nRange = Wlc_ObjRange( Wlc_NtkObj(p, iFanin) );
2543 assert( nRange >= 1 );
2544 for ( k = 0; k < nRange; k++ )
2545 {
2546 char Buffer[1000];
2547 Wlc_Obj_t * pFanin = Wlc_NtkObj(p, iFanin);
2548 sprintf( Buffer, "%s[%d]", pName, pFanin->Beg < pFanin->End ? pFanin->Beg+k : pFanin->Beg-k );
2549 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2550 }
2551 }
2552 }
2553 }
2554 // add real primary outputs
2555 Wlc_NtkForEachCo( p, pObj, i )
2556 if ( Wlc_ObjIsPo(pObj) )
2557 {
2558 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2559 nRange = Wlc_ObjRange( pObj );
2560 if ( pPar->fCreateWordMiter )
2561 {
2562 Wlc_Obj_t * pObj2 = Wlc_NtkCo( p, ++i );
2563 char * pName2 = Wlc_ObjName(p, Wlc_ObjId(p, pObj2));
2564 char Buffer[1000];
2565 sprintf( Buffer, "%s_xor_%s", pName, pName2 );
2566 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2567 //printf( "Adding output %s\n", Buffer );
2568 }
2569 else if ( pPar->fCreateMiter && nRange > 1 )
2570 {
2571 Wlc_Obj_t * pObj2 = Wlc_NtkCo( p, ++i );
2572 char * pName2 = Wlc_ObjName(p, Wlc_ObjId(p, pObj2));
2573 int nRange1 = Wlc_ObjRange( pObj );
2574 assert( nRange == nRange1 );
2575 for ( k = 0; k < nRange; k++ )
2576 {
2577 char Buffer[1000];
2578 sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2579 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2580 sprintf( Buffer, "%s[%d]", pName2, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2581 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2582 }
2583 }
2584 else
2585 {
2586 if ( fSkipBitRange && nRange == 1 )
2587 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
2588 else
2589 for ( k = 0; k < nRange; k++ )
2590 {
2591 char Buffer[1000];
2592 sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2593 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2594 }
2595 }
2596 }
2597 if ( vAddObjs )
2598 {
2599 // add internal primary outputs
2600 Wlc_NtkForEachObjVec( vAddObjs, p, pObj, i )
2601 {
2602 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2603 nRange = Wlc_ObjRange( pObj );
2604 if ( fSkipBitRange && nRange == 1 )
2605 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
2606 else
2607 for ( k = 0; k < nRange; k++ )
2608 {
2609 char Buffer[1000];
2610 sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2611 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2612 }
2613 }
2614 Vec_IntFreeP( &vAddObjs );
2615 }
2616 // add flop outputs
2617 if ( fAdded )
2618 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav("abc_reset_flop_in") );
2619 Wlc_NtkForEachCo( p, pObj, i )
2620 if ( !Wlc_ObjIsPo(pObj) )
2621 {
2622 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2623 nRange = Wlc_ObjRange( pObj );
2624 if ( fSkipBitRange && nRange == 1 )
2625 {
2626 char Buffer[1000];
2627 sprintf( Buffer, "%s_fi", pName );
2628 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2629 }
2630 else
2631 for ( k = 0; k < nRange; k++ )
2632 {
2633 char Buffer[1000];
2634 sprintf( Buffer, "%s_fi[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2635 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2636 }
2637 }
2638 Wlc_NtkForEachFf2( p, pObj, i )
2639 {
2640 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2641 nRange = Wlc_ObjRange( pObj );
2642 if ( fSkipBitRange && nRange == 1 )
2643 {
2644 char Buffer[1000];
2645 sprintf( Buffer, "%s_fi", pName );
2646 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2647 }
2648 else
2649 for ( k = 0; k < nRange; k++ )
2650 {
2651 char Buffer[1000];
2652 sprintf( Buffer, "%s_fi[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2653 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2654 }
2655 }
2656 assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) );
2657
2658 // replace the current library
2659 if ( pBoxLib )
2660 {
2662 Abc_FrameSetLibBox( pBoxLib );
2663 }
2664
2665 //pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName );
2666 // dump the miter parts
2667 if ( 0 )
2668 {
2669 char pFileName0[1000], pFileName1[1000];
2670 char * pNameGeneric = Extra_FileNameGeneric( p->pSpec );
2671 Vec_Int_t * vOrder = Vec_IntStartNatural( Gia_ManPoNum(pNew) );
2672 Gia_Man_t * pGia0 = Gia_ManDupCones( pNew, Vec_IntArray(vOrder), Vec_IntSize(vOrder)/2, 0 );
2673 Gia_Man_t * pGia1 = Gia_ManDupCones( pNew, Vec_IntArray(vOrder) + Vec_IntSize(vOrder)/2, Vec_IntSize(vOrder)/2, 0 );
2674 assert( Gia_ManPoNum(pNew) % 2 == 0 );
2675 sprintf( pFileName0, "%s_lhs_.aig", pNameGeneric );
2676 sprintf( pFileName1, "%s_rhs_.aig", pNameGeneric );
2677 Gia_AigerWrite( pGia0, pFileName0, 0, 0, 0 );
2678 Gia_AigerWrite( pGia1, pFileName1, 0, 0, 0 );
2679 Gia_ManStop( pGia0 );
2680 Gia_ManStop( pGia1 );
2681 Vec_IntFree( vOrder );
2682 ABC_FREE( pNameGeneric );
2683 printf( "Dumped two parts of the miter into files \"%s\" and \"%s\".\n", pFileName0, pFileName1 );
2684 }
2685 //Wlc_NtkPrintNameArray( pNew->vNamesIn );
2686 //Wlc_NtkPrintNameArray( pNew->vNamesOut );
2687 if ( pPar->vBoxIds )
2688 {
2689 Vec_PtrFreeFree( pNew->vNamesIn ); pNew->vNamesIn = NULL;
2690 Vec_PtrFreeFree( pNew->vNamesOut ); pNew->vNamesOut = NULL;
2691 }
2692 pNew->vRegClasses = vRegClasses;
2693 return pNew;
2694}
2695
2696
2708float * Extra_FileReadFloat( FILE * pFile, int * pnFileSize )
2709{
2710 float * pBuffer;
2711 int RetValue, nFileSize;
2712 fseek( pFile, 0, SEEK_END );
2713 nFileSize = *pnFileSize = ftell( pFile );
2714 rewind( pFile );
2715 assert( nFileSize%4 == 0 );
2716 pBuffer = ABC_CALLOC( float, nFileSize/4 );
2717 RetValue = fread( pBuffer, nFileSize, 1, pFile );
2718 return pBuffer;
2719}
2720float * Extra_FileReadFloatContents( char * pFileName, int * pnFileSize )
2721{
2722 FILE * pFile;
2723 float * pBuffer;
2724 pFile = fopen( pFileName, "rb" );
2725 pBuffer = pFile ? Extra_FileReadFloat( pFile, pnFileSize ) : NULL;
2726 if ( pFile ) fclose( pFile );
2727 return pBuffer;
2728}
2729static inline int Extra_FixedFound( int Value, int Fixed )
2730{
2731 Value += 1 << (Fixed-1);
2732 Value >>= Fixed;
2733 return Value;
2734}
2735static inline int Extra_ConvertFloat8( float Value )
2736{
2737 return Extra_FixedFound( (int)(Value * (1 << 16)), 8 );
2738}
2739Gia_Man_t * Wlc_BlastArray( char * pFileName )
2740{
2741 int nFileSize = 0;
2742 float * pBuffer = Extra_FileReadFloatContents( pFileName, &nFileSize );
2743 int i, v, Value, nInputs = nFileSize/4 - 1;
2744 Vec_Int_t * vArg0 = Vec_IntAlloc( 100 );
2745 Vec_Int_t * vArg1 = Vec_IntAlloc( 100 );
2746 Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
2747 Vec_Int_t * vRes = Vec_IntAlloc( 100 );
2748 Vec_Int_t * vSum = Vec_IntAlloc( 100 );
2749 Gia_Man_t * pTemp, * pNew = Gia_ManStart( 10000 );
2750 pNew->pName = Abc_UtilStrsav( "blast" );
2751 Gia_ManHashAlloc( pNew );
2752 for ( i = 0; i < 8*nInputs; i++ )
2753 Gia_ManAppendCi(pNew);
2754
2755 Value = (Extra_ConvertFloat8(pBuffer[0]) << 8) | (1 << 7);
2756 for ( v = 0; v < 20; v++ )
2757 Vec_IntPush( vSum, (Value >> v) & 1 );
2758
2759 for ( i = 0; i < nInputs; i++ )
2760 {
2761 Value = Extra_ConvertFloat8( pBuffer[1+i] );
2762
2763 Vec_IntClear( vArg0 );
2764 for ( v = 0; v < 8; v++ )
2765 Vec_IntPush( vArg0, Gia_ManCiLit(pNew, 8*i+v) );
2766
2767 Vec_IntClear( vArg1 );
2768 for ( v = 0; v < 12; v++ )
2769 Vec_IntPush( vArg1, (Value >> v) & 1 );
2770
2771 Wlc_BlastMultiplier( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), 8, 12, vTemp, vRes, 1 );
2772 Wlc_BlastAdder( pNew, Vec_IntArray(vSum), Vec_IntArray(vRes), 20, 0 );
2773 }
2774 ABC_FREE( pBuffer );
2775 for ( v = 8; v < 16; v++ )
2776 Gia_ManAppendCo( pNew, Vec_IntEntry(vSum, v) );
2777 Vec_IntFree( vArg0 );
2778 Vec_IntFree( vArg1 );
2779 Vec_IntFree( vTemp );
2780 Vec_IntFree( vRes );
2781 Vec_IntFree( vSum );
2782
2783 pNew = Gia_ManCleanup( pTemp = pNew );
2784 Gia_ManStop( pTemp );
2785 return pNew;
2786}
2787
2800{
2801 Vec_Int_t * vPerm = Vec_IntAlloc( 100 );
2802 Vec_Int_t * vSizes = Vec_IntAlloc( 100 );
2803 Vec_Int_t * vOffs = Vec_IntAlloc( 100 );
2804 Wlc_Obj_t * pObj;
2805 int i, k, First, Size, nBitCis = 0, fChange = 1;
2806 Wlc_NtkForEachPi( pNtk, pObj, i )
2807 {
2808 Vec_IntPush( vOffs, nBitCis );
2809 Vec_IntPush( vSizes, Wlc_ObjRange(pObj) );
2810 nBitCis += Wlc_ObjRange(pObj);
2811 }
2812 for ( k = 0; fChange; k++ )
2813 {
2814 fChange = 0;
2815 Vec_IntForEachEntryTwo( vOffs, vSizes, First, Size, i )
2816 if ( k < Size )
2817 {
2818 Vec_IntPush( vPerm, First+k );
2819 fChange = 1;
2820 }
2821 }
2822 assert( Vec_IntSize(vPerm) == nBitCis );
2823 Vec_IntFree( vOffs );
2824 Vec_IntFree( vSizes );
2825 Vec_IntReverseOrder( vPerm );
2826 for ( i = Vec_IntSize(vPerm); i < nPis; i++ )
2827 Vec_IntPush( vPerm, i );
2828 //Vec_IntPrint( vPerm );
2829 return vPerm;
2830}
2831
2844{
2845 int fSkipBitRange = 0;
2846 Wlc_Obj_t * pObj; int i, k;
2847 Vec_PtrFreeP( &pNew->vNamesIn );
2848 Vec_PtrFreeP( &pNew->vNamesOut );
2849 pNew->vNamesIn = Vec_PtrAlloc( Gia_ManPiNum(pNew) );
2850 pNew->vNamesOut = Vec_PtrAlloc( Gia_ManPoNum(pNew) );
2851 // create input names
2852 Wlc_NtkForEachCi( p, pObj, i )
2853 if ( Wlc_ObjIsPi(pObj) )
2854 {
2855 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2856 int nRange = Wlc_ObjRange( pObj );
2857 if ( fSkipBitRange && nRange == 1 )
2858 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(pName) );
2859 else
2860 for ( k = 0; k < nRange; k++ )
2861 {
2862 char Buffer[1000];
2863 sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2864 Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsav(Buffer) );
2865 //printf( "Writing %s\n", Buffer );
2866 }
2867 }
2868 // add real primary outputs
2869 Wlc_NtkForEachCo( p, pObj, i )
2870 if ( Wlc_ObjIsPo(pObj) )
2871 {
2872 char * pName = Wlc_ObjName(p, Wlc_ObjId(p, pObj));
2873 int nRange = Wlc_ObjRange( pObj );
2874 if ( fSkipBitRange && nRange == 1 )
2875 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(pName) );
2876 else
2877 for ( k = 0; k < nRange; k++ )
2878 {
2879 char Buffer[1000];
2880 sprintf( Buffer, "%s[%d]", pName, pObj->Beg < pObj->End ? pObj->Beg+k : pObj->Beg-k );
2881 Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsav(Buffer) );
2882 }
2883 }
2884 if ( Vec_PtrSize(pNew->vNamesIn) != Gia_ManPiNum(pNew) )
2885 printf( "The number of input bits (%d) does not match the number of primary inputs (%d) in the current AIG.\n", Vec_PtrSize(pNew->vNamesIn), Gia_ManPiNum(pNew) );
2886 if ( Vec_PtrSize(pNew->vNamesOut) != Gia_ManPoNum(pNew) )
2887 printf( "The number of output bits (%d) does not match the number of primary inputs (%d) in the current AIG.\n", Vec_PtrSize(pNew->vNamesOut), Gia_ManPoNum(pNew) );
2888 if ( Vec_PtrSize(pNew->vNamesIn) != Gia_ManPiNum(pNew) || Vec_PtrSize(pNew->vNamesOut) != Gia_ManPoNum(pNew) )
2889 {
2890 Vec_PtrFreeP( &pNew->vNamesIn );
2891 Vec_PtrFreeP( &pNew->vNamesOut );
2892 }
2893 else
2894 printf( "Successfully transferred the primary input/output names from the word-level design to the current AIG.\n" );
2895}
2896
2908void Wlc_MultBlastFileGen( int a, int b, int s )
2909{
2910 FILE * pFile = fopen( "_test13_.v", "wb" );
2911 fprintf( pFile, "module test ( a, b, z );\n" );
2912 fprintf( pFile, "input %s [%d:0] a;\n", s ? "signed":"", a-1 );
2913 fprintf( pFile, "input %s [%d:0] b;\n", s ? "signed":"", b-1 );
2914 fprintf( pFile, "output %s [%d:0] z;\n", s ? "signed":"", a+b-1 );
2915 fprintf( pFile, "assign z = a * b;\n" );
2916 fprintf( pFile, "endmodule\n" );
2917 fclose( pFile );
2918}
2920{
2921 char * Command = "%read _test13_.v; %blast; &ps; &w 1.aig; %read _test13_.v; %blast -b; &ps; &w 2.aig; cec -n 1.aig 2.aig";
2922 int a, b, s, Iters = 0;
2923 for ( a = 1; a < 8; a++ )
2924 for ( b = 1; b < 8; b++ )
2925 for ( s = 0; s < 2; s++ )
2926 {
2927 Wlc_MultBlastFileGen( a, b, s );
2928 if ( Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ) )
2929 {
2930 fprintf( stdout, "Cannot execute command \"%s\".\n", Command );
2931 return;
2932 }
2933 Iters++;
2934 }
2935 printf( "Finished %d iterations.\n", Iters );
2936}
2937
2941
2942
2944
#define ABC_SWAP(Type, a, b)
Definition abc_global.h:253
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
ABC_DLL Abc_Frame_t * Abc_FrameGetGlobalFrame()
Definition mainFrame.c:643
int nTotal
DECLARATIONS ///.
Definition cutTruth.c:37
ABC_DLL void Abc_FrameSetLibBox(void *pLib)
Definition mainFrame.c:94
ABC_DLL void * Abc_FrameReadLibBox()
Definition mainFrame.c:58
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
ABC_DLL int Cmd_CommandExecute(Abc_Frame_t *pAbc, const char *sCommand)
Definition cmdApi.c:193
Cube * p
Definition exorList.c:222
char * Extra_FileNameGeneric(char *FileName)
ABC_NAMESPACE_IMPL_START int Kit_TruthToGia(Gia_Man_t *pMan, unsigned *pTruth, int nVars, Vec_Int_t *vMemory, Vec_Int_t *vLeaves, int fHash)
DECLARATIONS ///.
Definition kitHop.c:80
void Extra_PrintHex(FILE *pFile, unsigned *pTruth, int nVars)
void Gia_ManStop(Gia_Man_t *p)
Definition giaMan.c:82
int Gia_ManHashDualMiter(Gia_Man_t *p, Vec_Int_t *vOuts)
Definition giaHash.c:809
void Gia_ManSetRegNum(Gia_Man_t *p, int nRegs)
Definition giaMan.c:764
int Gia_ManHashAndMulti(Gia_Man_t *p, Vec_Int_t *vLits)
Definition giaHash.c:783
void Gia_ManHashAlloc(Gia_Man_t *p)
Definition giaHash.c:105
Gia_Man_t * Gia_ManStart(int nObjsMax)
FUNCTION DEFINITIONS ///.
Definition giaMan.c:57
int Gia_ManHashOr(Gia_Man_t *p, int iLit0, int iLit1)
Definition giaHash.c:621
struct Gia_Obj_t_ Gia_Obj_t
Definition gia.h:76
int Gia_ManHashXor(Gia_Man_t *p, int iLit0, int iLit1)
Definition giaHash.c:668
void Gia_ManDupRemapLiterals(Vec_Int_t *vLits, Gia_Man_t *p)
FUNCTION DEFINITIONS ///.
Definition giaDup.c:54
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
int Gia_ManHashMux(Gia_Man_t *p, int iCtrl, int iData1, int iData0)
Definition giaHash.c:692
Gia_Man_t * Gia_ManDupCones(Gia_Man_t *p, int *pPos, int nPos, int fTrimPis)
Definition giaDup.c:3880
Gia_Man_t * Gia_ManCleanup(Gia_Man_t *p)
Definition giaScl.c:84
void Gia_ManTransferTiming(Gia_Man_t *p, Gia_Man_t *pGia)
Definition giaIf.c:2370
void Gia_ManCleanLevels(Gia_Man_t *p, int Size)
Definition giaUtil.c:511
Gia_Man_t * Gia_ManDupNormalize(Gia_Man_t *p, int fHashMapping)
Definition giaTim.c:139
int Gia_ManHashAnd(Gia_Man_t *p, int iLit0, int iLit1)
Definition giaHash.c:576
word Gia_ObjComputeTruth6Cis(Gia_Man_t *p, int iLit, Vec_Int_t *vSupp, Vec_Wrd_t *vTemp)
Definition giaTruth.c:345
Gia_Man_t * Gia_ManDupZeroUndc(Gia_Man_t *p, char *pInit, int nNewPis, int fGiaSimple, int fVerbose)
Definition giaDup.c:3569
void Gia_AigerWrite(Gia_Man_t *p, char *pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine)
Definition giaAiger.c:1595
struct If_LibBox_t_ If_LibBox_t
Definition if.h:83
If_Box_t * If_BoxStart(char *pName, int Id, int nPis, int nPos, int fSeq, int fBlack, int fOuter)
FUNCTION DEFINITIONS ///.
Definition ifLibBox.c:49
int If_LibBoxNum(If_LibBox_t *p)
Definition ifLibBox.c:144
void If_LibBoxAdd(If_LibBox_t *p, If_Box_t *pBox)
Definition ifLibBox.c:136
struct If_Box_t_ If_Box_t
Definition if.h:364
void If_LibBoxFree(If_LibBox_t *p)
Definition ifLibBox.c:98
If_LibBox_t * If_LibBoxStart()
Definition ifLibBox.c:86
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
Gia_Man_t * pAigExtra
Definition gia.h:167
Vec_Ptr_t * vNamesIn
Definition gia.h:181
Vec_Ptr_t * vNamesOut
Definition gia.h:182
int fGiaSimple
Definition gia.h:116
Vec_Int_t * vRegClasses
Definition gia.h:160
void * pManTime
Definition gia.h:194
char * pName
Definition gia.h:99
int nPos
Definition if.h:374
int nPis
Definition if.h:373
int * pDelays
Definition if.h:375
int fNonRest
Definition wlc.h:218
int fNoCleanup
Definition wlc.h:221
int fGiaSimple
Definition wlc.h:214
int fAddOutputs
Definition wlc.h:215
int fDivBy0
Definition wlc.h:220
int fDecMuxes
Definition wlc.h:224
int fSaveFfNames
Definition wlc.h:225
int fCreateWordMiter
Definition wlc.h:223
int fCreateMiter
Definition wlc.h:222
int nOutputRange
Definition wlc.h:211
int fCla
Definition wlc.h:219
Vec_Int_t * vBoxIds
Definition wlc.h:228
int fVerbose
Definition wlc.h:227
int fBlastNew
Definition wlc.h:226
int iOutput
Definition wlc.h:210
int fBooth
Definition wlc.h:217
unsigned Type
Definition wlc.h:121
int End
Definition wlc.h:129
unsigned fIsFi
Definition wlc.h:126
unsigned Mark
Definition wlc.h:123
int Beg
Definition wlc.h:130
void Tim_ManSetDelayTables(Tim_Man_t *p, Vec_Ptr_t *vDelayTables)
Definition timMan.c:765
int Tim_ManBoxNum(Tim_Man_t *p)
Definition timMan.c:722
typedefABC_NAMESPACE_HEADER_START struct Tim_Man_t_ Tim_Man_t
INCLUDES ///.
Definition tim.h:92
int Tim_ManCiNum(Tim_Man_t *p)
Definition timMan.c:700
void Tim_ManCreateBox(Tim_Man_t *p, int firstIn, int nIns, int firstOut, int nOuts, int iDelayTable, int fBlack)
ITERATORS ///.
Definition timBox.c:44
void Tim_ManBoxSetCopy(Tim_Man_t *p, int iBox, int iCopy)
Definition timBox.c:291
Tim_Man_t * Tim_ManStart(int nCis, int nCos)
DECLARATIONS ///.
Definition timMan.c:45
int Tim_ManCoNum(Tim_Man_t *p)
Definition timMan.c:704
#define assert(ex)
Definition util_old.h:213
char * memcpy()
char * memset()
int strlen()
char * sprintf()
VOID_HACK rewind()
#define Vec_IntForEachEntryDouble(vVec, Entry1, Entry2, i)
Definition vecInt.h:72
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
#define Vec_IntForEachEntryTwo(vVec1, vVec2, Entry1, Entry2, i)
Definition vecInt.h:66
#define Vec_IntForEachEntryReverse(vVec, pEntry, i)
Definition vecInt.h:62
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
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
Definition vecWec.h:55
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
Definition vecWec.h:42
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.
Definition vecWrd.h:42
int Wlc_BlastAdder(Gia_Man_t *pNew, int *pAdd0, int *pAdd1, int nBits, int Carry)
Definition wlcBlast.c:429
void Wlc_BlastMultiplierC(Gia_Man_t *pNew, int *pArgA, int *pArgB, int nArgA, int nArgB, Vec_Int_t *vTemp, Vec_Int_t *vRes, int fSigned)
Definition wlcBlast.c:659
void Wlc_BlastDividerSigned(Gia_Man_t *pNew, int *pNum, int nNum, int *pDiv, int nDiv, int fQuo, Vec_Int_t *vRes, int fNonRest)
Definition wlcBlast.c:764
int Wlc_NtkPrepareBits(Wlc_Ntk_t *p)
Definition wlcBlast.c:67
void Wlc_BlastAdderCLA_one(Gia_Man_t *pNew, int *pGen, int *pPro, int *pCar, int *pGen1, int *pPro1, int *pCar1)
Definition wlcBlast.c:443
Vec_Int_t * Wlc_BlastDecoder2(Gia_Man_t *pNew, int *pNum, int nNum, Vec_Int_t *vTmp, Vec_Int_t *vRes)
Definition wlcBlast.c:1234
void Wlc_MultBlastFileGen(int a, int b, int s)
Definition wlcBlast.c:2908
void Wlc_BlastMultiplier2(Gia_Man_t *pNew, int *pArg0, int *pArg1, int nBits, Vec_Int_t *vTemp, Vec_Int_t *vRes)
Definition wlcBlast.c:613
char * Wlc_NtkMuxTreeString(int nIns)
Definition wlcBlast.c:171
int Wlc_NtkMuxTree2(Gia_Man_t *pNew, int *pCtrl, int nCtrl, Vec_Int_t *vData, Vec_Int_t *vAnds, Vec_Int_t *vTemp)
Definition wlcBlast.c:126
void Wlc_BlastPrintMatrix(Gia_Man_t *p, Vec_Wec_t *vProds, int fVerbose)
Definition wlcBlast.c:937
void Wlc_BlastPower(Gia_Man_t *pNew, int *pNum, int nNum, int *pExp, int nExp, Vec_Int_t *vTemp, Vec_Int_t *vRes)
Definition wlcBlast.c:844
void Wlc_BlastZeroCondition(Gia_Man_t *pNew, int *pDiv, int nDiv, Vec_Int_t *vRes)
Definition wlcBlast.c:799
void Wlc_BlastShiftRight(Gia_Man_t *pNew, int *pNum, int nNum, int *pShift, int nShift, int fSticky, Vec_Int_t *vRes)
Definition wlcBlast.c:228
ABC_NAMESPACE_IMPL_START int Wlc_NtkCountConstBits(int *pArray, int nSize)
DECLARATIONS ///.
Definition wlcBlast.c:48
void Wlc_BlastShiftRightInt(Gia_Man_t *pNew, int *pNum, int nNum, int *pShift, int nShift, int fSticky, Vec_Int_t *vRes)
Definition wlcBlast.c:209
void Wlc_BlastRotateLeft(Gia_Man_t *pNew, int *pNum, int nNum, int *pShift, int nShift, Vec_Int_t *vRes)
Definition wlcBlast.c:291
void Wlc_BlastBooth(Gia_Man_t *pNew, int *pArgA, int *pArgB, int nArgA, int nArgB, Vec_Int_t *vRes, int fSigned, int fCla, Vec_Wec_t **pvProds, int fVerbose)
Definition wlcBlast.c:1242
void Wlc_BlastAdderFast(Gia_Man_t *pNew, int *pAdd0, int *pAdd1, int nBits, int fSign, int CarryIn)
Definition wlcBlast.c:581
float * Extra_FileReadFloatContents(char *pFileName, int *pnFileSize)
Definition wlcBlast.c:2720
int * Wlc_VecCopy(Vec_Int_t *vOut, int *pArray, int nSize)
Definition wlcBlast.c:79
int Wlc_BlastLessSigned(Gia_Man_t *pNew, int *pArg0, int *pArg1, int nBits)
Definition wlcBlast.c:372
void Wlc_BlastShiftLeftInt(Gia_Man_t *pNew, int *pNum, int nNum, int *pShift, int nShift, int fSticky, Vec_Int_t *vRes)
Definition wlcBlast.c:245
float * Extra_FileReadFloat(FILE *pFile, int *pnFileSize)
Definition wlcBlast.c:2708
void Wlc_BlastReduceMatrix(Gia_Man_t *pNew, Vec_Wec_t *vProds, Vec_Wec_t *vLevels, Vec_Int_t *vRes, int fSigned, int fCla)
Definition wlcBlast.c:971
Gia_Man_t * Wlc_NtkBitBlast(Wlc_Ntk_t *p, Wlc_BstPar_t *pParIn)
Definition wlcBlast.c:1349
void Wlc_TransferPioNames(Wlc_Ntk_t *p, Gia_Man_t *pNew)
Definition wlcBlast.c:2843
void Wlc_BlastFullAdderSubtr(Gia_Man_t *pNew, int a, int b, int c, int *pc, int *ps, int fSub)
Definition wlcBlast.c:631
Vec_Int_t * Wlc_ComputePerm(Wlc_Ntk_t *pNtk, int nPis)
Definition wlcBlast.c:2799
void Wlc_BlastSquare(Gia_Man_t *pNew, int *pNum, int nNum, Vec_Int_t *vTmp, Vec_Int_t *vRes)
Definition wlcBlast.c:1174
void Wlc_BlastMinus(Gia_Man_t *pNew, int *pNum, int nNum, Vec_Int_t *vRes)
Definition wlcBlast.c:603
void Wlc_NtkMuxTree3DecsFree(Vec_Int_t **pvDecs, char *pNums)
Definition wlcBlast.c:164
void Wlc_BlastSqrtNR(Gia_Man_t *pNew, int *pNum, int nNum, Vec_Int_t *vTmp, Vec_Int_t *vRes)
Definition wlcBlast.c:899
void Wlc_BlastAdderCLA_rec(Gia_Man_t *pNew, int *pGen, int *pPro, int *pCar, int nBits, int *pGen1, int *pPro1)
Definition wlcBlast.c:450
void Wlc_BlastRotateRight(Gia_Man_t *pNew, int *pNum, int nNum, int *pShift, int nShift, Vec_Int_t *vRes)
Definition wlcBlast.c:281
int Wlc_BlastGetConst(int *pNum, int nNum)
Definition wlcBlast.c:95
void Wlc_BlastLess_rec(Gia_Man_t *pNew, int *pArg0, int *pArg1, int nBits, int *pYes, int *pNo)
Definition wlcBlast.c:343
void Wlc_BlastMultiplier3(Gia_Man_t *pNew, int *pArgA, int *pArgB, int nArgA, int nArgB, Vec_Int_t *vRes, int fSigned, int fCla, Vec_Wec_t **pvProds, int fVerbose)
Definition wlcBlast.c:1140
void Wlc_BlastFullAdder(Gia_Man_t *pNew, int a, int b, int c, int *pc, int *ps)
Definition wlcBlast.c:401
void Wlc_BlastLut(Gia_Man_t *pNew, word Truth, int *pFans, int nFans, int nOuts, Vec_Int_t *vRes)
Definition wlcBlast.c:830
int Wlc_NtkMuxTree2_nb(Gia_Man_t *pNew, int *pCtrl, int nCtrl, Vec_Int_t *vData, Vec_Int_t *vAnds)
Definition wlcBlast.c:114
void Wlc_BlastShiftLeft(Gia_Man_t *pNew, int *pNum, int nNum, int *pShift, int nShift, int fSticky, Vec_Int_t *vRes)
Definition wlcBlast.c:264
void Wlc_BlastSqrt(Gia_Man_t *pNew, int *pNum, int nNum, Vec_Int_t *vTmp, Vec_Int_t *vRes)
Definition wlcBlast.c:868
Vec_Int_t ** Wlc_NtkMuxTree3DecsDerive(Gia_Man_t *p, int *pIns, int nIns, char *pNums)
Definition wlcBlast.c:153
void Wlc_NtkPrintNameArray(Vec_Ptr_t *vNames)
Definition wlcBlast.c:191
Vec_Int_t * Wlc_BlastDecoder2_rec(Gia_Man_t *p, int *pLits, int nLits)
Definition wlcBlast.c:1211
int Wlc_NtkMuxTree_rec(Gia_Man_t *pNew, int *pCtrl, int nCtrl, Vec_Int_t *vData, int Shift)
Definition wlcBlast.c:105
int Wlc_NtkMuxTree3(Gia_Man_t *p, Vec_Int_t *vData, char *pNums, Vec_Int_t **pvDecs)
Definition wlcBlast.c:136
void Wlc_BlastDividerTop(Gia_Man_t *pNew, int *pNum, int nNum, int *pDiv, int nDiv, int fQuo, Vec_Int_t *vRes, int fNonRest)
Definition wlcBlast.c:757
void Wlc_BlastDivider(Gia_Man_t *pNew, int *pNum, int nNum, int *pDiv, int nDiv, int fQuo, Vec_Int_t *vRes)
Definition wlcBlast.c:679
void Wlc_BlastAdderCLA_int(Gia_Man_t *pNew, int *pAdd0, int *pAdd1, int nBits, int CarryIn)
Definition wlcBlast.c:466
void Wlc_MultBlastTest()
Definition wlcBlast.c:2919
void Wlc_BlastSubtract(Gia_Man_t *pNew, int *pAdd0, int *pAdd1, int nBits, int Carry)
Definition wlcBlast.c:436
void Wlc_BlastDividerNR(Gia_Man_t *pNew, int *pNum, int nNum, int *pDiv, int nDiv, int fQuo, Vec_Int_t *vRes)
Definition wlcBlast.c:727
void Wlc_IntInsert(Vec_Int_t *vProd, Vec_Int_t *vLevel, int Node, int Level)
Definition wlcBlast.c:928
void Wlc_IntSortCostReverse(Gia_Man_t *pNew, int *pArray, int nSize)
Definition wlcBlast.c:1067
Gia_Man_t * Wlc_BlastArray(char *pFileName)
Definition wlcBlast.c:2739
void Wlc_BlastTable(Gia_Man_t *pNew, word *pTable, int *pFans, int nFans, int nOuts, Vec_Int_t *vRes)
Definition wlcBlast.c:805
void Wlc_BlastFullAdderCtrl(Gia_Man_t *pNew, int a, int ac, int b, int c, int *pc, int *ps, int fNeg)
Definition wlcBlast.c:626
void Wlc_BlastMultiplier(Gia_Man_t *pNew, int *pArgA, int *pArgB, int nArgA, int nArgB, Vec_Int_t *vTemp, Vec_Int_t *vRes, int fSigned)
Definition wlcBlast.c:635
void Wlc_BlastReduceMatrix2(Gia_Man_t *pNew, Vec_Wec_t *vProds, Vec_Int_t *vRes, int fSigned, int fCla)
Definition wlcBlast.c:1079
int Wlc_BlastLess(Gia_Man_t *pNew, int *pArg0, int *pArg1, int nBits)
Definition wlcBlast.c:364
int Wlc_BlastLess3(Gia_Man_t *p, int *pArg1, int *pArg0, int nBits)
Definition wlcBlast.c:377
int Wlc_BlastLessSigned3(Gia_Man_t *pNew, int *pArg0, int *pArg1, int nBits)
Definition wlcBlast.c:396
int Wlc_BlastAddLevel(Gia_Man_t *pNew, int Start)
Definition wlcBlast.c:1043
void Wlc_BlastAdderFast_int(Gia_Man_t *pNew, int *pAdd0, int *pAdd1, int Log2, int CarryIn)
Definition wlcBlast.c:514
void Wlc_IntInsert2(Gia_Man_t *pNew, Vec_Int_t *vProd, int iLit)
Definition wlcBlast.c:1056
int Wlc_BlastLess2(Gia_Man_t *pNew, int *pArg0, int *pArg1, int nBits)
Definition wlcBlast.c:331
int Wlc_BlastReduction(Gia_Man_t *pNew, int *pFans, int nFans, int Type)
Definition wlcBlast.c:305
int * Wlc_VecLoadFanins(Vec_Int_t *vOut, int *pFanins, int nFanins, int nTotal, int fSigned)
Definition wlcBlast.c:86
void Wlc_BlastAdderCLA(Gia_Man_t *pNew, int *pAdd0, int *pAdd1, int nBits, int fSign, int CarryIn)
Definition wlcBlast.c:492
void Wlc_BlastDecoder(Gia_Man_t *pNew, int *pNum, int nNum, Vec_Int_t *vTmp, Vec_Int_t *vRes)
Definition wlcBlast.c:1199
#define Wlc_NtkForEachFf2(p, pFf, i)
Definition wlc.h:372
#define Wlc_NtkForEachCi(p, pCi, i)
Definition wlc.h:366
#define Wlc_NtkForEachObjVec(vVec, p, pObj, i)
Definition wlc.h:360
#define Wlc_NtkForEachPi(p, pPi, i)
Definition wlc.h:362
struct Wlc_Ntk_t_ Wlc_Ntk_t
Definition wlc.h:135
#define Wlc_NtkForEachObj(p, pObj, i)
MACRO DEFINITIONS ///.
Definition wlc.h:356
#define Wlc_ObjForEachFanin(pObj, iFanin, i)
Definition wlc.h:375
char * Wlc_ObjName(Wlc_Ntk_t *p, int iObj)
Definition wlcNtk.c:225
#define Wlc_ObjForEachFaninReverse(pObj, iFanin, i)
Definition wlc.h:379
@ WLC_OBJ_ARI_MULTI
Definition wlc.h:90
@ WLC_OBJ_BIT_SIGNEXT
Definition wlc.h:70
@ WLC_OBJ_COMP_LESSEQU
Definition wlc.h:80
@ WLC_OBJ_LOGIC_XOR
Definition wlc.h:75
@ WLC_OBJ_SHIFT_LA
Definition wlc.h:57
@ WLC_OBJ_BIT_ZEROPAD
Definition wlc.h:69
@ WLC_OBJ_COMP_MOREEQU
Definition wlc.h:81
@ WLC_OBJ_BUF
Definition wlc.h:52
@ WLC_OBJ_COMP_MORE
Definition wlc.h:79
@ WLC_OBJ_REDUCT_AND
Definition wlc.h:82
@ WLC_OBJ_ARI_POWER
Definition wlc.h:94
@ WLC_OBJ_ARI_REM
Definition wlc.h:92
@ WLC_OBJ_ARI_SUB
Definition wlc.h:89
@ WLC_OBJ_LOGIC_OR
Definition wlc.h:74
@ WLC_OBJ_SEL
Definition wlc.h:102
@ WLC_OBJ_LOGIC_AND
Definition wlc.h:73
@ WLC_OBJ_NUMBER
Definition wlc.h:105
@ WLC_OBJ_COMP_LESS
Definition wlc.h:78
@ WLC_OBJ_ARI_SQUARE
Definition wlc.h:97
@ WLC_OBJ_REDUCT_NOR
Definition wlc.h:86
@ WLC_OBJ_BIT_NOT
Definition wlc.h:60
@ WLC_OBJ_SHIFT_R
Definition wlc.h:54
@ WLC_OBJ_TABLE
Definition wlc.h:98
@ WLC_OBJ_BIT_AND
Definition wlc.h:61
@ WLC_OBJ_CONST
Definition wlc.h:51
@ WLC_OBJ_FO
Definition wlc.h:48
@ WLC_OBJ_ARI_DIVIDE
Definition wlc.h:91
@ WLC_OBJ_REDUCT_NAND
Definition wlc.h:85
@ WLC_OBJ_BIT_SELECT
Definition wlc.h:67
@ WLC_OBJ_REDUCT_OR
Definition wlc.h:83
@ WLC_OBJ_MUX
Definition wlc.h:53
@ WLC_OBJ_BIT_NAND
Definition wlc.h:64
@ WLC_OBJ_ARI_ADDSUB
Definition wlc.h:101
@ WLC_OBJ_LOGIC_NOT
Definition wlc.h:71
@ WLC_OBJ_COMP_NOTEQU
Definition wlc.h:77
@ WLC_OBJ_REDUCT_XOR
Definition wlc.h:84
@ WLC_OBJ_BIT_NOR
Definition wlc.h:65
@ WLC_OBJ_BIT_CONCAT
Definition wlc.h:68
@ WLC_OBJ_BIT_OR
Definition wlc.h:62
@ WLC_OBJ_BIT_XOR
Definition wlc.h:63
@ WLC_OBJ_ARI_MINUS
Definition wlc.h:95
@ WLC_OBJ_DEC
Definition wlc.h:103
@ WLC_OBJ_ARI_MODULUS
Definition wlc.h:93
@ WLC_OBJ_ARI_ADD
Definition wlc.h:88
@ WLC_OBJ_COMP_EQU
Definition wlc.h:76
@ WLC_OBJ_ARI_SQRT
Definition wlc.h:96
@ WLC_OBJ_LOGIC_IMPL
Definition wlc.h:72
@ WLC_OBJ_SHIFT_L
Definition wlc.h:56
@ WLC_OBJ_REDUCT_NXOR
Definition wlc.h:87
@ WLC_OBJ_BIT_NXOR
Definition wlc.h:66
@ WLC_OBJ_ROTATE_L
Definition wlc.h:59
@ WLC_OBJ_LUT
Definition wlc.h:104
@ WLC_OBJ_SHIFT_RA
Definition wlc.h:55
@ WLC_OBJ_FF
Definition wlc.h:50
@ WLC_OBJ_ROTATE_R
Definition wlc.h:58
struct Wlc_BstPar_t_ Wlc_BstPar_t
Definition wlc.h:207
struct Wlc_Obj_t_ Wlc_Obj_t
BASIC TYPES ///.
Definition wlc.h:118
#define Wlc_NtkForEachCo(p, pCo, i)
Definition wlc.h:368
#define SEEK_END
Definition zconf.h:392