| /**CFile**************************************************************** |
| |
| FileName [plaSimple.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [SOP manager.] |
| |
| Synopsis [Scalable SOP transformations.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - March 18, 2015.] |
| |
| Revision [$Id: plaSimple.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "pla.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Dump PLA manager into a BLIF file.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Pla_ManDumpPla( Pla_Man_t * p, char * pFileName ) |
| { |
| // find the number of original variables |
| //int nVarsInit = Pla_ManDivNum(p) ? Vec_IntCountZero(&p->vDivs) : Pla_ManInNum(p); |
| FILE * pFile = fopen( pFileName, "wb" ); |
| if ( pFile == NULL ) |
| printf( "Cannot open file \"%s\" for writing.\n", pFileName ); |
| else |
| { |
| //char * pLits = "-01?"; |
| Vec_Str_t * vStr; |
| Vec_Int_t * vCube; |
| int i, k, Lit; |
| // comment |
| fprintf( pFile, "# PLA file written via PLA package in ABC on " ); |
| fprintf( pFile, "%s", Extra_TimeStamp() ); |
| fprintf( pFile, "\n\n" ); |
| // header |
| fprintf( pFile, ".i %d\n", Pla_ManInNum(p) ); |
| fprintf( pFile, ".o %d\n", 1 ); |
| fprintf( pFile, ".p %d\n", Vec_WecSize(&p->vCubeLits) ); |
| // SOP |
| vStr = Vec_StrStart( Pla_ManInNum(p) + 1 ); |
| Vec_WecForEachLevel( &p->vCubeLits, vCube, i ) |
| { |
| if ( !Vec_IntSize(vCube) ) |
| continue; |
| for ( k = 0; k < Pla_ManInNum(p); k++ ) |
| Vec_StrWriteEntry( vStr, k, '-' ); |
| Vec_IntForEachEntry( vCube, Lit, k ) |
| Vec_StrWriteEntry( vStr, Abc_Lit2Var(Lit), (char)(Abc_LitIsCompl(Lit) ? '0' : '1') ); |
| fprintf( pFile, "%s 1\n", Vec_StrArray(vStr) ); |
| } |
| Vec_StrFree( vStr ); |
| fprintf( pFile, ".e\n\n" ); |
| fclose( pFile ); |
| printf( "Written file \"%s\".\n", pFileName ); |
| } |
| } |
| void Pla_ManDumpBlif( Pla_Man_t * p, char * pFileName ) |
| { |
| // find the number of original variables |
| int nVarsInit = Pla_ManDivNum(p) ? Vec_IntCountZero(&p->vDivs) : Pla_ManInNum(p); |
| FILE * pFile = fopen( pFileName, "wb" ); |
| if ( pFile == NULL ) |
| printf( "Cannot open file \"%s\" for writing.\n", pFileName ); |
| else |
| { |
| //char * pLits = "-01?"; |
| Vec_Str_t * vStr; |
| Vec_Int_t * vCube; |
| int i, k, Lit, Div; |
| // comment |
| fprintf( pFile, "# BLIF file written via PLA package in ABC on " ); |
| fprintf( pFile, "%s", Extra_TimeStamp() ); |
| fprintf( pFile, "\n\n" ); |
| // header |
| fprintf( pFile, ".model %s\n", Pla_ManName(p) ); |
| fprintf( pFile, ".inputs" ); |
| for ( i = 0; i < nVarsInit; i++ ) |
| fprintf( pFile, " i%d", i ); |
| fprintf( pFile, "\n" ); |
| fprintf( pFile, ".outputs o" ); |
| fprintf( pFile, "\n" ); |
| // SOP |
| fprintf( pFile, ".names" ); |
| for ( i = 0; i < Pla_ManInNum(p); i++ ) |
| fprintf( pFile, " i%d", i ); |
| fprintf( pFile, " o\n" ); |
| vStr = Vec_StrStart( Pla_ManInNum(p) + 1 ); |
| Vec_WecForEachLevel( &p->vCubeLits, vCube, i ) |
| { |
| for ( k = 0; k < Pla_ManInNum(p); k++ ) |
| Vec_StrWriteEntry( vStr, k, '-' ); |
| Vec_IntForEachEntry( vCube, Lit, k ) |
| Vec_StrWriteEntry( vStr, Abc_Lit2Var(Lit), (char)(Abc_LitIsCompl(Lit) ? '0' : '1') ); |
| fprintf( pFile, "%s 1\n", Vec_StrArray(vStr) ); |
| } |
| Vec_StrFree( vStr ); |
| // divisors |
| Vec_IntForEachEntryStart( &p->vDivs, Div, i, nVarsInit ) |
| { |
| int pLits[3] = { (Div >> 2) & 0x3FF, (Div >> 12) & 0x3FF, (Div >> 22) & 0x3FF }; |
| fprintf( pFile, ".names" ); |
| fprintf( pFile, " i%d", Abc_Lit2Var(pLits[0]) ); |
| fprintf( pFile, " i%d", Abc_Lit2Var(pLits[1]) ); |
| if ( (Div & 3) == 3 ) // MUX |
| fprintf( pFile, " i%d", Abc_Lit2Var(pLits[2]) ); |
| fprintf( pFile, " i%d\n", i ); |
| if ( (Div & 3) == 1 ) // AND |
| fprintf( pFile, "%d%d 1\n", !Abc_LitIsCompl(pLits[0]), !Abc_LitIsCompl(pLits[1]) ); |
| else if ( (Div & 3) == 2 ) // XOR |
| { |
| assert( !Abc_LitIsCompl(pLits[0]) ); |
| assert( !Abc_LitIsCompl(pLits[1]) ); |
| fprintf( pFile, "10 1\n01 1\n" ); |
| } |
| else if ( (Div & 3) == 3 ) // MUX |
| { |
| assert( !Abc_LitIsCompl(pLits[1]) ); |
| assert( !Abc_LitIsCompl(pLits[2]) ); |
| fprintf( pFile, "%d-0 1\n-11 1\n", !Abc_LitIsCompl(pLits[0]) ); |
| } |
| else assert( 0 ); |
| } |
| fprintf( pFile, ".end\n\n" ); |
| fclose( pFile ); |
| printf( "Written file \"%s\".\n", pFileName ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Transforms truth table into an SOP manager.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Pla_ManExpendDirNum( word * pOn, int nBits, int iMint, int * pVars ) |
| { |
| int v, nVars = 0; |
| for ( v = 0; v < nBits; v++ ) |
| if ( Pla_TtGetBit(pOn, iMint ^ (1 << v)) ) |
| pVars[nVars++] = v; |
| return nVars; |
| } |
| void Pla_PrintBinary( word * pT, int nBits ) |
| { |
| int v; |
| for ( v = 0; v < nBits; v++ ) |
| printf( "%d", Pla_TtGetBit(pT, v) ); |
| printf( "\n" ); |
| } |
| Vec_Wrd_t * Pla_ManFxMinimize( word * pOn, int nVars ) |
| { |
| int i, v, iMint, iVar, nMints = (1 << nVars); |
| int nWords = Abc_Bit6WordNum( nMints ); |
| Vec_Wrd_t * vCubes = Vec_WrdAlloc( 1000 ); |
| word * pDc = ABC_CALLOC( word, nWords ); |
| int Count[32] = {0}; |
| int Cubes[32] = {0}; |
| Vec_Int_t * vStore = Vec_IntAlloc( 1000 ); |
| |
| // count the number of expansion directions |
| for ( i = 0; i < nMints; i++ ) |
| if ( Pla_TtGetBit(pOn, i) && !Pla_TtGetBit(pDc, i) ) |
| { |
| int pDirs[32], nDirs = Pla_ManExpendDirNum(pOn, nVars, i, pDirs); |
| Count[nDirs]++; |
| if ( nDirs == 0 ) |
| { |
| Pla_TtSetBit(pDc, i); |
| Cubes[0]++; |
| // save |
| Vec_IntPushTwo( vStore, i, -1 ); |
| continue; |
| } |
| if ( nDirs == 1 ) |
| { |
| //Pla_PrintBinary( (word *)&i, nVars ); |
| //printf( " %d \n", pDirs[0] ); |
| |
| Pla_TtSetBit(pDc, i); |
| Pla_TtSetBit(pDc, i ^ (1 << pDirs[0])); |
| Cubes[1]++; |
| // save |
| Vec_IntPushTwo( vStore, i, pDirs[0] ); |
| continue; |
| } |
| if ( nDirs == 2 && Pla_TtGetBit(pOn, i ^ (1 << pDirs[0]) ^ (1 << pDirs[1])) ) |
| { |
| assert( 0 ); |
| Pla_TtSetBit(pDc, i); |
| Pla_TtSetBit(pDc, i ^ (1 << pDirs[0])); |
| Pla_TtSetBit(pDc, i ^ (1 << pDirs[1])); |
| Pla_TtSetBit(pDc, i ^ (1 << pDirs[0]) ^ (1 << pDirs[1])); |
| Cubes[2]++; |
| continue; |
| } |
| } |
| |
| // go through the remaining cubes |
| for ( i = 0; i < nMints; i++ ) |
| if ( Pla_TtGetBit(pOn, i) && !Pla_TtGetBit(pDc, i) ) |
| { |
| int pDirs[32], nDirs = Pla_ManExpendDirNum(pOn, nVars, i, pDirs); |
| // find direction, which is not taken |
| for ( v = 0; v < nDirs; v++ ) |
| if ( Pla_TtGetBit(pOn, i ^ (1 << pDirs[v])) && !Pla_TtGetBit(pDc, i ^ (1 << pDirs[v])) ) |
| break; |
| // if there is no open directions, use any one |
| if ( v == nDirs ) |
| v = 0; |
| // mark this one |
| Pla_TtSetBit(pDc, i); |
| Pla_TtSetBit(pDc, i ^ (1 << pDirs[v])); |
| Cubes[10]++; |
| // save |
| Vec_IntPushTwo( vStore, i, pDirs[v] ); |
| continue; |
| } |
| |
| printf( "\n" ); |
| printf( "Truth = %d. ", Pla_TtCountOnes(pOn, nWords) ); |
| printf( "Cover = %d. ", Pla_TtCountOnes(pDc, nWords) ); |
| printf( "\n" ); |
| |
| printf( "Count: " ); |
| for ( i = 0; i < 16; i++ ) |
| if ( Count[i] ) |
| printf( "%d=%d ", i, Count[i] ); |
| printf( "\n" ); |
| |
| printf( "Cubes: " ); |
| for ( i = 0; i < 16; i++ ) |
| if ( Cubes[i] ) |
| printf( "%d=%d ", i, Cubes[i] ); |
| printf( "\n" ); |
| |
| /* |
| // extract cubes one at a time |
| for ( i = 0; i < nMints; i++ ) |
| if ( Pla_TtGetBit(pOn, i) ) |
| { |
| word Cube = 0; |
| for ( v = 0; v < nVars; v++ ) |
| if ( (i >> v) & 1 ) |
| Pla_CubeSetLit( &Cube, v, PLA_LIT_ONE ); |
| else |
| Pla_CubeSetLit( &Cube, v, PLA_LIT_ZERO ); |
| Vec_WrdPush( vCubes, Cube ); |
| } |
| */ |
| Vec_IntForEachEntryDouble( vStore, iMint, iVar, i ) |
| { |
| word Cube = 0; |
| for ( v = 0; v < nVars; v++ ) |
| { |
| if ( v == iVar ) |
| continue; |
| if ( (iMint >> v) & 1 ) |
| Pla_CubeSetLit( &Cube, v, PLA_LIT_ONE ); |
| else |
| Pla_CubeSetLit( &Cube, v, PLA_LIT_ZERO ); |
| } |
| Vec_WrdPush( vCubes, Cube ); |
| } |
| Vec_IntFree( vStore ); |
| |
| // collect the minterms |
| ABC_FREE( pDc ); |
| return vCubes; |
| } |
| Pla_Man_t * Pla_ManFxPrepare( int nVars ) |
| { |
| Pla_Man_t * p; char Buffer[1000]; |
| Vec_Bit_t * vFunc = Pla_ManPrimesTable( nVars ); |
| Vec_Wrd_t * vSop = Pla_ManFxMinimize( (word *)Vec_BitArray(vFunc), nVars ); |
| word Cube, * pCube = &Cube; int i, k, Lit; |
| sprintf( Buffer, "primes%02d", nVars ); |
| p = Pla_ManAlloc( Buffer, nVars, 1, Vec_WrdSize(vSop) ); |
| Vec_WecInit( &p->vCubeLits, Pla_ManCubeNum(p) ); |
| Vec_WecInit( &p->vOccurs, 2*Pla_ManInNum(p) ); |
| Vec_WrdForEachEntry( vSop, Cube, i ) |
| Pla_CubeForEachLit( nVars, pCube, Lit, k ) |
| if ( Lit != PLA_LIT_DASH ) |
| { |
| Lit = Abc_Var2Lit( k, Lit == PLA_LIT_ZERO ); |
| Vec_WecPush( &p->vCubeLits, i, Lit ); |
| Vec_WecPush( &p->vOccurs, Lit, i ); |
| } |
| Vec_BitFree( vFunc ); |
| Vec_WrdFree( vSop ); |
| return p; |
| } |
| int Pla_ManFxPerformSimple( int nVars ) |
| { |
| char Buffer[100]; |
| Pla_Man_t * p = Pla_ManFxPrepare( nVars ); |
| sprintf( Buffer, "primesmin%02d.pla", nVars ); |
| Pla_ManDumpPla( p, Buffer ); |
| Pla_ManFree( p ); |
| return 1; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |