mirror of https://github.com/YosysHQ/abc.git
Structural mapper into structures.
This commit is contained in:
parent
e70adbcd2d
commit
4e00ec6169
|
|
@ -3715,6 +3715,10 @@ SOURCE=.\src\aig\gia\giaIf.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaIff.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaIso.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
|
|
@ -0,0 +1,349 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaCut.h]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Cut computation.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaCut.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef ABC__aig__gia__giaAig_h
|
||||
#define ABC__aig__gia__giaAig_h
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "gia.h"
|
||||
|
||||
ABC_NAMESPACE_HEADER_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// BASIC TYPES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define GIA_CUT_LEAF_MAX 8
|
||||
#define GIA_CUT_WORD_MAX ((GIA_CUT_LEAF_MAX > 6) ? 1 << (GIA_CUT_LEAF_MAX-6) : 1)
|
||||
#define GIA_CUT_NUM_MAX 16
|
||||
|
||||
typedef struct Gia_Cut_t_ Gia_Cut_t;
|
||||
struct Gia_Cut_t_
|
||||
{
|
||||
word Sign; // signature
|
||||
int Id; // cut ID
|
||||
int iFunc; // function
|
||||
int iNext; // next cut
|
||||
int iFan0; // left child
|
||||
int iFan1; // right child
|
||||
int nLeaves; // number of leaves
|
||||
int pLeaves[GIA_CUT_LEAF_MAX]; // cut
|
||||
int pCompls[GIA_CUT_LEAF_MAX]; // polarity
|
||||
};
|
||||
|
||||
static inline int Gia_CutSize( int * pCut ) { return pCut[0] & 0xF; } // 4 bits
|
||||
|
||||
#define Gia_ObjForEachCut( pList, pCut, i, AddOn ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += Gia_CutSize(pCut) + AddOn )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// loads cuts from storage
|
||||
static inline int Gia_ObjLoadCuts( Gia_Cut_t * pCutsI, int * pCuts, int AddOn )
|
||||
{
|
||||
Gia_Cut_t * pCutsICur;
|
||||
int i, k, Lit, * pCut;
|
||||
assert( AddOn == 1 || AddOn == 2 );
|
||||
Gia_ObjForEachCut( pCuts, pCut, i, AddOn )
|
||||
{
|
||||
pCutsICur = pCutsI + i;
|
||||
pCutsICur->Id = i;
|
||||
pCutsICur->Sign = 0;
|
||||
pCutsICur->iFunc = (AddOn == 1) ? -1 : pCut[pCut[0] + 1];
|
||||
pCutsICur->nLeaves = pCut[0];
|
||||
for ( k = 0; k < pCut[0]; k++ )
|
||||
{
|
||||
Lit = pCut[k+1];
|
||||
pCutsICur->pCompls[k] = Abc_LitIsCompl(Lit);
|
||||
pCutsICur->pLeaves[k] = Abc_Lit2Var(Lit);
|
||||
pCutsICur->Sign |= 1 << (Abc_Lit2Var(Lit) & 0x3F);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static inline int Gia_CutId( Gia_Cut_t * pCutsOut, Gia_Cut_t * pCut )
|
||||
{
|
||||
return pCut - pCutsOut;
|
||||
}
|
||||
static inline void Gia_CutInsert( Gia_Cut_t * pCutsOut, Gia_Cut_t * pCut ) // inserts cut into the list
|
||||
{
|
||||
int * pPlace = &pCutsOut[pCut->nLeaves].iNext;
|
||||
pCut->iNext = *pPlace; *pPlace = pCut - pCutsOut;
|
||||
}
|
||||
static inline void Gia_CutRemove( int * pPlace, Gia_Cut_t * pCut ) // removes cut from the list
|
||||
{
|
||||
*pPlace = pCut->iNext;
|
||||
}
|
||||
static inline word Gia_CutGetSign( Gia_Cut_t * pCut )
|
||||
{
|
||||
word Sign = 0; int i;
|
||||
for ( i = 0; i < pCut->nLeaves; i++ )
|
||||
Sign |= ((word)1) << (pCut->pLeaves[i] & 0x3F);
|
||||
return Sign;
|
||||
}
|
||||
static inline int Gia_CutCountBits( word i )
|
||||
{
|
||||
i = i - ((i >> 1) & 0x5555555555555555);
|
||||
i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333);
|
||||
i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F);
|
||||
return (i*(0x0101010101010101))>>56;
|
||||
}
|
||||
|
||||
static inline int Gia_CutIsContainedOrder( Gia_Cut_t * pBase, Gia_Cut_t * pCut ) // check if pCut is contained pBase
|
||||
{
|
||||
int i, k;
|
||||
if ( pBase->nLeaves == pCut->nLeaves )
|
||||
{
|
||||
for ( i = 1; i <= pCut->nLeaves; i++ )
|
||||
if ( pBase->pLeaves[i] != pCut->pLeaves[i] )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
assert( pBase->nLeaves > pCut->nLeaves );
|
||||
for ( i = k = 1; i <= pBase->nLeaves; i++ )
|
||||
{
|
||||
if ( pBase->pLeaves[i] > pCut->pLeaves[k] )
|
||||
return 0;
|
||||
if ( pBase->pLeaves[i] == pCut->pLeaves[k] )
|
||||
{
|
||||
if ( k++ == pCut->nLeaves )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// check if the given cut is contained in previous cuts
|
||||
static inline int Gia_ObjCheckContainInPrev( Gia_Cut_t * pCutsOut, Gia_Cut_t * pCut )
|
||||
{
|
||||
Gia_Cut_t * pPrev;
|
||||
for ( pPrev = pCutsOut; pPrev->iNext; pPrev = pCutsOut + pPrev->iNext )
|
||||
{
|
||||
if ( pPrev->iFunc == -2 ) // skip sentinels
|
||||
continue;
|
||||
if ( pPrev->nLeaves > pCut->nLeaves ) // stop when we reached bigger cuts
|
||||
return 0;
|
||||
if ( (pCut->Sign & pPrev->Sign) != pPrev->Sign )
|
||||
continue;
|
||||
if ( Gia_CutIsContainedOrder(pPrev, pCut) )
|
||||
return 1;
|
||||
}
|
||||
assert( 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// check if the given cut contains following cuts
|
||||
static inline void Gia_ObjCheckContainsNext( Gia_Cut_t * pCutsOut, Gia_Cut_t * pCut, int ** ppPlace )
|
||||
{
|
||||
Gia_Cut_t * pNext;
|
||||
int * pPlace = &pCut->iNext;
|
||||
while ( *pPlace )
|
||||
{
|
||||
pNext = pCutsOut + pNext->iNext;
|
||||
if ( pNext->iFunc == -2 ) // skip sentinels
|
||||
continue;
|
||||
assert( pNext != pCut && pNext->nLeaves >= pCut->nLeaves );
|
||||
if ( (pNext->Sign & pCut->Sign) != pCut->Sign )
|
||||
continue;
|
||||
if ( !Gia_CutIsContainedOrder(pCut, pNext) )
|
||||
{
|
||||
pPlace = &pNext->iNext;
|
||||
continue;
|
||||
}
|
||||
// shift the pointer
|
||||
if ( *ppPlace == &pNext->iNext )
|
||||
*ppPlace = pPlace;
|
||||
// remove pNext
|
||||
Gia_CutRemove( pPlace, pNext );
|
||||
}
|
||||
}
|
||||
|
||||
static inline int Gia_ObjMergeCutsOrder( Gia_Cut_t * pCut, Gia_Cut_t * pCut0, Gia_Cut_t * pCut1, int LutSize )
|
||||
{
|
||||
int nSize0 = pCut0->nLeaves;
|
||||
int nSize1 = pCut1->nLeaves;
|
||||
int * pC0 = pCut0->pLeaves;
|
||||
int * pC1 = pCut1->pLeaves;
|
||||
int * pC = pCut->pLeaves;
|
||||
int i, k, c, s;
|
||||
// the case of the largest cut sizes
|
||||
if ( nSize0 == LutSize && nSize1 == LutSize )
|
||||
{
|
||||
for ( i = 0; i < nSize0; i++ )
|
||||
{
|
||||
if ( pC0[i] != pC1[i] )
|
||||
return 0;
|
||||
pC[i] = pC0[i];
|
||||
}
|
||||
pCut->nLeaves = LutSize;
|
||||
return 1;
|
||||
}
|
||||
// compare two cuts with different numbers
|
||||
i = k = c = s = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( c == LutSize ) return 0;
|
||||
if ( pC0[i] < pC1[k] )
|
||||
{
|
||||
pC[c++] = pC0[i++];
|
||||
if ( i >= nSize0 ) goto FlushCut1;
|
||||
}
|
||||
else if ( pC0[i] > pC1[k] )
|
||||
{
|
||||
pC[c++] = pC1[k++];
|
||||
if ( k >= nSize1 ) goto FlushCut0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pC[c++] = pC0[i++]; k++;
|
||||
if ( i >= nSize0 ) goto FlushCut1;
|
||||
if ( k >= nSize1 ) goto FlushCut0;
|
||||
}
|
||||
}
|
||||
|
||||
FlushCut0:
|
||||
if ( c + nSize0 > LutSize + i ) return 0;
|
||||
while ( i < nSize0 )
|
||||
pC[c++] = pC0[i++];
|
||||
pCut->nLeaves = c;
|
||||
return 1;
|
||||
|
||||
FlushCut1:
|
||||
if ( c + nSize1 > LutSize + k ) return 0;
|
||||
while ( k < nSize1 )
|
||||
pC[c++] = pC1[k++];
|
||||
pCut->nLeaves = c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int Gia_ObjCombineCuts( Gia_Cut_t * pCutsOut, Gia_Cut_t * pCut, Gia_Cut_t * pCut0, Gia_Cut_t * pCut1, int LutSize )
|
||||
{
|
||||
if ( !Gia_ObjMergeCutsOrder(pCut, pCut0, pCut1, LutSize) )
|
||||
return 0;
|
||||
pCut->Sign = pCut0->Sign | pCut1->Sign;
|
||||
if ( !Gia_ObjCheckContainInPrev(pCutsOut, pCut) )
|
||||
return 0;
|
||||
Gia_CutInsert( pCutsOut, pCut );
|
||||
pCut->Id = pCut - pCutsOut;
|
||||
pCut->iFan0 = pCut0->Id;
|
||||
pCut->iFan1 = pCut1->Id;
|
||||
pCut->iFunc = -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Gia_TtComputeForCut( Vec_Mem_t * vTtMem, int iFuncLit0, int iFuncLit1, Gia_Cut_t * pCut0, Gia_Cut_t * pCut1, Gia_Cut_t * pCut, int LutSize )
|
||||
{
|
||||
word uTruth[GIA_CUT_WORD_MAX], uTruth0[GIA_CUT_WORD_MAX], uTruth1[GIA_CUT_WORD_MAX];
|
||||
int fCompl, truthId;
|
||||
int nWords = Abc_Truth6WordNum(LutSize);
|
||||
word * pTruth0 = Vec_MemReadEntry(vTtMem, Abc_Lit2Var(iFuncLit0));
|
||||
word * pTruth1 = Vec_MemReadEntry(vTtMem, Abc_Lit2Var(iFuncLit1));
|
||||
Abc_TtCopy( uTruth0, pTruth0, nWords, Abc_LitIsCompl(iFuncLit0) );
|
||||
Abc_TtCopy( uTruth1, pTruth1, nWords, Abc_LitIsCompl(iFuncLit1) );
|
||||
Abc_TtStretch( uTruth0, LutSize, pCut0->pLeaves, pCut0->nLeaves, pCut->pLeaves, pCut->nLeaves );
|
||||
Abc_TtStretch( uTruth1, LutSize, pCut1->pLeaves, pCut1->nLeaves, pCut->pLeaves, pCut->nLeaves );
|
||||
fCompl = (int)(uTruth0[0] & uTruth1[0] & 1);
|
||||
Abc_TtAnd( uTruth, uTruth0, uTruth1, nWords, fCompl );
|
||||
pCut->nLeaves = Abc_TtMinBase( uTruth, pCut->pLeaves, pCut->nLeaves, LutSize );
|
||||
assert( (uTruth[0] & 1) == 0 );
|
||||
truthId = Vec_MemHashInsert(vTtMem, uTruth);
|
||||
return Abc_Var2Lit( truthId, fCompl );
|
||||
}
|
||||
|
||||
// Gia_Cut_t pCutsOut[GIA_CUT_LEAF_MAX + 2 + GIA_CUT_NUM_MAX * GIA_CUT_NUM_MAX]; // LutSize+1 placeholders + CutNum ^ 2 + 1
|
||||
static inline int Gia_ObjComputeCuts( Gia_Cut_t * pCutsOut, int * pCuts0, int * pCuts1, Vec_Mem_t * vTtMem, int AddOn, int nLutSize, int nCutNum, int fCompl0, int fCompl1 )
|
||||
{
|
||||
Gia_Cut_t * pCut;
|
||||
Gia_Cut_t pCuts0i[GIA_CUT_NUM_MAX];
|
||||
Gia_Cut_t pCuts1i[GIA_CUT_NUM_MAX];
|
||||
int i, nCuts0i = Gia_ObjLoadCuts( pCuts0i, pCuts0, AddOn );
|
||||
int k, nCuts1i = Gia_ObjLoadCuts( pCuts1i, pCuts1, AddOn );
|
||||
int * pPlace, c = GIA_CUT_NUM_MAX + 1;
|
||||
assert( nCuts0i <= GIA_CUT_NUM_MAX );
|
||||
assert( nCuts1i <= GIA_CUT_NUM_MAX );
|
||||
// prepare cuts
|
||||
for ( i = 0; i <= GIA_CUT_NUM_MAX; i++ )
|
||||
{
|
||||
pCut = pCutsOut + i;
|
||||
pCut->nLeaves = i;
|
||||
pCut->iNext = i+1;
|
||||
pCut->iFunc = -2;
|
||||
pCut->Id = i;
|
||||
}
|
||||
pCut->iNext = 0;
|
||||
// enumerate pairs
|
||||
for ( i = 0; i < nCuts0i; i++ )
|
||||
for ( k = 0; k < nCuts1i; k++ )
|
||||
if ( Gia_CutCountBits(pCuts0i[i].Sign | pCuts1i[k].Sign) <= nLutSize )
|
||||
Gia_ObjCombineCuts( pCutsOut, pCutsOut + c++, pCuts0i + i, pCuts1i + k, nLutSize );
|
||||
assert( c <= GIA_CUT_LEAF_MAX + 2 + GIA_CUT_NUM_MAX * GIA_CUT_NUM_MAX );
|
||||
// check containment for cuts
|
||||
for ( pPlace = &pCutsOut->iNext; *pPlace; pPlace = &pCut->iNext )
|
||||
{
|
||||
pCut = pCutsOut + *pPlace;
|
||||
if ( pCut->iFunc == -2 )
|
||||
continue;
|
||||
// compute truth table
|
||||
if ( AddOn == 2 )
|
||||
{
|
||||
Gia_Cut_t * pCut0 = pCuts0i + pCut->iFan0;
|
||||
Gia_Cut_t * pCut1 = pCuts1i + pCut->iFan1;
|
||||
int iLit0 = Abc_LitNotCond( pCut0->iFunc, fCompl0 );
|
||||
int iLit1 = Abc_LitNotCond( pCut1->iFunc, fCompl1 );
|
||||
int nLeavesOld = pCut->nLeaves;
|
||||
pCut->iFunc = Gia_TtComputeForCut( vTtMem, iLit0, iLit1, pCut0, pCut1, pCut, nLutSize );
|
||||
// if size has changed, move the cut closer
|
||||
if ( nLeavesOld != pCut->nLeaves )
|
||||
{
|
||||
Gia_CutRemove( pPlace, pCut );
|
||||
Gia_CutInsert( pCutsOut, pCut );
|
||||
pCut->Sign = Gia_CutGetSign( pCut );
|
||||
}
|
||||
}
|
||||
// check containment after this cut
|
||||
Gia_ObjCheckContainsNext( pCutsOut, pCut, &pPlace );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ABC_NAMESPACE_HEADER_END
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -1461,6 +1461,7 @@ void Gia_ManTransferPacking( Gia_Man_t * pGia, Gia_Man_t * p )
|
|||
***********************************************************************/
|
||||
Gia_Man_t * Gia_ManPerformMapping( Gia_Man_t * p, void * pp, int fNormalized )
|
||||
{
|
||||
extern void Gia_ManIffTest( Gia_Man_t * pGia, If_LibLut_t * pLib, int fVerbose );
|
||||
Gia_Man_t * pNew;
|
||||
If_Man_t * pIfMan;
|
||||
If_Par_t * pPars = (If_Par_t *)pp;
|
||||
|
|
@ -1529,6 +1530,8 @@ Gia_Man_t * Gia_ManPerformMapping( Gia_Man_t * p, void * pp, int fNormalized )
|
|||
Gia_ManStop( p );
|
||||
// printf( "PERFORMING VERIFICATION:\n" );
|
||||
// Gia_ManVerifyWithBoxes( pNew, NULL );
|
||||
if ( pPars->fRepack )
|
||||
Gia_ManIffTest( pNew, pPars->pLutLib, pPars->fVerbose );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,382 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaIff.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis [Hierarchical mapping of AIG with white boxes.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaIff.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
#include "map/if/if.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Iff_Man_t_ Iff_Man_t;
|
||||
struct Iff_Man_t_
|
||||
{
|
||||
Gia_Man_t * pGia; // mapped GIA
|
||||
If_LibLut_t * pLib; // LUT library
|
||||
int nLutSize; // LUT size
|
||||
int nDegree; // degree
|
||||
Vec_Flt_t * vTimes; // arrival times
|
||||
Vec_Int_t * vMatch[4]; // matches
|
||||
};
|
||||
|
||||
static inline float Iff_ObjTimeId( Iff_Man_t * p, int iObj, int Type ) { return Vec_FltEntry( p->vTimes, iObj ); }
|
||||
static inline float Iff_ObjTime( Iff_Man_t * p, Gia_Obj_t * pObj, int Type ) { return Iff_ObjTimeId( p, Gia_ObjId(p->pGia, pObj), Type ); }
|
||||
static inline void Iff_ObjSetTimeId( Iff_Man_t * p, int iObj, int Type, float Time ) { Vec_FltWriteEntry( p->vTimes, iObj, Time ); }
|
||||
static inline void Iff_ObjSetTime( Iff_Man_t * p, Gia_Obj_t * pObj, int Type, float Time ) { Iff_ObjSetTimeId( p, Gia_ObjId(p->pGia, pObj), Type, Time ); }
|
||||
|
||||
static inline int Iff_ObjMatchId( Iff_Man_t * p, int iObj, int Type ) { return Vec_IntEntry( p->vMatch[Type], iObj ); }
|
||||
static inline int Iff_ObjMatch( Iff_Man_t * p, Gia_Obj_t * pObj, int Type ) { return Iff_ObjTimeId( p, Gia_ObjId(p->pGia, pObj), Type ); }
|
||||
static inline void Iff_ObjSetMatchId( Iff_Man_t * p, int iObj, int Type, int Match ) { Vec_IntWriteEntry( p->vMatch[Type], iObj, Match ); }
|
||||
static inline void Iff_ObjSetMatch( Iff_Man_t * p, Gia_Obj_t * pObj, int Type, int Match ) { Iff_ObjSetTimeId( p, Gia_ObjId(p->pGia, pObj), Type, Match );}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Iff_Man_t * Gia_ManIffStart( Gia_Man_t * pGia )
|
||||
{
|
||||
Iff_Man_t * p = ABC_CALLOC( Iff_Man_t, 1 );
|
||||
p->vTimes = Vec_FltStartFull( Gia_ManObjNum(pGia) );
|
||||
p->vMatch[2] = Vec_IntStartFull( Gia_ManObjNum(pGia) );
|
||||
p->vMatch[3] = Vec_IntStartFull( Gia_ManObjNum(pGia) );
|
||||
return p;
|
||||
}
|
||||
void Gia_ManIffStop( Iff_Man_t * p )
|
||||
{
|
||||
Vec_FltFree( p->vTimes );
|
||||
Vec_IntFree( p->vMatch[2] );
|
||||
Vec_IntFree( p->vMatch[3] );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Gia_IffObjTimeBest( Iff_Man_t * p, int iObj )
|
||||
{
|
||||
return Abc_MinFloat( Iff_ObjTimeId(p, iObj, 1), Iff_ObjTimeId(p, iObj, 2) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Count the number of unique fanins.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_IffObjCount( Gia_Man_t * pGia, int iObj, int iFaninSkip, int iFaninSkip2 )
|
||||
{
|
||||
int i, iFanin, Count = 0;
|
||||
Gia_ManIncrementTravId( pGia );
|
||||
Gia_LutForEachFanin( pGia, iObj, iFanin, i )
|
||||
{
|
||||
if ( iFanin == iFaninSkip || iFanin == iFaninSkip2 )
|
||||
continue;
|
||||
if ( Gia_ObjIsTravIdCurrentId( pGia, iFanin ) )
|
||||
continue;
|
||||
Gia_ObjSetTravIdCurrentId( pGia, iFanin );
|
||||
Count++;
|
||||
}
|
||||
if ( iFaninSkip >= 0 )
|
||||
{
|
||||
Gia_LutForEachFanin( pGia, iFaninSkip, iFanin, i )
|
||||
{
|
||||
if ( iFanin == iFaninSkip2 )
|
||||
continue;
|
||||
if ( Gia_ObjIsTravIdCurrentId( pGia, iFanin ) )
|
||||
continue;
|
||||
Gia_ObjSetTravIdCurrentId( pGia, iFanin );
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
if ( iFaninSkip2 >= 0 )
|
||||
{
|
||||
Gia_LutForEachFanin( pGia, iFaninSkip2, iFanin, i )
|
||||
{
|
||||
if ( Gia_ObjIsTravIdCurrentId( pGia, iFanin ) )
|
||||
continue;
|
||||
Gia_ObjSetTravIdCurrentId( pGia, iFanin );
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Gia_IffObjTimeOne( Iff_Man_t * p, int iObj, int iFaninSkip, int iFaninSkip2 )
|
||||
{
|
||||
int i, iFanin;
|
||||
float Best = -ABC_INFINITY;
|
||||
Gia_LutForEachFanin( p->pGia, iObj, iFanin, i )
|
||||
if ( iFanin != iFaninSkip && iFanin != iFaninSkip2 && Best < Iff_ObjTimeId(p, iFanin, 1) )
|
||||
Best = Iff_ObjTimeId(p, iFanin, 1);
|
||||
assert( i == Gia_ObjLutSize(p->pGia, iObj) );
|
||||
if ( iFaninSkip == -1 )
|
||||
return Best + p->pLib->pLutDelays[i][0];
|
||||
Gia_LutForEachFanin( p->pGia, iFaninSkip, iFanin, i )
|
||||
if ( Best < Iff_ObjTimeId(p, iFanin, 1) )
|
||||
Best = Iff_ObjTimeId(p, iFanin, 1);
|
||||
if ( iFaninSkip2 == -1 )
|
||||
return Best;
|
||||
Gia_LutForEachFanin( p->pGia, iFaninSkip2, iFanin, i )
|
||||
if ( Best < Iff_ObjTimeId(p, iFanin, 1) )
|
||||
Best = Iff_ObjTimeId(p, iFanin, 1);
|
||||
assert( Best >= 0 );
|
||||
return Best;
|
||||
}
|
||||
float Gia_IffObjTimeTwo( Iff_Man_t * p, int iObj, int * piFanin )
|
||||
{
|
||||
int i, iFanin, nSize;
|
||||
float This, Best = -ABC_INFINITY;
|
||||
*piFanin = -1;
|
||||
Gia_LutForEachFanin( p->pGia, iObj, iFanin, i )
|
||||
{
|
||||
This = Gia_IffObjTimeOne( p, iObj, iFanin, -1 );
|
||||
nSize = Abc_MinInt( Gia_ObjLutSize(p->pGia, iObj) + Gia_ObjLutSize(p->pGia, iFanin) - 1, p->pLib->LutMax );
|
||||
This += p->pLib->pLutDelays[nSize][0];
|
||||
if ( Best < This )
|
||||
{
|
||||
Best = This;
|
||||
*piFanin = iFanin;
|
||||
}
|
||||
}
|
||||
return Best;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Iff_Man_t * Gia_ManIffPerform( Gia_Man_t * pGia, If_LibLut_t * pLib, Tim_Man_t * pTime, int nLutSize, int nDegree )
|
||||
{
|
||||
Iff_Man_t * p;
|
||||
Gia_Obj_t * pObj;
|
||||
float arrTime1, arrTime2;
|
||||
int iObj, iFanin;
|
||||
assert( nDegree == 2 );//|| nDegree == 3 );
|
||||
// start the mapping manager and set its parameters
|
||||
p = Gia_ManIffStart( pGia );
|
||||
p->pGia = pGia;
|
||||
p->pLib = pLib;
|
||||
p->nLutSize = nLutSize;
|
||||
p->nDegree = nDegree;
|
||||
// compute arrival times of each node
|
||||
Iff_ObjSetTimeId( p, 0, 1, 0 );
|
||||
Iff_ObjSetTimeId( p, 0, 2, 0 );
|
||||
Iff_ObjSetTimeId( p, 0, 3, 0 );
|
||||
Tim_ManIncrementTravId( pTime );
|
||||
Gia_ManForEachObj1( pGia, pObj, iObj )
|
||||
{
|
||||
if ( Gia_ObjIsAnd(pObj) )
|
||||
{
|
||||
if ( !Gia_ObjIsLut(pGia, iObj) )
|
||||
continue;
|
||||
// compute arrival times of LUT inputs
|
||||
arrTime1 = Gia_IffObjTimeOne( p, iObj, -1, -1 );
|
||||
// compute arrival times of LUT pairs
|
||||
arrTime2 = Gia_IffObjTimeTwo( p, iObj, &iFanin );
|
||||
// check arrival times
|
||||
Iff_ObjSetTimeId( p, iObj, 1, arrTime2 );
|
||||
if ( arrTime2 < arrTime1 )
|
||||
Iff_ObjSetMatchId( p, iObj, 2, iFanin );
|
||||
// compute arrival times of LUT triples
|
||||
}
|
||||
else if ( Gia_ObjIsCi(pObj) )
|
||||
{
|
||||
arrTime1 = Tim_ManGetCiArrival( pTime, Gia_ObjCioId(pObj) );
|
||||
Iff_ObjSetTime( p, pObj, 1, arrTime1 );
|
||||
Iff_ObjSetTime( p, pObj, 2, arrTime1 );
|
||||
Iff_ObjSetTime( p, pObj, 3, arrTime1 );
|
||||
}
|
||||
else if ( Gia_ObjIsCo(pObj) )
|
||||
{
|
||||
arrTime1 = Gia_IffObjTimeBest( p, Gia_ObjFaninId0p(pGia, pObj) );
|
||||
Tim_ManSetCoArrival( pTime, Gia_ObjCioId(pObj), arrTime1 );
|
||||
Iff_ObjSetTime( p, pObj, 1, arrTime1 );
|
||||
Iff_ObjSetTime( p, pObj, 2, arrTime1 );
|
||||
Iff_ObjSetTime( p, pObj, 3, arrTime1 );
|
||||
}
|
||||
else assert( 0 );
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManIffSelect_rec( Iff_Man_t * p, int iObj, Vec_Int_t * vPacking )
|
||||
{
|
||||
int i, iFanin, iFaninSkip;
|
||||
if ( Gia_ObjIsTravIdCurrentId( p->pGia, iObj ) )
|
||||
return;
|
||||
Gia_ObjSetTravIdCurrentId( p->pGia, iObj );
|
||||
assert( Gia_ObjIsLut(p->pGia, iObj) );
|
||||
iFaninSkip = Iff_ObjMatchId(p, iObj, 2);
|
||||
if ( iFaninSkip == -1 )
|
||||
{
|
||||
Gia_LutForEachFanin( p->pGia, iObj, iFanin, i )
|
||||
Gia_ManIffSelect_rec( p, iFanin, vPacking );
|
||||
Vec_IntPush( vPacking, 1 );
|
||||
Vec_IntPush( vPacking, iObj );
|
||||
}
|
||||
else
|
||||
{
|
||||
Gia_LutForEachFanin( p->pGia, iFaninSkip, iFanin, i )
|
||||
Gia_ManIffSelect_rec( p, iFanin, vPacking );
|
||||
Gia_LutForEachFanin( p->pGia, iObj, iFanin, i )
|
||||
if ( iFanin != iFaninSkip )
|
||||
Gia_ManIffSelect_rec( p, iFanin, vPacking );
|
||||
Vec_IntPush( vPacking, 2 );
|
||||
Vec_IntPush( vPacking, iFaninSkip );
|
||||
Vec_IntPush( vPacking, iObj );
|
||||
}
|
||||
Vec_IntAddToEntry( vPacking, 0, 1 );
|
||||
}
|
||||
Vec_Int_t * Gia_ManIffSelect( Iff_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vPacking;
|
||||
Gia_Obj_t * pObj; int i;
|
||||
vPacking = Vec_IntAlloc( Gia_ManObjNum(p->pGia) );
|
||||
Vec_IntPush( vPacking, 0 );
|
||||
// mark const0 and PIs
|
||||
Gia_ManIncrementTravId( p->pGia );
|
||||
Gia_ObjSetTravIdCurrent( p->pGia, Gia_ManConst0(p->pGia) );
|
||||
Gia_ManForEachCi( p->pGia, pObj, i )
|
||||
Gia_ObjSetTravIdCurrent( p->pGia, pObj );
|
||||
// recursively collect internal nodes
|
||||
Gia_ManForEachCo( p->pGia, pObj, i )
|
||||
Gia_ManIffSelect_rec( p, Gia_ObjFaninId0p(p->pGia, pObj), vPacking );
|
||||
return vPacking;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [This command performs hierarhical mapping.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Gia_ManIffTest( Gia_Man_t * pGia, If_LibLut_t * pLib, int fVerbose )
|
||||
{
|
||||
Iff_Man_t * p;
|
||||
int nDegree = -1;
|
||||
int nLutSize = Gia_ManLutSizeMax( pGia );
|
||||
if ( nLutSize <= 4 )
|
||||
{
|
||||
nLutSize = 4;
|
||||
if ( pLib->LutMax <= 7 )
|
||||
nDegree = 2;
|
||||
else if ( pLib->LutMax <= 10 )
|
||||
nDegree = 3;
|
||||
else
|
||||
{ printf( "Degree is more than 3.\n" ); return; }
|
||||
}
|
||||
else if ( nLutSize <= 6 )
|
||||
{
|
||||
nLutSize = 6;
|
||||
if ( pLib->LutMax <= 11 )
|
||||
nDegree = 2;
|
||||
else if ( pLib->LutMax <= 16 )
|
||||
nDegree = 3;
|
||||
else
|
||||
{ printf( "Degree is more than 3.\n" ); return; }
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "The LUT size is more than 6.\n" );
|
||||
return;
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "Performing %d-clustering with %d-LUTs:\n", nDegree, nLutSize );
|
||||
// create timing manager
|
||||
if ( pGia->pManTime == NULL )
|
||||
pGia->pManTime = Tim_ManStart( Gia_ManCiNum(pGia), Gia_ManCoNum(pGia) );
|
||||
// perform timing computation
|
||||
p = Gia_ManIffPerform( pGia, pLib, pGia->pManTime, nLutSize, nDegree );
|
||||
// derive clustering
|
||||
Vec_IntFreeP( &pGia->vPacking );
|
||||
pGia->vPacking = Gia_ManIffSelect( p );
|
||||
Gia_ManIffStop( p );
|
||||
// print statistics
|
||||
if ( fVerbose )
|
||||
Gia_ManPrintPackingStats( pGia );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -27,6 +27,7 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaGlitch.c \
|
||||
src/aig/gia/giaHash.c \
|
||||
src/aig/gia/giaIf.c \
|
||||
src/aig/gia/giaIff.c \
|
||||
src/aig/gia/giaIso.c \
|
||||
src/aig/gia/giaIso2.c \
|
||||
src/aig/gia/giaJf.c \
|
||||
|
|
|
|||
|
|
@ -29741,7 +29741,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
}
|
||||
pPars->pLutLib = (If_LibLut_t *)pAbc->pLibLut;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRDEWSqalepmrsdbgyojikfuzvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGRDEWSqalepmrsdbgyojikfuztvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -29917,6 +29917,9 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'z':
|
||||
pPars->fDeriveLuts ^= 1;
|
||||
break;
|
||||
case 't':
|
||||
pPars->fRepack ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
pPars->fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -30111,7 +30114,7 @@ usage:
|
|||
sprintf(LutSize, "library" );
|
||||
else
|
||||
sprintf(LutSize, "%d", pPars->nLutSize );
|
||||
Abc_Print( -2, "usage: &if [-KCFAGR num] [-DEW float] [-S str] [-qarlepmsdbgyojikfuczvh]\n" );
|
||||
Abc_Print( -2, "usage: &if [-KCFAGR num] [-DEW float] [-S str] [-qarlepmsdbgyojikfucztvh]\n" );
|
||||
Abc_Print( -2, "\t performs FPGA technology mapping of the network\n" );
|
||||
Abc_Print( -2, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, LutSize );
|
||||
Abc_Print( -2, "\t-C num : the max number of priority cuts (0 < num < 2^12) [default = %d]\n", pPars->nCutsMax );
|
||||
|
|
@ -30142,6 +30145,7 @@ usage:
|
|||
Abc_Print( -2, "\t-f : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck75? "yes": "no" );
|
||||
Abc_Print( -2, "\t-u : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck75u? "yes": "no" );
|
||||
Abc_Print( -2, "\t-z : toggles deriving LUTs when mapping into LUT structures [default = %s]\n", pPars->fDeriveLuts? "yes": "no" );
|
||||
Abc_Print( -2, "\t-t : toggles repacking LUTs into new structures [default = %s]\n", pPars->fRepack? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : prints the command usage\n");
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ struct If_Par_t_
|
|||
int fEnableCheck75u;// enable additional checking
|
||||
int fUseDsd; // compute DSD of the cut functions
|
||||
int fDeriveLuts; // enables deriving LUT structures
|
||||
int fRepack; // repack after mapping
|
||||
int fVerbose; // the verbosity flag
|
||||
char * pLutStruct; // LUT structure
|
||||
float WireDelay; // wire delay
|
||||
|
|
|
|||
|
|
@ -106,6 +106,14 @@ static inline Vec_Flt_t * Vec_FltStart( int nSize )
|
|||
memset( p->pArray, 0, sizeof(float) * nSize );
|
||||
return p;
|
||||
}
|
||||
static inline Vec_Flt_t * Vec_FltStartFull( int nSize )
|
||||
{
|
||||
Vec_Flt_t * p;
|
||||
p = Vec_FltAlloc( nSize );
|
||||
p->nSize = nSize;
|
||||
memset( p->pArray, 0xFF, sizeof(float) * nSize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue