diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2010-11-28 22:30:15 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2010-11-28 22:30:15 -0800 |
commit | a17a4e5ca4d01220912fd3e85f9db2f6dc119254 (patch) | |
tree | d2b746fc725b3f51d7470762e92374cb3498860b /src/base | |
parent | 98257daa82043256cea4da4fd4bcc65d5ff130ca (diff) | |
download | abc-a17a4e5ca4d01220912fd3e85f9db2f6dc119254.tar.gz abc-a17a4e5ca4d01220912fd3e85f9db2f6dc119254.tar.bz2 abc-a17a4e5ca4d01220912fd3e85f9db2f6dc119254.zip |
NPN class computation.
Diffstat (limited to 'src/base')
-rw-r--r-- | src/base/abci/abcCut.c | 20 | ||||
-rw-r--r-- | src/base/abci/abcNpnSave.c | 739 | ||||
-rw-r--r-- | src/base/abci/module.make | 1 |
3 files changed, 752 insertions, 8 deletions
diff --git a/src/base/abci/abcCut.c b/src/base/abci/abcCut.c index e80ddb92..f8b27c32 100644 --- a/src/base/abci/abcCut.c +++ b/src/base/abci/abcCut.c @@ -122,7 +122,8 @@ void Abc_NtkCutsAddFanunt( Abc_Ntk_t * pNtk ) Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) { ProgressBar * pProgress; - Cut_Man_t * p; + Cut_Man_t * p; + Cut_Cut_t * pList; Abc_Obj_t * pObj, * pNode; Vec_Ptr_t * vNodes; Vec_Int_t * vChoices; @@ -172,7 +173,15 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) // continue; Extra_ProgressBarUpdate( pProgress, i, NULL ); // compute the cuts to the internal node - Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree ); + pList = Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree ); + if ( pParams->fNpnSave && pList ) + { + extern void Npn_ManSaveOne( unsigned * puTruth, int nVars ); + Cut_Cut_t * pCut; + for ( pCut = pList; pCut; pCut = pCut->pNext ) + if ( pCut->nLeaves >= 4 ) + Npn_ManSaveOne( Cut_CutReadTruth(pCut), pCut->nLeaves ); + } // consider dropping the fanins cuts if ( pParams->fDrop ) { @@ -193,7 +202,7 @@ Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) Vec_IntFree( vChoices ); Cut_ManPrintStats( p ); ABC_PRT( "TOTAL", clock() - clk ); - printf( "Area = %d.\n", Abc_NtkComputeArea( pNtk, p ) ); +// printf( "Area = %d.\n", Abc_NtkComputeArea( pNtk, p ) ); //Abc_NtkPrintCuts( p, pNtk, 0 ); // Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk ); @@ -428,7 +437,6 @@ void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree ) // assert( Abc_NtkIsStrash(pObj->pNtk) ); assert( Abc_ObjFaninNum(pObj) == 2 ); - // check if the node is a DAG node fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj)); // increment the counter of DAG nodes @@ -444,7 +452,6 @@ void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree ) TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1); } - // changes due to the global/local cut computation { Cut_Params_t * pParams = Cut_ManReadParams((Cut_Man_t *)p); @@ -568,9 +575,6 @@ void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq ) Cut_CutPrintList( pList, fSeq ); } - - - /**Function************************************************************* Synopsis [Assigns global attributes randomly.] diff --git a/src/base/abci/abcNpnSave.c b/src/base/abci/abcNpnSave.c new file mode 100644 index 00000000..381409de --- /dev/null +++ b/src/base/abci/abcNpnSave.c @@ -0,0 +1,739 @@ +/**CFile**************************************************************** + + FileName [abcNpnSave.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Interface with the FPGA mapping package.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - November 21, 2006.] + + Revision [$Id: abcNpnSave.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" +#include "aig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Npn_Obj_t_ Npn_Obj_t; +typedef struct Npn_Man_t_ Npn_Man_t; + +struct Npn_Obj_t_ +{ + word uTruth; // truth table + int Count; // occurances + int iNext; // next entry +}; +struct Npn_Man_t_ +{ + Npn_Obj_t * pBuffer; // all NPN entries + int * pBins; // hash table + int nBins; // hash table size + int nBufferSize; // buffer size + int nEntries; // entry count +}; + +static inline Npn_Obj_t * Npn_ManObj( Npn_Man_t * p, int i ) { assert( i < p->nBufferSize ); return i ? p->pBuffer + i : NULL; } +static inline int Npn_ManObjNum( Npn_Man_t * p, Npn_Obj_t * pObj ) { assert( p->pBuffer < pObj ); return pObj - p->pBuffer; } + +static word Truth[8] = { + 0xAAAAAAAAAAAAAAAA, + 0xCCCCCCCCCCCCCCCC, + 0xF0F0F0F0F0F0F0F0, + 0xFF00FF00FF00FF00, + 0xFFFF0000FFFF0000, + 0xFFFFFFFF00000000, + 0x0000000000000000, + 0xFFFFFFFFFFFFFFFF +}; + +static Npn_Man_t * pNpnMan = NULL; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Npn_TruthPermute_rec( char * pStr, int mid, int end ) +{ + static int count = 0; + char * pTemp = Aig_UtilStrsav(pStr); + char e; + int i; + if ( mid == end ) + { + printf( "%03d: %s\n", count++, pTemp ); + return ; + } + for ( i = mid; i <= end; i++ ) + { + e = pTemp[mid]; + pTemp[mid] = pTemp[i]; + pTemp[i] = e; + + Npn_TruthPermute_rec( pTemp, mid + 1, end ); + + e = pTemp[mid]; + pTemp[mid] = pTemp[i]; + pTemp[i] = e; + } + ABC_FREE( pTemp ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Npn_TruthHasVar( word t, int v ) +{ + return ((t & Truth[v]) >> (1<<v)) != (t & ~Truth[v]); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Npn_TruthSupport( word t ) +{ + int v, Supp = 0; + for ( v = 0; v < 6; v++ ) + if ( Npn_TruthHasVar( t, v ) ) + Supp |= (1 << v); + return Supp; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Npn_TruthSuppSize( word t, int nVars ) +{ + int v, nSupp = 0; + assert( nVars <= 6 ); + for ( v = 0; v < nVars; v++ ) + if ( Npn_TruthHasVar( t, v ) ) + nSupp++; + return nSupp; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Npn_TruthIsMinBase( word t ) +{ + int Supp = Npn_TruthSupport(t); + return (Supp & (Supp+1)) == 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word Npn_TruthPadWord( word uTruth, int nVars ) +{ + if ( nVars == 6 ) + return uTruth; + if ( nVars <= 5 ) + uTruth = ((uTruth & 0x00000000FFFFFFFF) << 32) | (uTruth & 0x00000000FFFFFFFF); + if ( nVars <= 4 ) + uTruth = ((uTruth & 0x0000FFFF0000FFFF) << 16) | (uTruth & 0x0000FFFF0000FFFF); + if ( nVars <= 3 ) + uTruth = ((uTruth & 0x00FF00FF00FF00FF) << 8) | (uTruth & 0x00FF00FF00FF00FF); + if ( nVars <= 2 ) + uTruth = ((uTruth & 0x0F0F0F0F0F0F0F0F) << 4) | (uTruth & 0x0F0F0F0F0F0F0F0F); + if ( nVars <= 1 ) + uTruth = ((uTruth & 0x3333333333333333) << 2) | (uTruth & 0x3333333333333333); + if ( nVars == 0 ) + uTruth = ((uTruth & 0x5555555555555555) << 1) | (uTruth & 0x5555555555555555); + return uTruth; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Npn_TruthCountOnes( word t ) +{ + t = (t & 0x5555555555555555) + ((t>> 1) & 0x5555555555555555); + t = (t & 0x3333333333333333) + ((t>> 2) & 0x3333333333333333); + t = (t & 0x0F0F0F0F0F0F0F0F) + ((t>> 4) & 0x0F0F0F0F0F0F0F0F); + t = (t & 0x00FF00FF00FF00FF) + ((t>> 8) & 0x00FF00FF00FF00FF); + t = (t & 0x0000FFFF0000FFFF) + ((t>>16) & 0x0000FFFF0000FFFF); + return (t & 0x00000000FFFFFFFF) + (t>>32); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word Npn_TruthChangePhase( word t, int v ) +{ + return ((t & Truth[v]) >> (1<<v)) | ((t & ~Truth[v]) << (1<<v)); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word Npn_TruthSwapAdjacentVars( word t, int v ) +{ + static word PMasks[5][3] = { + { 0x9999999999999999, 0x2222222222222222, 0x4444444444444444 }, + { 0xC3C3C3C3C3C3C3C3, 0x0C0C0C0C0C0C0C0C, 0x3030303030303030 }, + { 0xF00FF00FF00FF00F, 0x00F000F000F000F0, 0x0F000F000F000F00 }, + { 0xFF0000FFFF0000FF, 0x0000FF000000FF00, 0x00FF000000FF0000 }, + { 0xFFFF00000000FFFF, 0x00000000FFFF0000, 0x0000FFFF00000000 } + }; + assert( v < 6 ); + return (t & PMasks[v][0]) | ((t & PMasks[v][1]) << (1 << v)) | ((t & PMasks[v][2]) >> (1 << v)); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word Npn_TruthCanon( word t, int nVars, int * pPhase ) +{ + int fUsePolarity = 0; + int fUsePermutation = 0; + char Temp, pSigs[13], pCanonPerm[6]; + int v, fChange, CanonPhase = 0; + assert( nVars < 7 ); + pSigs[12] = Npn_TruthCountOnes( t ); + if ( pSigs[12] > 32 ) + { + t = ~t; + pSigs[12] = 64 - pSigs[12]; + CanonPhase |= (1 << 6); + } + if ( fUsePolarity || fUsePermutation ) + { + for ( v = 0; v < nVars; v++ ) + { + pCanonPerm[v] = v; + pSigs[2*v+1] = Npn_TruthCountOnes( t & Truth[v] ); + pSigs[2*v] = pSigs[12] - pSigs[2*v+1]; + } + } + if ( fUsePolarity ) + { + for ( v = 0; v < nVars; v++ ) + { + if ( pSigs[2*v] >= pSigs[2*v+1] ) + continue; + CanonPhase |= (1 << v); + Temp = pSigs[2*v]; + pSigs[2*v] = pSigs[2*v+1]; + pSigs[2*v+1] = Temp; + t = Npn_TruthChangePhase( t, v ); + } + } + if ( fUsePermutation ) + { + do { + fChange = 0; + for ( v = 0; v < nVars-1; v++ ) + { + if ( fUsePolarity ) + { + if ( pSigs[2*v] >= pSigs[2*(v+1)] ) + continue; + } + else + { + if ( ABC_MIN(pSigs[2*v],pSigs[2*v+1]) >= ABC_MIN(pSigs[2*(v+1)],pSigs[2*(v+1)+1]) ) + continue; + } + fChange = 1; + + Temp = pCanonPerm[v]; + pCanonPerm[v] = pCanonPerm[v+1]; + pCanonPerm[v+1] = Temp; + + Temp = pSigs[2*v]; + pSigs[2*v] = pSigs[2*(v+1)]; + pSigs[2*(v+1)] = Temp; + + Temp = pSigs[2*v+1]; + pSigs[2*v+1] = pSigs[2*(v+1)+1]; + pSigs[2*(v+1)+1] = Temp; + + t = Npn_TruthSwapAdjacentVars( t, v ); + } + } while ( fChange ); + } + if ( pPhase ) + { + *pPhase = 0; + for ( v = 0; v < nVars; v++ ) + *pPhase |= (pCanonPerm[v] << (4 * v)); + *pPhase |= (CanonPhase << 24); + } + return t; +} + + +/**Function************************************************************* + + Synopsis [Computes the hash key.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Npn_ManHash( Npn_Man_t * p, word uTruth ) +{ + word Key = (uTruth * (word)101) ^ (uTruth * (word)733) ^ (uTruth * (word)1777); + return (int)(Key % (word)p->nBins); +} + +/**Function************************************************************* + + Synopsis [Resizes the table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Npn_ManResize( Npn_Man_t * p ) +{ + Npn_Obj_t * pEntry, * pNext; + int * pBinsOld, * ppPlace; + int nBinsOld, Counter, i, clk; + assert( p->pBins != NULL ); +clk = clock(); + // save the old Bins + pBinsOld = p->pBins; + nBinsOld = p->nBins; + // get the new Bins + p->nBins = Aig_PrimeCudd( 3 * nBinsOld ); + p->pBins = ABC_CALLOC( int, p->nBins ); + // rehash the entries from the old table + Counter = 1; + for ( i = 0; i < nBinsOld; i++ ) + for ( pEntry = Npn_ManObj(p, pBinsOld[i]), + pNext = pEntry ? Npn_ManObj(p, pEntry->iNext) : NULL; + pEntry; + pEntry = pNext, + pNext = pEntry ? Npn_ManObj(p, pEntry->iNext) : NULL ) + { + // get the place where this entry goes + ppPlace = p->pBins + Npn_ManHash( p, pEntry->uTruth ); + // add the entry to the list + pEntry->iNext = *ppPlace; + *ppPlace = Npn_ManObjNum( p, pEntry ); + Counter++; + } + assert( Counter == p->nEntries ); + ABC_FREE( pBinsOld ); +//ABC_PRT( "Hash table resizing time", clock() - clk ); +} + +/**Function************************************************************* + + Synopsis [Adds one entry to the table.] + + Description [Increments ref counter by 1.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Npn_Obj_t * Npn_ManAdd( Npn_Man_t * p, word uTruth ) +{ + Npn_Obj_t * pEntry; + int * pPlace, Key = Npn_ManHash( p, uTruth ); + // resize the link storage if needed + if ( p->nEntries == p->nBufferSize ) + { + p->nBufferSize *= 2; + p->pBuffer = ABC_REALLOC( Npn_Obj_t, p->pBuffer, p->nBufferSize ); + } + // find the entry + for ( pEntry = Npn_ManObj(p, p->pBins[Key]), + pPlace = p->pBins + Key; + pEntry; + pPlace = &pEntry->iNext, + pEntry = Npn_ManObj(p, pEntry->iNext) ) + if ( pEntry->uTruth == uTruth ) + { + pEntry->Count++; + return pEntry; + } + // create new entry + *pPlace = p->nEntries; + assert( p->nEntries < p->nBufferSize ); + pEntry = Npn_ManObj( p, p->nEntries++ ); + pEntry->uTruth = uTruth; + pEntry->Count = 1; + pEntry->iNext = 0; + // resize the table if needed + if ( p->nEntries > 3 * p->nBins ) + Npn_ManResize( p ); + return pEntry; +} + +/**Function************************************************************* + + Synopsis [Fills table from file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Npn_ManRead( Npn_Man_t * p, char * pFileName ) +{ + char pBuffer[1000]; + char * pToken; + Npn_Obj_t * pEntry; + unsigned Truth[2]; + word uTruth; + FILE * pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + Abc_Print( -1, "Cannot open NPN function file \"%s\".\n", pFileName ); + return; + } + // read lines from the file + while ( fgets( pBuffer, 1000, pFile ) != NULL ) + { + pToken = strtok( pBuffer, " \t\n" ); + if ( pToken == NULL ) + continue; + if ( pToken[0] == '#' ) + continue; + if ( strlen(pToken) != 16 ) + { + Abc_Print( 0, "Skipping token %s that does not look like a 16-digit hex number.\n" ); + continue; + } + // extract truth table + Extra_ReadHexadecimal( Truth, pToken, 6 ); + uTruth = (((word)Truth[1]) << 32) | (word)Truth[0]; + // add truth table + pEntry = Npn_ManAdd( p, uTruth ); + assert( pEntry->Count == 1 ); + // read area + pToken = strtok( NULL, " \t\n" ); + pEntry->Count = atoi(pToken); + } + fclose( pFile ); +} + +/**Function************************************************************* + + Synopsis [Comparison procedure for two entries.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int Npn_ManCompareEntries( Npn_Obj_t ** pp1, Npn_Obj_t ** pp2 ) +{ + if ( (*pp1)->Count > (*pp2)->Count ) + return -1; + if ( (*pp1)->Count < (*pp2)->Count ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Adds one entry to the table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Npn_ManWrite( Npn_Man_t * p, char * pFileName ) +{ + Vec_Ptr_t * vEntries; + Npn_Obj_t * pEntry; + FILE * pFile = fopen( pFileName, "w" ); + int i; + if ( pFile == NULL ) + { + Abc_Print( -1, "Cannot open NPN function file \"%s\".\n", pFileName ); + return; + } + vEntries = Vec_PtrAlloc( p->nEntries ); + for ( i = 0; i < p->nBins; i++ ) + for ( pEntry = Npn_ManObj(p, p->pBins[i]); pEntry; pEntry = Npn_ManObj(p, pEntry->iNext) ) + Vec_PtrPush( vEntries, pEntry ); + Vec_PtrSort( vEntries, (int (*)())Npn_ManCompareEntries ); + Vec_PtrForEachEntry( Npn_Obj_t *, vEntries, pEntry, i ) + { + Extra_PrintHexadecimal( pFile, (unsigned *)&pEntry->uTruth, 6 ); + fprintf( pFile, " %d %d\n", pEntry->Count, Npn_TruthSuppSize(pEntry->uTruth, 6) ); + } + fclose( pFile ); + Vec_PtrFree( vEntries ); +} + +/**Function************************************************************* + + Synopsis [Creates the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Npn_Man_t * Npn_ManStart( char * pFileName ) +{ + Npn_Man_t * p; + p = ABC_CALLOC( Npn_Man_t, 1 ); + if ( pFileName == NULL ) + { + p->nBufferSize = 1000000; + p->nBufferSize = 100; + p->pBuffer = ABC_ALLOC( Npn_Obj_t, p->nBufferSize ); + p->nBins = Aig_PrimeCudd( p->nBufferSize / 2 ); + p->pBins = ABC_CALLOC( int, p->nBins ); + p->nEntries = 1; + } + else + { + FILE * pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + Abc_Print( -1, "Cannot open NPN function file \"%s\".\n", pFileName ); + return NULL; + } + fclose( pFile ); + p->nBufferSize = 4 * ( Extra_FileSize(pFileName) / 20 ); + p->pBuffer = ABC_ALLOC( Npn_Obj_t, p->nBufferSize ); + p->nBins = Aig_PrimeCudd( p->nBufferSize / 2 ); + p->pBins = ABC_CALLOC( int, p->nBins ); + p->nEntries = 1; + Npn_ManRead( p, pFileName ); + } + return p; +} + +/**Function************************************************************* + + Synopsis [Deletes the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Npn_ManStop( Npn_Man_t * p ) +{ + ABC_FREE( p->pBuffer ); + ABC_FREE( p->pBins ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Cleans the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Npn_ManClean() +{ + if ( pNpnMan != NULL ) + { + Npn_ManStop( pNpnMan ); + pNpnMan = NULL; + } +} + +/**Function************************************************************* + + Synopsis [Loads functions from a file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Npn_ManLoad( char * pFileName ) +{ +// Npn_TruthPermute_rec( "012345", 0, 5 ); + if ( pNpnMan != NULL ) + { + Abc_Print( 1, "Removing old table with %d entries.\n", pNpnMan->nEntries ); + Npn_ManStop( pNpnMan ); + } + pNpnMan = Npn_ManStart( pFileName ); + Abc_Print( 1, "Created new table with %d entries from file \"%s\".\n", pNpnMan->nEntries, pFileName ); +} + +/**Function************************************************************* + + Synopsis [Saves functions into a file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Npn_ManSave( char * pFileName ) +{ + if ( pNpnMan == NULL ) + { + Abc_Print( 1, "There is no table with entries.\n" ); + return; + } + Npn_ManWrite( pNpnMan, pFileName ); + Abc_Print( 1, "Dumped table with %d entries from file \"%s\".\n", pNpnMan->nEntries, pFileName ); +} + +/**Function************************************************************* + + Synopsis [Saves one function into storage.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Npn_ManSaveOne( unsigned * puTruth, int nVars ) +{ + word uTruth = (((word)puTruth[1]) << 32) | (word)puTruth[0]; + assert( nVars >= 0 && nVars <= 6 ); + if ( pNpnMan == NULL ) + { + Abc_Print( 1, "Creating new table with 0 entries.\n" ); + pNpnMan = Npn_ManStart( NULL ); + } + // skip truth tables that do not depend on some vars + if ( !Npn_TruthIsMinBase( uTruth ) ) + return; + // extend truth table to look like 6-input + uTruth = Npn_TruthPadWord( uTruth, nVars ); + // semi(!)-NPN-canonize the truth table + uTruth = Npn_TruthCanon( uTruth, 6, NULL ); + // add to storage + Npn_ManAdd( pNpnMan, uTruth ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/abci/module.make b/src/base/abci/module.make index b9342881..b0223330 100644 --- a/src/base/abci/module.make +++ b/src/base/abci/module.make @@ -34,6 +34,7 @@ SRC += src/base/abci/abc.c \ src/base/abci/abcMiter.c \ src/base/abci/abcMulti.c \ src/base/abci/abcNtbdd.c \ + src/base/abci/abcNpnSave.c \ src/base/abci/abcOdc.c \ src/base/abci/abcOrder.c \ src/base/abci/abcPart.c \ |