00001
00021 #include "abc.h"
00022 #include "main.h"
00023 #include "mio.h"
00024
00028
00029 #define ATTACH_FULL (~((unsigned)0))
00030 #define ATTACH_MASK(n) ((~((unsigned)0)) >> (32-(n)))
00031
00032 static void Abc_AttachSetupTruthTables( unsigned uTruths[][2] );
00033 static void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthNode );
00034 static Mio_Gate_t * Abc_AttachFind( Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned * uTruthNode, int * Perm );
00035 static int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode );
00036 static int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] );
00037 static void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm );
00038
00039 static char ** s_pPerms = NULL;
00040 static int s_nPerms;
00041
00045
00057 int Abc_NtkAttach( Abc_Ntk_t * pNtk )
00058 {
00059 Mio_Library_t * pGenlib;
00060 unsigned ** puTruthGates;
00061 unsigned uTruths[6][2];
00062 Abc_Obj_t * pNode;
00063 Mio_Gate_t ** ppGates;
00064 int nGates, nFanins, i;
00065
00066 assert( Abc_NtkIsSopLogic(pNtk) );
00067
00068
00069 pGenlib = Abc_FrameReadLibGen();
00070 if ( pGenlib == NULL )
00071 {
00072 printf( "The current library is not available.\n" );
00073 return 0;
00074 }
00075
00076
00077 Abc_AttachSetupTruthTables( uTruths );
00078
00079
00080 ppGates = Mio_CollectRoots( pGenlib, 6, (float)1.0e+20, 1, &nGates );
00081
00082
00083 puTruthGates = ALLOC( unsigned *, nGates );
00084 puTruthGates[0] = ALLOC( unsigned, 2 * nGates );
00085 for ( i = 1; i < nGates; i++ )
00086 puTruthGates[i] = puTruthGates[i-1] + 2;
00087 for ( i = 0; i < nGates; i++ )
00088 Mio_DeriveTruthTable( ppGates[i], uTruths, Mio_GateReadInputs(ppGates[i]), 6, puTruthGates[i] );
00089
00090
00091 Abc_NtkCleanCopy( pNtk );
00092 Abc_NtkForEachNode( pNtk, pNode, i )
00093 {
00094 nFanins = Abc_ObjFaninNum(pNode);
00095 if ( nFanins == 0 )
00096 {
00097 if ( Abc_SopIsConst1(pNode->pData) )
00098 pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst1(pGenlib);
00099 else
00100 pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadConst0(pGenlib);
00101 }
00102 else if ( nFanins == 1 )
00103 {
00104 if ( Abc_SopIsBuf(pNode->pData) )
00105 pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadBuf(pGenlib);
00106 else
00107 pNode->pCopy = (Abc_Obj_t *)Mio_LibraryReadInv(pGenlib);
00108 }
00109 else if ( nFanins > 6 )
00110 {
00111 printf( "Cannot attach gate with more than 6 inputs to node %s.\n", Abc_ObjName(pNode) );
00112 free( puTruthGates[0] );
00113 free( puTruthGates );
00114 free( ppGates );
00115 return 0;
00116 }
00117 else if ( !Abc_NodeAttach( pNode, ppGates, puTruthGates, nGates, uTruths ) )
00118 {
00119 printf( "Could not attach the library gate to node %s.\n", Abc_ObjName(pNode) );
00120 free( puTruthGates[0] );
00121 free( puTruthGates );
00122 free( ppGates );
00123 return 0;
00124 }
00125 }
00126 free( puTruthGates[0] );
00127 free( puTruthGates );
00128 free( ppGates );
00129 FREE( s_pPerms );
00130
00131
00132 Abc_NtkForEachNode( pNtk, pNode, i )
00133 {
00134 if ( pNode->pCopy == NULL )
00135 {
00136 printf( "Some elementary gates (constant, buffer, or inverter) are missing in the library.\n" );
00137 return 0;
00138 }
00139 }
00140
00141
00142 Abc_NtkForEachNode( pNtk, pNode, i )
00143 pNode->pData = pNode->pCopy, pNode->pCopy = NULL;
00144 pNtk->ntkFunc = ABC_FUNC_MAP;
00145 Extra_MmFlexStop( pNtk->pManFunc );
00146 pNtk->pManFunc = pGenlib;
00147
00148 printf( "Library gates are successfully attached to the nodes.\n" );
00149
00150
00151 if ( !Abc_NtkCheck( pNtk ) )
00152 {
00153 printf( "Abc_NtkAttach: The network check has failed.\n" );
00154 return 0;
00155 }
00156 return 1;
00157 }
00158
00170 int Abc_NodeAttach( Abc_Obj_t * pNode, Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned uTruths[][2] )
00171 {
00172 int Perm[10];
00173 int pTempInts[10];
00174 unsigned uTruthNode[2];
00175 Abc_Obj_t * pFanin;
00176 Mio_Gate_t * pGate;
00177 int nFanins, i;
00178
00179
00180 Abc_AttachComputeTruth( pNode->pData, uTruths, uTruthNode );
00181
00182 pGate = Abc_AttachFind( ppGates, puTruthGates, nGates, uTruthNode, Perm );
00183 if ( pGate == NULL )
00184 return 0;
00185
00186 nFanins = Abc_ObjFaninNum(pNode);
00187 Abc_ObjForEachFanin( pNode, pFanin, i )
00188 pTempInts[i] = pFanin->Id;
00189 for ( i = 0; i < nFanins; i++ )
00190 pNode->vFanins.pArray[Perm[i]] = pTempInts[i];
00191
00192 pNode->pCopy = (Abc_Obj_t *)pGate;
00193 return 1;
00194 }
00195
00207 void Abc_AttachSetupTruthTables( unsigned uTruths[][2] )
00208 {
00209 int m, v;
00210 for ( v = 0; v < 5; v++ )
00211 uTruths[v][0] = 0;
00212
00213 for ( m = 0; m < 32; m++ )
00214 for ( v = 0; v < 5; v++ )
00215 if ( m & (1 << v) )
00216 uTruths[v][0] |= (1 << m);
00217
00218 for ( v = 0; v < 5; v++ )
00219 uTruths[v][1] = uTruths[v][0];
00220 uTruths[5][0] = 0;
00221 uTruths[5][1] = ATTACH_FULL;
00222 }
00223
00235 void Abc_AttachComputeTruth( char * pSop, unsigned uTruthsIn[][2], unsigned * uTruthRes )
00236 {
00237
00238 unsigned uSignCube[2];
00239 int Value;
00240
00241 int nInputs = 6;
00242 int nFanins = Abc_SopGetVarNum(pSop);
00243 char * pCube;
00244 int k;
00245
00246
00247 assert( nInputs < 7 );
00248
00249
00250 uTruthRes[0] = 0;
00251 uTruthRes[1] = 0;
00252 if ( nInputs < 6 )
00253 {
00254
00255
00256 Abc_SopForEachCube( pSop, nFanins, pCube )
00257 {
00258 uSignCube[0] = ATTACH_FULL;
00259
00260 Abc_CubeForEachVar( pCube, Value, k )
00261 {
00262 if ( Value == '0' )
00263 uSignCube[0] &= ~uTruthsIn[k][0];
00264 else if ( Value == '1' )
00265 uSignCube[0] &= uTruthsIn[k][0];
00266 }
00267 uTruthRes[0] |= uSignCube[0];
00268 }
00269 if ( Abc_SopGetPhase(pSop) == 0 )
00270 uTruthRes[0] = ~uTruthRes[0];
00271 if ( nInputs < 5 )
00272 uTruthRes[0] &= ATTACH_MASK(1<<nInputs);
00273 }
00274 else
00275 {
00276
00277
00278 Abc_SopForEachCube( pSop, nFanins, pCube )
00279 {
00280 uSignCube[0] = ATTACH_FULL;
00281 uSignCube[1] = ATTACH_FULL;
00282
00283 Abc_CubeForEachVar( pCube, Value, k )
00284 {
00285 if ( Value == '0' )
00286 {
00287 uSignCube[0] &= ~uTruthsIn[k][0];
00288 uSignCube[1] &= ~uTruthsIn[k][1];
00289 }
00290 else if ( Value == '1' )
00291 {
00292 uSignCube[0] &= uTruthsIn[k][0];
00293 uSignCube[1] &= uTruthsIn[k][1];
00294 }
00295 }
00296 uTruthRes[0] |= uSignCube[0];
00297 uTruthRes[1] |= uSignCube[1];
00298 }
00299
00300
00301 if ( Abc_SopGetPhase(pSop) == 0 )
00302 {
00303 uTruthRes[0] = ~uTruthRes[0];
00304 uTruthRes[1] = ~uTruthRes[1];
00305 }
00306 }
00307 }
00308
00320 Mio_Gate_t * Abc_AttachFind( Mio_Gate_t ** ppGates, unsigned ** puTruthGates, int nGates, unsigned * uTruthNode, int * Perm )
00321 {
00322 unsigned uTruthPerm[2];
00323 int i, v, iNum;
00324
00325
00326 if ( (iNum = Abc_AttachCompare( puTruthGates, nGates, uTruthNode )) >= 0 )
00327 {
00328 for ( v = 0; v < 6; v++ )
00329 Perm[v] = v;
00330 return ppGates[iNum];
00331 }
00332
00333 if ( s_pPerms == NULL )
00334 {
00335 s_pPerms = Extra_Permutations( 6 );
00336 s_nPerms = Extra_Factorial( 6 );
00337 }
00338
00339 for ( i = 0; i < s_nPerms; i++ )
00340 {
00341 Abc_TruthPermute( s_pPerms[i], 6, uTruthNode, uTruthPerm );
00342 if ( (iNum = Abc_AttachCompare( puTruthGates, nGates, uTruthPerm )) >= 0 )
00343 {
00344 for ( v = 0; v < 6; v++ )
00345 Perm[v] = (int)s_pPerms[i][v];
00346 return ppGates[iNum];
00347 }
00348 }
00349 return NULL;
00350 }
00351
00363 int Abc_AttachCompare( unsigned ** puTruthGates, int nGates, unsigned * uTruthNode )
00364 {
00365 int i;
00366 for ( i = 0; i < nGates; i++ )
00367 if ( puTruthGates[i][0] == uTruthNode[0] && puTruthGates[i][1] == uTruthNode[1] )
00368 return i;
00369 return -1;
00370 }
00371
00383 void Abc_TruthPermute( char * pPerm, int nVars, unsigned * uTruthNode, unsigned * uTruthPerm )
00384 {
00385 int nMints, iMintPerm, iMint, v;
00386 uTruthPerm[0] = uTruthPerm[1] = 0;
00387 nMints = (1 << nVars);
00388 for ( iMint = 0; iMint < nMints; iMint++ )
00389 {
00390 if ( (uTruthNode[iMint>>5] & (1 << (iMint&31))) == 0 )
00391 continue;
00392 iMintPerm = 0;
00393 for ( v = 0; v < nVars; v++ )
00394 if ( iMint & (1 << v) )
00395 iMintPerm |= (1 << pPerm[v]);
00396 uTruthPerm[iMintPerm>>5] |= (1 << (iMintPerm&31));
00397 }
00398 }
00399
00403
00404