mirror of https://github.com/YosysHQ/abc.git
301 lines
9.0 KiB
C
301 lines
9.0 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [plaMan.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: plaMan.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "pla.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Generates PLA description of a sorter.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Pla_GenSorter( int nVars )
|
|
{
|
|
int i, k, Count, nMints = ( 1 << nVars );
|
|
char Buffer[20];
|
|
FILE * pFile;
|
|
sprintf( Buffer, "sorter%02d.pla", nVars );
|
|
pFile = fopen( Buffer, "wb" );
|
|
fprintf( pFile, "# This file was generated by ABC on %s.\n", Extra_TimeStamp() );
|
|
fprintf( pFile, ".i %d\n", nVars );
|
|
fprintf( pFile, ".o %d\n", nVars );
|
|
fprintf( pFile, ".p %d\n", nMints-1 );
|
|
for ( i = 1; i < nMints; i++ )
|
|
{
|
|
Count = 0;
|
|
for ( k = nVars-1; k >= 0; k-- )
|
|
{
|
|
Count += ((i >> k) & 1);
|
|
fprintf( pFile, "%d", (i >> k) & 1 );
|
|
}
|
|
fprintf( pFile, " " );
|
|
for ( k = 0; k < Count; k++ )
|
|
fprintf( pFile, "1" );
|
|
for ( ; k < nVars; k++ )
|
|
fprintf( pFile, "0" );
|
|
fprintf( pFile, "\n" );
|
|
}
|
|
fprintf( pFile, ".end\n" );
|
|
fclose( pFile );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Generates prime detector for the given bit-widths.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Vec_Bit_t * Pla_ManPrimesTable( int nVars )
|
|
{
|
|
int i, n, nBits = 1 << nVars;
|
|
Vec_Bit_t * vMap = Vec_BitStartFull( Abc_MaxInt(64, nBits) );
|
|
for ( i = nBits; i < 64; i++ )
|
|
Vec_BitWriteEntry( vMap, i, 0 );
|
|
Vec_BitShrink( vMap, nBits );
|
|
Vec_BitWriteEntry( vMap, 0, 0 );
|
|
Vec_BitWriteEntry( vMap, 1, 0 );
|
|
for ( n = 2; n < nBits; n++ )
|
|
if ( Vec_BitEntry(vMap, n) )
|
|
for ( i = 2*n; i < nBits; i += n )
|
|
Vec_BitWriteEntry( vMap, i, 0 );
|
|
return vMap;
|
|
}
|
|
Vec_Int_t * Pla_GenPrimes( int nVars )
|
|
{
|
|
int n, nBits = ( 1 << nVars );
|
|
Vec_Int_t * vPrimes = Vec_IntAlloc( 1000 );
|
|
Vec_Bit_t * vMap = Pla_ManPrimesTable( nVars );
|
|
for ( n = 2; n < nBits; n++ )
|
|
if ( Vec_BitEntry(vMap, n) )
|
|
Vec_IntPush( vPrimes, n );
|
|
printf( "Primes up to 2^%d = %d\n", nVars, Vec_IntSize(vPrimes) );
|
|
// Abc_GenCountHits1( vMap, vPrimes, nVars );
|
|
Vec_BitFree( vMap );
|
|
return vPrimes;
|
|
}
|
|
Pla_Man_t * Pla_GenFromMinterms( char * pName, Vec_Int_t * vMints, int nVars )
|
|
{
|
|
Pla_Man_t * p = Pla_ManAlloc( pName, nVars, 1, Vec_IntSize(vMints) );
|
|
int i, k, Lit, Mint;
|
|
word * pCube;
|
|
Pla_ForEachCubeIn( p, pCube, i )
|
|
{
|
|
Mint = Vec_IntEntry(vMints, i);
|
|
Pla_CubeForEachLitIn( p, pCube, Lit, k )
|
|
Pla_CubeSetLit( pCube, k, ((Mint >> k) & 1) ? PLA_LIT_ONE : PLA_LIT_ZERO );
|
|
}
|
|
Pla_ForEachCubeOut( p, pCube, i )
|
|
Pla_CubeSetLit( pCube, 0, PLA_LIT_ONE );
|
|
return p;
|
|
}
|
|
Pla_Man_t * Pla_ManPrimesDetector( int nVars )
|
|
{
|
|
char pName[1000];
|
|
Pla_Man_t * p;
|
|
Vec_Int_t * vMints = Pla_GenPrimes( nVars );
|
|
sprintf( pName, "primes%02d", nVars );
|
|
p = Pla_GenFromMinterms( pName, vMints, nVars );
|
|
Vec_IntFree( vMints );
|
|
return p;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Vec_Bit_t * Pla_GenRandom( int nVars, int nNums, int fNonZero )
|
|
{
|
|
int Mint, Count = 0;
|
|
Vec_Bit_t * vBits = Vec_BitStart( 1 << nVars );
|
|
assert( nVars > 0 && nVars <= 30 );
|
|
assert( nNums > 0 && nNums < (1 << (nVars - 1)) );
|
|
while ( Count < nNums )
|
|
{
|
|
Mint = Gia_ManRandom(0) & ((1 << nVars) - 1);
|
|
if ( fNonZero && Mint == 0 )
|
|
continue;
|
|
if ( Vec_BitEntry(vBits, Mint) )
|
|
continue;
|
|
Vec_BitWriteEntry( vBits, Mint, 1 );
|
|
Count++;
|
|
}
|
|
return vBits;
|
|
}
|
|
Pla_Man_t * Pla_ManGenerate( int nInputs, int nOutputs, int nCubes, int fVerbose )
|
|
{
|
|
Pla_Man_t * p;
|
|
Vec_Bit_t * vBits;
|
|
int i, k, Count;
|
|
word * pCube;
|
|
char Buffer[1000];
|
|
sprintf( Buffer, "%s_%d_%d_%d", "rand", nInputs, nOutputs, nCubes );
|
|
p = Pla_ManAlloc( Buffer, nInputs, nOutputs, nCubes );
|
|
// generate nCube random input minterms
|
|
vBits = Pla_GenRandom( nInputs, nCubes, 0 );
|
|
for ( i = Count = 0; i < Vec_BitSize(vBits); i++ )
|
|
if ( Vec_BitEntry(vBits, i) )
|
|
{
|
|
pCube = Pla_CubeIn( p, Count++ );
|
|
for ( k = 0; k < nInputs; k++ )
|
|
Pla_CubeSetLit( pCube, k, ((i >> k) & 1) ? PLA_LIT_ONE : PLA_LIT_ZERO );
|
|
}
|
|
assert( Count == nCubes );
|
|
Vec_BitFree( vBits );
|
|
// generate nCube random output minterms
|
|
if ( nOutputs > 1 )
|
|
{
|
|
vBits = Pla_GenRandom( nOutputs, nCubes, 1 );
|
|
for ( i = Count = 0; i < Vec_BitSize(vBits); i++ )
|
|
if ( Vec_BitEntry(vBits, i) )
|
|
{
|
|
pCube = Pla_CubeOut( p, Count++ );
|
|
for ( k = 0; k < nOutputs; k++ )
|
|
Pla_CubeSetLit( pCube, k, ((i >> k) & 1) ? PLA_LIT_ONE : PLA_LIT_ZERO );
|
|
}
|
|
assert( Count == nCubes );
|
|
Vec_BitFree( vBits );
|
|
}
|
|
else
|
|
{
|
|
Pla_ForEachCubeOut( p, pCube, i )
|
|
Pla_CubeSetLit( pCube, 0, PLA_LIT_ONE );
|
|
}
|
|
return p;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Pla_ManConvertFromBits( Pla_Man_t * p )
|
|
{
|
|
Vec_Int_t * vCube;
|
|
word * pCube; int i, k, Lit, Count;
|
|
Vec_WecClear( &p->vCubeLits );
|
|
Vec_WecClear( &p->vOccurs );
|
|
Vec_WecInit( &p->vCubeLits, Pla_ManCubeNum(p) );
|
|
Vec_WecInit( &p->vOccurs, 2*Pla_ManInNum(p) );
|
|
Pla_ForEachCubeIn( p, pCube, i )
|
|
{
|
|
vCube = Vec_WecEntry( &p->vCubeLits, i );
|
|
|
|
Count = 0;
|
|
Pla_CubeForEachLitIn( p, pCube, Lit, k )
|
|
if ( Lit != PLA_LIT_DASH )
|
|
Count++;
|
|
Vec_IntGrow( vCube, Count );
|
|
|
|
Count = 0;
|
|
Pla_CubeForEachLitIn( p, 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, Pla_CubeHandle(i, Count++) );
|
|
Vec_WecPush( &p->vOccurs, Lit, i );
|
|
}
|
|
assert( Vec_IntSize(vCube) == Vec_IntCap(vCube) );
|
|
}
|
|
}
|
|
void Pla_ManConvertToBits( Pla_Man_t * p )
|
|
{
|
|
Vec_Int_t * vCube; int i, k, Lit;
|
|
Vec_IntFillNatural( &p->vCubes, Vec_WecSize(&p->vCubeLits) );
|
|
Vec_WrdFill( &p->vInBits, Pla_ManCubeNum(p) * p->nInWords, 0 );
|
|
Vec_WecForEachLevel( &p->vCubeLits, vCube, i )
|
|
Vec_IntForEachEntry( vCube, Lit, k )
|
|
Pla_CubeSetLit( Pla_CubeIn(p, i), Abc_Lit2Var(Lit), Abc_LitIsCompl(Lit) ? PLA_LIT_ZERO : PLA_LIT_ONE );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Pla_ManDist1Num( Pla_Man_t * p )
|
|
{
|
|
word * pCube1, * pCube2;
|
|
int i, k, Dist, Count = 0;
|
|
Pla_ForEachCubeIn( p, pCube1, i )
|
|
Pla_ForEachCubeInStart( p, pCube2, k, i+1 )
|
|
{
|
|
Dist = Pla_CubesAreDistance1( pCube1, pCube2, p->nInWords );
|
|
// Dist = Pla_CubesAreConsensus( pCube1, pCube2, p->nInWords, NULL );
|
|
Count += (Dist == 1);
|
|
}
|
|
return Count;
|
|
}
|
|
int Pla_ManDist1NumTest( Pla_Man_t * p )
|
|
{
|
|
abctime clk = Abc_Clock();
|
|
int Count = Pla_ManDist1Num( p );
|
|
printf( "Found %d pairs among %d cubes using cube pair enumeration. ", Count, Pla_ManCubeNum(p) );
|
|
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
|
return 1;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|