ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
abcSymm.c
Go to the documentation of this file.
1
20
21#include "base/abc/abc.h"
22#include "opt/sim/sim.h"
23#include "opt/dau/dau.h"
24#include "misc/util/utilTruth.h"
25
26#ifdef ABC_USE_CUDD
27#include "bdd/extrab/extraBdd.h"
28#endif
29
31
32
36
37#ifdef ABC_USE_CUDD
38
39static void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fReorder, int fVerbose );
40static void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose );
41static void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose );
42static void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms );
43
47
59void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fReorder, int fVerbose )
60{
61 if ( fUseBdds || fNaive )
62 Abc_NtkSymmetriesUsingBdds( pNtk, fNaive, fReorder, fVerbose );
63 else
64 Abc_NtkSymmetriesUsingSandS( pNtk, fVerbose );
65}
66
78void Abc_NtkSymmetriesUsingSandS( Abc_Ntk_t * pNtk, int fVerbose )
79{
80// extern int Sim_ComputeTwoVarSymms( Abc_Ntk_t * pNtk, int fVerbose );
81 int nSymms = Sim_ComputeTwoVarSymms( pNtk, fVerbose );
82 printf( "The total number of symmetries is %d.\n", nSymms );
83}
84
96void Abc_NtkSymmetriesUsingBdds( Abc_Ntk_t * pNtk, int fNaive, int fReorder, int fVerbose )
97{
98 DdManager * dd;
99 abctime clk, clkBdd, clkSym;
100 int fGarbCollect = 1;
101
102 // compute the global functions
103clk = Abc_Clock();
104 dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, fReorder, 0, fVerbose );
105 printf( "Shared BDD size = %d nodes.\n", Abc_NtkSizeOfGlobalBdds(pNtk) );
106 Cudd_AutodynDisable( dd );
107 if ( !fGarbCollect )
108 Cudd_DisableGarbageCollection( dd );
109 Cudd_zddVarsFromBddVars( dd, 2 );
110clkBdd = Abc_Clock() - clk;
111 // create the collapsed network
112clk = Abc_Clock();
113 Ntk_NetworkSymmsBdd( dd, pNtk, fNaive, fVerbose );
114clkSym = Abc_Clock() - clk;
115 // undo the global functions
116 Abc_NtkFreeGlobalBdds( pNtk, 1 );
117printf( "Statistics of BDD-based symmetry detection:\n" );
118printf( "Algorithm = %s. Reordering = %s. Garbage collection = %s.\n",
119 fNaive? "naive" : "fast", fReorder? "yes" : "no", fGarbCollect? "yes" : "no" );
120ABC_PRT( "Constructing BDDs", clkBdd );
121ABC_PRT( "Computing symms ", clkSym );
122ABC_PRT( "TOTAL ", clkBdd + clkSym );
123}
124
136void Ntk_NetworkSymmsBdd( DdManager * dd, Abc_Ntk_t * pNtk, int fNaive, int fVerbose )
137{
138 Extra_SymmInfo_t * pSymms;
139 Abc_Obj_t * pNode;
140 DdNode * bFunc;
141 int nSymms = 0;
142 int nSupps = 0;
143 int i;
144
145 // compute symmetry info for each PO
146 Abc_NtkForEachCo( pNtk, pNode, i )
147 {
148// bFunc = pNtk->vFuncsGlob->pArray[i];
149 bFunc = (DdNode *)Abc_ObjGlobalBdd( pNode );
150 nSupps += Cudd_SupportSize( dd, bFunc );
151 if ( Cudd_IsConstant(bFunc) )
152 continue;
153 if ( fNaive )
154 pSymms = Extra_SymmPairsComputeNaive( dd, bFunc );
155 else
156 pSymms = Extra_SymmPairsCompute( dd, bFunc );
157 nSymms += pSymms->nSymms;
158 if ( fVerbose )
159 {
160 printf( "Output %6s (%d): ", Abc_ObjName(pNode), pSymms->nSymms );
161 Ntk_NetworkSymmsPrint( pNtk, pSymms );
162 }
163//Extra_SymmPairsPrint( pSymms );
164 Extra_SymmPairsDissolve( pSymms );
165 }
166 printf( "Total number of vars in functional supports = %8d.\n", nSupps );
167 printf( "Total number of two-variable symmetries = %8d.\n", nSymms );
168}
169
181void Ntk_NetworkSymmsPrint( Abc_Ntk_t * pNtk, Extra_SymmInfo_t * pSymms )
182{
183 char ** pInputNames;
184 int * pVarTaken;
185 int i, k, nVars, nSize, fStart;
186
187 // get variable names
188 nVars = Abc_NtkCiNum(pNtk);
189 pInputNames = Abc_NtkCollectCioNames( pNtk, 0 );
190
191 // alloc the array of marks
192 pVarTaken = ABC_ALLOC( int, nVars );
193 memset( pVarTaken, 0, sizeof(int) * nVars );
194
195 // print the groups
196 fStart = 1;
197 nSize = pSymms->nVars;
198 for ( i = 0; i < nSize; i++ )
199 {
200 // skip the variable already considered
201 if ( pVarTaken[i] )
202 continue;
203 // find all the vars symmetric with this one
204 for ( k = 0; k < nSize; k++ )
205 {
206 if ( k == i )
207 continue;
208 if ( pSymms->pSymms[i][k] == 0 )
209 continue;
210 // vars i and k are symmetric
211 assert( pVarTaken[k] == 0 );
212 // there is a new symmetry pair
213 if ( fStart == 1 )
214 { // start a new symmetry class
215 fStart = 0;
216 printf( " { %s", pInputNames[ pSymms->pVars[i] ] );
217 // mark the var as taken
218 pVarTaken[i] = 1;
219 }
220 printf( " %s", pInputNames[ pSymms->pVars[k] ] );
221 // mark the var as taken
222 pVarTaken[k] = 1;
223 }
224 if ( fStart == 0 )
225 {
226 printf( " }" );
227 fStart = 1;
228 }
229 }
230 printf( "\n" );
231
232 ABC_FREE( pInputNames );
233 ABC_FREE( pVarTaken );
234}
235
236#else
237
238void Abc_NtkSymmetries( Abc_Ntk_t * pNtk, int fUseBdds, int fNaive, int fReorder, int fVerbose ) {}
239
240#endif
241
253void Ntk_SymTryRandomFlips( word * pFun, word * pNpn, int nVars )
254{
255 int Rand[16] = { 17290, 20203, 19027, 12035, 14687, 10920, 10413, 261, 2072, 16899, 4480, 6192, 3978, 8343, 745, 1370 };
256 int i, nWords = Abc_TtWordNum(nVars);
257 word * pFunT = ABC_CALLOC( word, nWords );
258 Abc_TtCopy( pFunT, pFun, nWords, 0 );
259 for ( i = 0; i < 16; i++ )
260 Abc_TtFlip( pFunT, nWords, Rand[i] % (nVars-1) );
261 assert( Abc_TtCompareRev(pNpn, pFunT, nWords) != 1 );
262 ABC_FREE( pFunT );
263}
264
276void Ntk_SymFunDeriveNpn( word * pFun, int nVars, int * pComp )
277{
278 int i, nWords = Abc_TtWordNum(nVars);
279 word * pFunB = ABC_CALLOC( word, nWords );
280 Abc_TtCopy( pFunB, pFun, nWords, 1 );
281 if ( Abc_TtCompareRev(pFunB, pFun, nWords) == 1 )
282 Abc_TtCopy( pFunB, pFun, nWords, 0 );
283 for ( i = 0; i < (1 << nVars); i++ )
284 {
285 Abc_TtFlip( pFun, nWords, pComp[i] );
286 if ( Abc_TtCompareRev(pFunB, pFun, nWords) == 1 )
287 Abc_TtCopy( pFunB, pFun, nWords, 0 );
288 Abc_TtNot( pFun, nWords );
289 if ( Abc_TtCompareRev(pFunB, pFun, nWords) == 1 )
290 Abc_TtCopy( pFunB, pFun, nWords, 0 );
291 }
292 //Ntk_SymTryRandomFlips( pFun, pFunB, nVars );
293 Abc_TtCopy( pFun, pFunB, nWords, 0 );
294 ABC_FREE( pFunB );
295}
296
308void Ntk_SymFunGenerate( int nVars, int fVerbose )
309{
310 int k, m, Class;
311 int * pComp = Extra_GreyCodeSchedule( nVars );
312 Vec_Mem_t * vTtMem = Vec_MemAlloc( Abc_Truth6WordNum(nVars), 12 );
313 Vec_MemHashAlloc( vTtMem, 10000 );
314 assert( !(nVars < 1 || nVars > 16) );
315 printf( "Generating truth tables of all symmetric functions of %d variables.\n", nVars );
316 for ( m = 0; m < (1 << (nVars+1)); m++ )
317 {
318 word * pFun;
319 char Ones[100] = {0};
320 for ( k = 0; k <= nVars; k++ )
321 Ones[k] = '0' + ((m >> k) & 1);
322 if ( fVerbose )
323 printf( "%s : ", Ones );
324 pFun = Abc_TtSymFunGenerate( Ones, nVars );
325 if ( nVars < 6 )
326 pFun[0] = Abc_Tt6Stretch( pFun[0], nVars );
327 if ( fVerbose )
328 Extra_PrintHex( stdout, (unsigned *)pFun, nVars );
329 Ntk_SymFunDeriveNpn( pFun, nVars, pComp );
330 Class = Vec_MemHashInsert( vTtMem, pFun );
331 if ( fVerbose )
332 {
333 printf( " : NPN " );
334 Extra_PrintHex( stdout, (unsigned *)pFun, nVars );
335 printf( " Class %3d", Class );
336 printf( "\n" );
337 }
338 ABC_FREE( pFun );
339 }
340 printf( "The number of different NPN classes is %d.\n", Vec_MemEntryNum(vTtMem) );
341 Vec_MemHashFree( vTtMem );
342 Vec_MemFreeP( &vTtMem );
343 ABC_FREE( pComp );
344}
345
349
350
352
int nWords
Definition abcNpn.c:127
void Ntk_SymFunGenerate(int nVars, int fVerbose)
Definition abcSymm.c:308
void Ntk_SymTryRandomFlips(word *pFun, word *pNpn, int nVars)
Definition abcSymm.c:253
ABC_NAMESPACE_IMPL_START void Abc_NtkSymmetries(Abc_Ntk_t *pNtk, int fUseBdds, int fNaive, int fReorder, int fVerbose)
DECLARATIONS ///.
Definition abcSymm.c:238
void Ntk_SymFunDeriveNpn(word *pFun, int nVars, int *pComp)
Definition abcSymm.c:276
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
#define Abc_NtkForEachCo(pNtk, pCo, i)
Definition abc.h:522
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition abcNames.c:49
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
ABC_DLL void * Abc_NtkFreeGlobalBdds(Abc_Ntk_t *pNtk, int fFreeMan)
ABC_DLL void * Abc_NtkBuildGlobalBdds(Abc_Ntk_t *pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose)
ABC_DLL char ** Abc_NtkCollectCioNames(Abc_Ntk_t *pNtk, int fCollectCos)
Definition abcNames.c:285
ABC_DLL int Abc_NtkSizeOfGlobalBdds(Abc_Ntk_t *pNtk)
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_PRT(a, t)
Definition abc_global.h:255
#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
struct Extra_SymmInfo_t_ Extra_SymmInfo_t
Definition extraBdd.h:256
Extra_SymmInfo_t * Extra_SymmPairsComputeNaive(DdManager *dd, DdNode *bFunc)
Extra_SymmInfo_t * Extra_SymmPairsCompute(DdManager *dd, DdNode *bFunc)
void Extra_SymmPairsDissolve(Extra_SymmInfo_t *)
int * Extra_GreyCodeSchedule(int n)
void Extra_PrintHex(FILE *pFile, unsigned *pTruth, int nVars)
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
int Sim_ComputeTwoVarSymms(Abc_Ntk_t *pNtk, int fVerbose)
DECLARATIONS ///.
Definition simSym.c:46
typedefABC_NAMESPACE_IMPL_START struct Vec_Mem_t_ Vec_Mem_t
DECLARATIONS ///.
Definition utilMem.c:35
#define assert(ex)
Definition util_old.h:213
char * memset()