abcNpn.c 9.47 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
/**CFile****************************************************************

  FileName    [abcNpn.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Network and node package.]

  Synopsis    [Procedures for testing and comparing semi-canonical forms.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

  Revision    [$Id: abcNpn.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

***********************************************************************/

#include "misc/extra/extra.h"
#include "misc/vec/vec.h"

#include "bool/kit/kit.h"
#include "bool/lucky/lucky.h"

ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////
 
// semi-canonical form types
// 0 - none
// 1 - based on counting 1s in cofactors
// 2 - based on minimum truth table value
// 3 - exact NPN

// data-structure to store a bunch of truth tables
typedef struct Abc_TtStore_t_  Abc_TtStore_t;
struct Abc_TtStore_t_ 
{
44 45 46 47
    int                nVars;
    int                nWords;
    int                nFuncs;
    word **            pFuncs;
48 49
};

Alan Mishchenko committed
50 51
extern Abc_TtStore_t * Abc_TtStoreLoad( char * pFileName );
extern void            Abc_TtStoreFree( Abc_TtStore_t * p );
52
extern void            Abc_TtStoreWrite( char * pFileName, Abc_TtStore_t * p );
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [Counts the number of unique truth tables.]

  Description []
               
  SideEffects [] 

  SeeAlso     []

***********************************************************************/
int nWords = 0; // unfortunate global variable
70
int Abc_TruthCompare( word ** p1, word ** p2 ) { return memcmp(*p1, *p2, sizeof(word) * nWords); }
71 72
int Abc_TruthNpnCountUnique( Abc_TtStore_t * p )
{
73
    int i, k;
74 75 76
    // sort them by value
    nWords = p->nWords;
    assert( nWords > 0 );
77
    qsort( (void *)p->pFuncs, p->nFuncs, sizeof(word *), (int(*)(const void *,const void *))Abc_TruthCompare );
78
    // count the number of unqiue functions
79 80 81 82
    for ( i = k = 1; i < p->nFuncs; i++ )
        if ( memcmp( p->pFuncs[i-1], p->pFuncs[i], sizeof(word) * nWords ) )
            p->pFuncs[k++] = p->pFuncs[i];
    return (p->nFuncs = k);
83 84 85 86
}

/**Function*************************************************************

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
  Synopsis    [Prints out one NPN transform.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_TruthNpnPrint( char * pCanonPerm, unsigned uCanonPhase, int nVars )
{
    int i;
    printf( "   %c = ( ", Abc_InfoHasBit(&uCanonPhase, nVars) ? 'Z':'z' );
    for ( i = 0; i < nVars; i++ )
        printf( "%c%s", pCanonPerm[i] + ('A'-'a') * Abc_InfoHasBit(&uCanonPhase, pCanonPerm[i]-'a'), i == nVars-1 ? "":"," );
    printf( " )  " );
}

/**Function*************************************************************

107 108 109 110 111 112 113 114 115 116 117 118
  Synopsis    [Apply decomposition to the truth table.]

  Description [Returns the number of AIG nodes.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
{
    unsigned pAux[2048];
119 120
    char pCanonPerm[32];
    unsigned uCanonPhase=0;
121
    clock_t clk = clock();
122
    int i;
123 124

    char * pAlgoName = NULL;
125
    if ( NpnType == 0 )
126
        pAlgoName = "uniqifying       ";
127
    else if ( NpnType == 1 )
128
        pAlgoName = "exact NPN        ";
129
    else if ( NpnType == 2 )
130
        pAlgoName = "counting 1s      ";
131
    else if ( NpnType == 3 )
132
        pAlgoName = "minimizing TT    ";
133
    else if ( NpnType == 4 )
134 135 136
        pAlgoName = "hybrid NPN       ";
    else if ( NpnType == 5 )
        pAlgoName = "Jake's hybrid NPN";
137 138 139 140 141 142 143 144

    assert( p->nVars <= 16 );
    if ( pAlgoName )
        printf( "Applying %-10s to %8d func%s of %2d vars...  ",  
            pAlgoName, p->nFuncs, (p->nFuncs == 1 ? "":"s"), p->nVars );
    if ( fVerbose )
        printf( "\n" );

145
    if ( NpnType == 0 )
146 147 148 149 150 151 152 153 154
    {
        for ( i = 0; i < p->nFuncs; i++ )
        {
            if ( fVerbose )
                printf( "%7d : ", i );
            if ( fVerbose )
                Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" );
        }
    }
155
    else if ( NpnType == 1 )
156 157 158 159 160 161 162 163 164
    {
        int * pComp = Extra_GreyCodeSchedule( p->nVars );
        int * pPerm = Extra_PermSchedule( p->nVars );
        if ( p->nVars == 6 )
        {
            for ( i = 0; i < p->nFuncs; i++ )
            {
                if ( fVerbose )
                    printf( "%7d : ", i );
165
                *((word *)p->pFuncs[i]) = Extra_Truth6MinimumExact( *((word *)p->pFuncs[i]), pComp, pPerm );
166 167 168 169 170 171 172 173 174
                if ( fVerbose )
                    Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" );
            }
        }
        else
            printf( "This feature only works for 6-variable functions.\n" );
        ABC_FREE( pComp );
        ABC_FREE( pPerm );
    }
175 176 177 178 179 180
    else if ( NpnType == 2 )
    {
        for ( i = 0; i < p->nFuncs; i++ )
        {
            if ( fVerbose )
                printf( "%7d : ", i );
181 182
            resetPCanonPermArray(pCanonPerm, p->nVars);
            uCanonPhase = Kit_TruthSemiCanonicize( (unsigned *)p->pFuncs[i], pAux, p->nVars, pCanonPerm );
183
            if ( fVerbose )
184
                Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" );
185 186 187 188 189 190 191 192
        }
    }
    else if ( NpnType == 3 )
    {
        for ( i = 0; i < p->nFuncs; i++ )
        {
            if ( fVerbose )
                printf( "%7d : ", i );
193 194
            resetPCanonPermArray(pCanonPerm, p->nVars);
            uCanonPhase = Kit_TruthSemiCanonicize_new( (unsigned *)p->pFuncs[i], pAux, p->nVars, pCanonPerm );
195
            if ( fVerbose )
196
                Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" );
197 198
        }
    }
199 200 201 202 203 204 205 206
    else if ( NpnType == 4 )
    {
        if ( p->nVars == 6 )
        {
            for ( i = 0; i < p->nFuncs; i++ )
            {
                if ( fVerbose )
                    printf( "%7d : ", i );
207 208
                resetPCanonPermArray(pCanonPerm, p->nVars);
                Kit_TruthSemiCanonicize( (unsigned *)p->pFuncs[i], pAux, p->nVars, pCanonPerm );
209 210 211 212 213 214 215 216
                *((word *)p->pFuncs[i]) = Extra_Truth6MinimumHeuristic( *((word *)p->pFuncs[i]) );
                if ( fVerbose )
                    Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" );
            }
        }
        else
            printf( "This feature only works for 6-variable functions.\n" );
    }
217 218 219 220 221 222 223 224 225 226 227 228
    else if ( NpnType == 5 )
    {
        for ( i = 0; i < p->nFuncs; i++ )
        {
            if ( fVerbose )
                printf( "%7d : ", i );
            resetPCanonPermArray(pCanonPerm, p->nVars);
            uCanonPhase = luckyCanonicizer_final_fast( p->pFuncs[i], p->nVars, pCanonPerm );
            if ( fVerbose )
                Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" );
        }
    }
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
    else assert( 0 );

    clk = clock() - clk;
    printf( "Classes =%9d  ", Abc_TruthNpnCountUnique(p) );
    Abc_PrintTime( 1, "Time", clk );
}

/**Function*************************************************************

  Synopsis    [Apply decomposition to truth tables.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Abc_TruthNpnTest( char * pFileName, int NpnType, int fVerbose )
{
    Abc_TtStore_t * p;
250
    char * pFileNameOut;
251 252

    // read info from file
Alan Mishchenko committed
253
    p = Abc_TtStoreLoad( pFileName );
254 255 256 257 258 259
    if ( p == NULL )
        return;

    // consider functions from the file
    Abc_TruthNpnPerform( p, NpnType, fVerbose );

260 261 262 263 264 265
    // write the result
    pFileNameOut = Extra_FileNameGenericAppend( pFileName, "_out.txt" );
    Abc_TtStoreWrite( pFileNameOut, p );
    if ( fVerbose )
        printf( "The resulting functions are written into file \"%s\".\n", pFileNameOut );

266
    // delete data-structure
Alan Mishchenko committed
267
    Abc_TtStoreFree( p );
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
//    printf( "Finished computing canonical forms for functions from file \"%s\".\n", pFileName );
}


/**Function*************************************************************

  Synopsis    [Testbench for decomposition algorithms.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Abc_NpnTest( char * pFileName, int NpnType, int fVerbose )
{
    if ( fVerbose )
        printf( "Using truth tables from file \"%s\"...\n", pFileName );
287
    if ( NpnType >= 0 && NpnType <= 5 )
288 289 290 291 292 293 294 295 296 297 298 299 300 301
        Abc_TruthNpnTest( pFileName, NpnType, fVerbose );
    else
        printf( "Unknown canonical form value (%d).\n", NpnType );
    fflush( stdout );
    return 0;
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END