Commit 9f5ef0d6 by Alan Mishchenko

Version abc70831

parent ddc6d1c1
......@@ -1542,6 +1542,22 @@ SOURCE=.\src\opt\lpk\lpk.h
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkAbcCore.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkAbcDsd.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkAbcFun.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkAbcMux.c
# End Source File
# Begin Source File
SOURCE=.\src\opt\lpk\lpkCore.c
# End Source File
# Begin Source File
......
......@@ -143,6 +143,7 @@ static inline int Kit_DsdLitRegular( int Lit ) { return Li
static inline unsigned Kit_DsdObjOffset( int nFans ) { return (nFans >> 2) + ((nFans & 3) > 0); }
static inline unsigned * Kit_DsdObjTruth( Kit_DsdObj_t * pObj ) { return pObj->Type == KIT_DSD_PRIME ? (unsigned *)pObj->pFans + pObj->Offset: NULL; }
static inline int Kit_DsdNtkObjNum( Kit_DsdNtk_t * pNtk ){ return pNtk->nVars + pNtk->nNodes; }
static inline Kit_DsdObj_t * Kit_DsdNtkObj( Kit_DsdNtk_t * pNtk, int Id ) { assert( Id >= 0 && Id < pNtk->nVars + pNtk->nNodes ); return Id < pNtk->nVars ? NULL : pNtk->pNodes[Id - pNtk->nVars]; }
static inline Kit_DsdObj_t * Kit_DsdNtkRoot( Kit_DsdNtk_t * pNtk ) { return Kit_DsdNtkObj( pNtk, Kit_DsdLit2Var(pNtk->Root) ); }
static inline int Kit_DsdLitIsLeaf( Kit_DsdNtk_t * pNtk, int Lit ) { int Id = Kit_DsdLit2Var(Lit); assert( Id >= 0 && Id < pNtk->nVars + pNtk->nNodes ); return Id < pNtk->nVars; }
......@@ -429,6 +430,25 @@ static inline void Kit_TruthMux( unsigned * pOut, unsigned * pIn0, unsigned * pI
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
pOut[w] = (pIn0[w] & ~pCtrl[w]) | (pIn1[w] & pCtrl[w]);
}
static inline void Kit_TruthIthVar( unsigned * pTruth, int nVars, int iVar )
{
unsigned Masks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
int k, nWords = (nVars <= 5 ? 1 : (1 << (nVars - 5)));
if ( iVar < 5 )
{
for ( k = 0; k < nWords; k++ )
pTruth[k] = Masks[iVar];
}
else
{
for ( k = 0; k < nWords; k++ )
if ( k & (1 << (iVar-5)) )
pTruth[k] = ~(unsigned)0;
else
pTruth[k] = 0;
}
}
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
......@@ -453,12 +473,13 @@ extern DdNode * Kit_SopToBdd( DdManager * dd, Kit_Sop_t * cSop, int nVars
extern DdNode * Kit_GraphToBdd( DdManager * dd, Kit_Graph_t * pGraph );
extern DdNode * Kit_TruthToBdd( DdManager * dd, unsigned * pTruth, int nVars, int fMSBonTop );
/*=== kitDsd.c ==========================================================*/
extern Kit_DsdMan_t * Kit_DsdManAlloc( int nVars );
extern Kit_DsdMan_t * Kit_DsdManAlloc( int nVars, int nNodes );
extern void Kit_DsdManFree( Kit_DsdMan_t * p );
extern Kit_DsdNtk_t * Kit_DsdDeriveNtk( unsigned * pTruth, int nVars, int nLutSize );
extern unsigned * Kit_DsdTruthCompute( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, unsigned uSupp );
extern void Kit_DsdTruth( Kit_DsdNtk_t * pNtk, unsigned * pTruthRes );
extern void Kit_DsdTruthPartial( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, unsigned * pTruthRes, unsigned uSupp );
extern void Kit_DsdTruthPartialTwo( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, unsigned uSupp, int iVar, unsigned * pTruthCo, unsigned * pTruthDec );
extern void Kit_DsdPrint( FILE * pFile, Kit_DsdNtk_t * pNtk );
extern void Kit_DsdPrintExpanded( Kit_DsdNtk_t * pNtk );
extern void Kit_DsdPrintFromTruth( unsigned * pTruth, int nVars );
......
......@@ -39,7 +39,7 @@
SeeAlso []
***********************************************************************/
Kit_DsdMan_t * Kit_DsdManAlloc( int nVars )
Kit_DsdMan_t * Kit_DsdManAlloc( int nVars, int nNodes )
{
Kit_DsdMan_t * p;
p = ALLOC( Kit_DsdMan_t, 1 );
......@@ -47,7 +47,7 @@ Kit_DsdMan_t * Kit_DsdManAlloc( int nVars )
p->nVars = nVars;
p->nWords = Kit_TruthWordNum( p->nVars );
p->vTtElems = Vec_PtrAllocTruthTables( p->nVars );
p->vTtNodes = Vec_PtrAllocSimInfo( 1024, p->nWords );
p->vTtNodes = Vec_PtrAllocSimInfo( nNodes, p->nWords );
return p;
}
......@@ -472,11 +472,40 @@ unsigned * Kit_DsdTruthCompute( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, unsigned
SeeAlso []
***********************************************************************/
void Kit_DsdTruthComputeTwo( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, unsigned uSupp, int iVar )
{
unsigned * pTruthRes;
int i;
// if support is specified, request that supports are available
if ( uSupp )
Kit_DsdGetSupports( pNtk );
// assign elementary truth tables
assert( pNtk->nVars <= p->nVars );
for ( i = 0; i < (int)pNtk->nVars; i++ )
Kit_TruthCopy( Vec_PtrEntry(p->vTtNodes, i), Vec_PtrEntry(p->vTtElems, i), p->nVars );
// compute truth table for each node
pTruthRes = Kit_DsdTruthComputeNode_rec( p, pNtk, Kit_DsdLit2Var(pNtk->Root), uSupp );
// complement the truth table if needed
if ( Kit_DsdLitIsCompl(pNtk->Root) )
Kit_TruthNot( pTruthRes, pTruthRes, pNtk->nVars );
}
/**Function*************************************************************
Synopsis [Derives the truth table of the DSD network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Kit_DsdTruth( Kit_DsdNtk_t * pNtk, unsigned * pTruthRes )
{
Kit_DsdMan_t * p;
unsigned * pTruth;
p = Kit_DsdManAlloc( pNtk->nVars );
p = Kit_DsdManAlloc( pNtk->nVars, Kit_DsdNtkObjNum(pNtk) );
pTruth = Kit_DsdTruthCompute( p, pNtk, 0 );
Kit_TruthCopy( pTruthRes, pTruth, pNtk->nVars );
Kit_DsdManFree( p );
......@@ -501,6 +530,29 @@ void Kit_DsdTruthPartial( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, unsigned * pTru
/**Function*************************************************************
Synopsis [Derives the truth table of the DSD network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Kit_DsdTruthPartialTwo( Kit_DsdMan_t * p, Kit_DsdNtk_t * pNtk, unsigned uSupp, int iVar, unsigned * pTruthCo, unsigned * pTruthDec )
{
unsigned * pTruth;
Kit_DsdObj_t * pRoot;
Kit_DsdTruthComputeTwo( p, pNtk, uSupp, iVar );
pRoot = Kit_DsdNtkRoot( pNtk );
pTruth = Vec_PtrEntry( p->vTtNodes, 2*pRoot->Id+0 );
Kit_TruthCopy( pTruthCo, pTruth, p->nVars );
pTruth = Vec_PtrEntry( p->vTtNodes, 2*pRoot->Id+1 );
Kit_TruthCopy( pTruthDec, pTruth, p->nVars );
}
/**Function*************************************************************
Synopsis [Counts the number of blocks of the given number of inputs.]
Description []
......@@ -1620,7 +1672,7 @@ int Kit_DsdEval( unsigned * pTruth, int nVars, int nLutSize )
// printf( "Eval = %d.\n", Result );
// recompute the truth table
p = Kit_DsdManAlloc( nVars );
p = Kit_DsdManAlloc( nVars, Kit_DsdNtkObjNum(pNtk) );
pTruthC = Kit_DsdTruthCompute( p, pNtk, 0 );
if ( !Extra_TruthIsEqual( pTruth, pTruthC, nVars ) )
printf( "Verification failed.\n" );
......@@ -1645,7 +1697,7 @@ void Kit_DsdVerify( Kit_DsdNtk_t * pNtk, unsigned * pTruth, int nVars )
{
Kit_DsdMan_t * p;
unsigned * pTruthC;
p = Kit_DsdManAlloc( nVars );
p = Kit_DsdManAlloc( nVars, Kit_DsdNtkObjNum(pNtk) );
pTruthC = Kit_DsdTruthCompute( p, pNtk, 0 );
if ( !Extra_TruthIsEqual( pTruth, pTruthC, nVars ) )
printf( "Verification failed.\n" );
......@@ -1687,7 +1739,7 @@ void Kit_DsdTest( unsigned * pTruth, int nVars )
// Kit_DsdTestCofs( pNtk, pTruth );
// recompute the truth table
p = Kit_DsdManAlloc( nVars );
p = Kit_DsdManAlloc( nVars, Kit_DsdNtkObjNum(pNtk) );
pTruthC = Kit_DsdTruthCompute( p, pNtk, 0 );
// Extra_PrintBinary( stdout, pTruth, 1 << nVars ); printf( "\n" );
// Extra_PrintBinary( stdout, pTruthC, 1 << nVars ); printf( "\n" );
......@@ -1757,7 +1809,7 @@ void Kit_DsdPrecompute4Vars()
printf( "\n" );
*/
p = Kit_DsdManAlloc( 4 );
p = Kit_DsdManAlloc( 4, Kit_DsdNtkObjNum(pNtk) );
pTruthC = Kit_DsdTruthCompute( p, pNtk, 0 );
if ( !Extra_TruthIsEqual( &uTruth, pTruthC, 4 ) )
printf( "Verification failed.\n" );
......
......@@ -5160,7 +5160,7 @@ usage:
Description []
SideEffects []
SeeAlso []
***********************************************************************/
......@@ -11278,6 +11278,11 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Only works for structrally hashed networks.\n" );
return 1;
}
if ( !Abc_NtkLatchNum(pNtk) )
{
fprintf( pErr, "Only works for sequential networks.\n" );
return 1;
}
// modify the current network
pNtkRes = Abc_NtkDarLatchSweep( pNtk, fLatchSweep, fVerbose );
if ( pNtkRes == NULL )
......@@ -11367,6 +11372,11 @@ int Abc_CommandCycle( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Only works for strashed networks or logic SOP networks.\n" );
return 1;
}
if ( !Abc_NtkLatchNum(pNtk) )
{
fprintf( pErr, "Only works for sequential networks.\n" );
return 1;
}
if ( Abc_NtkIsStrash(pNtk) )
Abc_NtkCycleInitState( pNtk, nFrames, fVerbose );
......@@ -11457,7 +11467,11 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Only works for strashed networks.\n" );
return 1;
}
if ( !Abc_NtkLatchNum(pNtk) )
{
fprintf( pErr, "Only works for sequential networks.\n" );
return 1;
}
Abc_NtkXValueSimulate( pNtk, nFrames, fXInputs, fXState, fVerbose );
return 0;
......
......@@ -834,8 +834,8 @@ int Abc_NtkDSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fVer
// conver to the manager
pMan = Abc_NtkToDar( pNtk, 0 );
// derive CNF
// pCnf = Cnf_Derive( pMan, 0 );
pCnf = Cnf_DeriveSimple( pMan, 0 );
pCnf = Cnf_Derive( pMan, 0 );
// pCnf = Cnf_DeriveSimple( pMan, 0 );
// convert into the SAT solver
pSat = Cnf_DataWriteIntoSolver( pCnf );
vCiIds = Cnf_DataCollectPiSatNums( pCnf, pMan );
......
......@@ -366,7 +366,7 @@ timeFind += clock() - clk2;
Vec_PtrPush( vPartsAll, vPart );
Vec_PtrPush( vPartSuppsAll, vPartSupp );
Vec_PtrPush( vPartSuppsChar, Abc_NtkSuppCharStart(vOne, Abc_NtkPiNum(pNtk)) );
Vec_PtrPush( vPartSuppsChar, Abc_NtkSuppCharStart(vOne, Abc_NtkCiNum(pNtk)) );
}
else
{
......@@ -380,7 +380,7 @@ timeFind += clock() - clk2;
// reinsert new support
Vec_PtrWriteEntry( vPartSuppsAll, iPart, vPartSupp );
Abc_NtkSuppCharAdd( Vec_PtrEntry(vPartSuppsChar, iPart), vOne, Abc_NtkPiNum(pNtk) );
Abc_NtkSuppCharAdd( Vec_PtrEntry(vPartSuppsChar, iPart), vOne, Abc_NtkCiNum(pNtk) );
}
}
......@@ -801,7 +801,7 @@ Abc_Ntk_t * Abc_NtkFraigPartitioned( Abc_Ntk_t * pNtk, void * pParams )
// perform partitioning
assert( Abc_NtkIsStrash(pNtk) );
// vParts = Abc_NtkPartitionNaive( pNtk, 20 );
vParts = Abc_NtkPartitionSmart( pNtk, 0, 1 );
vParts = Abc_NtkPartitionSmart( pNtk, 0, 0 );
Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "unset progressbar" );
......
/**CFile****************************************************************
FileName [lpkAbcCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Fast Boolean matching for LUT structures.]
Synopsis [The new core procedure.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpkAbcCore.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "lpkInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Implements the function.]
Description [Returns the node implementing this function.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Lpk_FunImplement( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Lpk_Fun_t * p )
{
Abc_Obj_t * pObjNew;
int i;
pObjNew = Abc_NtkCreateNode( pNtk );
for ( i = 0; i < (int)p->nVars; i++ )
Abc_ObjAddFanin( pObjNew, Vec_PtrEntry(vLeaves, p->pFanins[i]) );
Abc_ObjLevelNew( pObjNew );
// create the logic function
{
extern Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph );
// allocate memory for the ISOP
Vec_Int_t * vCover = Vec_IntAlloc( 0 );
// transform truth table into the decomposition tree
Kit_Graph_t * pGraph = Kit_TruthToGraph( Lpk_FunTruth(p, 0), p->nVars, vCover );
// derive the AIG for the decomposition tree
pObjNew->pData = Kit_GraphToHop( pNtk->pManFunc, pGraph );
Kit_GraphFree( pGraph );
Vec_IntFree( vCover );
}
return pObjNew;
}
/**Function*************************************************************
Synopsis [Implements the function.]
Description [Returns the node implementing this function.]
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Lpk_LptImplement( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, int nLeavesOld )
{
Lpk_Fun_t * pFun;
Abc_Obj_t * pRes;
int i;
for ( i = Vec_PtrSize(vLeaves) - 1; i >= nLeavesOld; i-- )
{
pFun = Vec_PtrEntry( vLeaves, i );
pRes = Lpk_FunImplement( pNtk, vLeaves, pFun );
Vec_PtrWriteEntry( vLeaves, i, pRes );
Lpk_FunFree( pFun );
}
return pRes;
}
/**Function*************************************************************
Synopsis [Decomposes the function using recursive MUX decomposition.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Lpk_LpkDecompose_rec( Lpk_Fun_t * p )
{
Lpk_Fun_t * p2;
int VarPol;
assert( p->nAreaLim > 0 );
if ( p->nVars <= p->nLutK )
return 1;
// check if decomposition exists
VarPol = Lpk_FunAnalizeMux( p );
if ( VarPol == -1 )
return 0;
// split and call recursively
p2 = Lpk_FunSplitMux( p, VarPol );
if ( !Lpk_LpkDecompose_rec( p2 ) )
return 0;
return Lpk_LpkDecompose_rec( p );
}
/**Function*************************************************************
Synopsis [Decomposes the function using recursive MUX decomposition.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Obj_t * Lpk_LpkDecompose( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsigned * pTruth, int nLutK, int AreaLim, int DelayLim )
{
Lpk_Fun_t * p;
Abc_Obj_t * pObjNew = NULL;
int i, nLeaves;
// create the starting function
nLeaves = Vec_PtrSize( vLeaves );
p = Lpk_FunCreate( pNtk, vLeaves, pTruth, nLutK, AreaLim, DelayLim );
Lpk_FunSuppMinimize( p );
// decompose the function
if ( Lpk_LpkDecompose_rec(p) )
pObjNew = Lpk_LptImplement( pNtk, vLeaves, nLeaves );
else
{
for ( i = Vec_PtrSize(vLeaves) - 1; i >= nLeaves; i-- )
Lpk_FunFree( Vec_PtrEntry(vLeaves, i) );
}
Vec_PtrShrink( vLeaves, nLeaves );
return pObjNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [lpkAbcFun.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Fast Boolean matching for LUT structures.]
Synopsis [Procedures working on decomposed functions.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpkAbcFun.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "lpkInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates the function.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Lpk_Fun_t * Lpk_FunAlloc( int nVars )
{
Lpk_Fun_t * p;
p = (Lpk_Fun_t *)malloc( sizeof(Lpk_Fun_t) + sizeof(unsigned) * Kit_TruthWordNum(nVars) * 3 );
memset( p, 0, sizeof(Lpk_Fun_t) );
return p;
}
/**Function*************************************************************
Synopsis [Deletes the function]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Lpk_FunFree( Lpk_Fun_t * p )
{
free( p );
}
/**Function*************************************************************
Synopsis [Creates the starting function.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Lpk_Fun_t * Lpk_FunCreate( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsigned * pTruth, int nLutK, int AreaLim, int DelayLim )
{
Lpk_Fun_t * p;
Abc_Obj_t * pNode;
int i;
p = Lpk_FunAlloc( Vec_PtrSize(vLeaves) );
p->Id = Vec_PtrSize(vLeaves);
p->vNodes = vLeaves;
p->nVars = Vec_PtrSize(vLeaves);
p->nLutK = nLutK;
p->nAreaLim = AreaLim;
p->nDelayLim = DelayLim;
p->uSupp = Kit_TruthSupport( pTruth, p->nVars );
Kit_TruthCopy( Lpk_FunTruth(p,0), pTruth, p->nVars );
Vec_PtrForEachEntry( vLeaves, pNode, i )
{
p->pFanins[i] = i;
p->pDelays[i] = pNode->Level;
}
Vec_PtrPush( p->vNodes, p );
return p;
}
/**Function*************************************************************
Synopsis [Creates the new function with the given truth table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Lpk_Fun_t * Lpk_FunDup( Lpk_Fun_t * p, unsigned * pTruth )
{
Lpk_Fun_t * pNew;
pNew = Lpk_FunAlloc( p->nVars );
pNew->Id = Vec_PtrSize(p->vNodes);
pNew->vNodes = p->vNodes;
pNew->nVars = p->nVars;
pNew->nLutK = p->nLutK;
pNew->nAreaLim = p->nAreaLim;
pNew->nDelayLim = p->nDelayLim;
pNew->uSupp = Kit_TruthSupport( pTruth, p->nVars );
Kit_TruthCopy( Lpk_FunTruth(pNew,0), pTruth, p->nVars );
memcpy( pNew->pFanins, p->pFanins, 16 );
memcpy( pNew->pDelays, p->pDelays, 16 );
Vec_PtrPush( p->vNodes, pNew );
return p;
}
/**Function*************************************************************
Synopsis [Minimizes support of the function.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Lpk_FunSuppMinimize( Lpk_Fun_t * p )
{
int j, k, nVarsNew;
// compress the truth table
if ( p->uSupp == Kit_BitMask(p->nVars) )
return;
// minimize support
nVarsNew = Kit_WordCountOnes(p->uSupp);
Kit_TruthShrink( Lpk_FunTruth(p, 1), Lpk_FunTruth(p, 0), nVarsNew, p->nVars, p->uSupp, 1 );
for ( j = k = 0; j < (int)p->nVars; j++ )
if ( p->uSupp & (1 << j) )
{
p->pFanins[k] = p->pFanins[j];
p->pDelays[k] = p->pDelays[j];
k++;
}
assert( k == nVarsNew );
p->nVars = k;
p->uSupp = Kit_BitMask(p->nVars);
}
/**Function*************************************************************
Synopsis [Get the delay of the bound set.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Lpk_SuppDelay( unsigned uSupp, char * pDelays )
{
int Delay, Var;
Delay = 0;
Lpk_SuppForEachVar( uSupp, Var )
Delay = ABC_MAX( Delay, pDelays[Var] );
return Delay + 1;
}
/**Function*************************************************************
Synopsis [Converts support into variables.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Lpk_SuppToVars( unsigned uBoundSet, char * pVars )
{
int i, nVars = 0;
Lpk_SuppForEachVar( uBoundSet, i )
pVars[nVars++] = i;
return nVars;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [lpkAbcMux.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Fast Boolean matching for LUT structures.]
Synopsis [Iterative MUX decomposition.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: lpkAbcMux.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "lpkInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes cofactors w.r.t. the given var.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Lpk_FunComputeCofs( Lpk_Fun_t * p, int iVar )
{
unsigned * pTruth = Lpk_FunTruth( p, 0 );
unsigned * pTruth0 = Lpk_FunTruth( p, 1 );
unsigned * pTruth1 = Lpk_FunTruth( p, 2 );
Kit_TruthCofactor0New( pTruth0, pTruth, p->nVars, iVar );
Kit_TruthCofactor1New( pTruth1, pTruth, p->nVars, iVar );
}
/**Function*************************************************************
Synopsis [Computes cofactors w.r.t. each variable.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Lpk_FunComputeCofSupps( Lpk_Fun_t * p, unsigned * puSupps )
{
unsigned * pTruth = Lpk_FunTruth( p, 0 );
unsigned * pTruth0 = Lpk_FunTruth( p, 1 );
unsigned * pTruth1 = Lpk_FunTruth( p, 2 );
int Var;
Lpk_SuppForEachVar( p->uSupp, Var )
{
Lpk_FunComputeCofs( p, Var );
puSupps[2*Var+0] = Kit_TruthSupport( pTruth0, p->nVars );
puSupps[2*Var+1] = Kit_TruthSupport( pTruth1, p->nVars );
}
}
/**Function*************************************************************
Synopsis [Checks the possibility of MUX decomposition.]
Description [Returns the best variable to use for MUX decomposition.]
SideEffects []
SeeAlso []
***********************************************************************/
int Lpk_FunAnalizeMux( Lpk_Fun_t * p )
{
unsigned puSupps[32] = {0};
int nSuppSize0, nSuppSize1, Delay, Delay0, Delay1, DelayA, DelayB;
int Var, Area, Polarity, VarBest, AreaBest, PolarityBest, nSuppSizeBest;
if ( p->nVars > p->nAreaLim * (p->nLutK - 1) + 1 )
return -1;
// get cofactor supports for each variable
Lpk_FunComputeCofSupps( p, puSupps );
// derive the delay and area of each MUX-decomposition
VarBest = -1;
Lpk_SuppForEachVar( p->uSupp, Var )
{
nSuppSize0 = Kit_WordCountOnes(puSupps[2*Var+0]);
nSuppSize1 = Kit_WordCountOnes(puSupps[2*Var+1]);
if ( nSuppSize0 <= (int)p->nLutK - 2 && nSuppSize1 <= (int)p->nLutK - 2 )
{
// include cof var into 0-block
DelayA = Lpk_SuppDelay( puSupps[2*Var+0] | (1<<Var), p->pDelays );
DelayB = Lpk_SuppDelay( puSupps[2*Var+1] , p->pDelays );
Delay0 = ABC_MAX( DelayA, DelayB + 1 );
// include cof var into 1-block
DelayA = Lpk_SuppDelay( puSupps[2*Var+1] | (1<<Var), p->pDelays );
DelayB = Lpk_SuppDelay( puSupps[2*Var+0] , p->pDelays );
Delay1 = ABC_MAX( DelayA, DelayB + 1 );
// get the best delay
Delay = ABC_MIN( Delay0, Delay1 );
Area = 2;
Polarity = (int)(Delay1 == Delay);
}
else if ( nSuppSize0 <= (int)p->nLutK - 2 )
{
DelayA = Lpk_SuppDelay( puSupps[2*Var+0] | (1<<Var), p->pDelays );
DelayB = Lpk_SuppDelay( puSupps[2*Var+1] , p->pDelays );
Delay = ABC_MAX( DelayA, DelayB + 1 );
Area = 1 + Lpk_LutNumLuts( nSuppSize1, p->nLutK );
Polarity = 0;
}
else if ( nSuppSize0 <= (int)p->nLutK )
{
DelayA = Lpk_SuppDelay( puSupps[2*Var+1] | (1<<Var), p->pDelays );
DelayB = Lpk_SuppDelay( puSupps[2*Var+0] , p->pDelays );
Delay = ABC_MAX( DelayA, DelayB + 1 );
Area = 1 + Lpk_LutNumLuts( nSuppSize1+2, p->nLutK );
Polarity = 1;
}
else if ( nSuppSize1 <= (int)p->nLutK - 2 )
{
DelayA = Lpk_SuppDelay( puSupps[2*Var+1] | (1<<Var), p->pDelays );
DelayB = Lpk_SuppDelay( puSupps[2*Var+0] , p->pDelays );
Delay = ABC_MAX( DelayA, DelayB + 1 );
Area = 1 + Lpk_LutNumLuts( nSuppSize0, p->nLutK );
Polarity = 1;
}
else if ( nSuppSize1 <= (int)p->nLutK )
{
DelayA = Lpk_SuppDelay( puSupps[2*Var+0] | (1<<Var), p->pDelays );
DelayB = Lpk_SuppDelay( puSupps[2*Var+1] , p->pDelays );
Delay = ABC_MAX( DelayA, DelayB + 1 );
Area = 1 + Lpk_LutNumLuts( nSuppSize0+2, p->nLutK );
Polarity = 0;
}
else
{
// include cof var into 0-block
DelayA = Lpk_SuppDelay( puSupps[2*Var+0] | (1<<Var), p->pDelays );
DelayB = Lpk_SuppDelay( puSupps[2*Var+1] , p->pDelays );
Delay0 = ABC_MAX( DelayA, DelayB + 1 );
// include cof var into 1-block
DelayA = Lpk_SuppDelay( puSupps[2*Var+1] | (1<<Var), p->pDelays );
DelayB = Lpk_SuppDelay( puSupps[2*Var+0] , p->pDelays );
Delay1 = ABC_MAX( DelayA, DelayB + 1 );
// get the best delay
Delay = ABC_MIN( Delay0, Delay1 );
if ( Delay == Delay0 )
Area = Lpk_LutNumLuts( nSuppSize0+2, p->nLutK ) + Lpk_LutNumLuts( nSuppSize1, p->nLutK );
else
Area = Lpk_LutNumLuts( nSuppSize1+2, p->nLutK ) + Lpk_LutNumLuts( nSuppSize0, p->nLutK );
Polarity = (int)(Delay1 == Delay);
}
// find the best variable
if ( Delay > (int)p->nDelayLim )
continue;
if ( Area > (int)p->nAreaLim )
continue;
if ( VarBest == -1 || AreaBest > Area || (AreaBest == Area && nSuppSizeBest > nSuppSize0+nSuppSize1) )
{
VarBest = Var;
AreaBest = Area;
PolarityBest = Polarity;
nSuppSizeBest = nSuppSize0+nSuppSize1;
}
}
return (VarBest == -1)? -1 : (2*VarBest + Polarity);
}
/**Function*************************************************************
Synopsis [Transforms the function decomposed by the MUX decomposition.]
Description [Returns the best variable to use for MUX decomposition.]
SideEffects []
SeeAlso []
***********************************************************************/
Lpk_Fun_t * Lpk_FunSplitMux( Lpk_Fun_t * p, int VarPol )
{
Lpk_Fun_t * pNew;
unsigned * pTruth = Lpk_FunTruth( p, 0 );
unsigned * pTruth0 = Lpk_FunTruth( p, 1 );
unsigned * pTruth1 = Lpk_FunTruth( p, 2 );
int Var = VarPol / 2;
int Pol = VarPol % 2;
int iVarVac;
assert( VarPol >= 0 && VarPol < 2 * (int)p->nVars );
assert( p->nAreaLim >= 2 );
Lpk_FunComputeCofs( p, Var );
if ( Pol == 0 )
{
// derive the new component
pNew = Lpk_FunDup( p, pTruth1 );
// update the old component
p->uSupp = Kit_TruthSupport( pTruth0, p->nVars );
iVarVac = Kit_WordFindFirstBit( ~(p->uSupp | (1 << Var)) );
assert( iVarVac < (int)p->nVars );
Kit_TruthIthVar( pTruth, p->nVars, iVarVac );
// update the truth table
Kit_TruthMux( pTruth, pTruth0, pTruth1, pTruth, p->nVars );
p->pFanins[iVarVac] = pNew->Id;
p->pDelays[iVarVac] = Lpk_SuppDelay( pNew->uSupp, pNew->pDelays );
// support minimize both
Lpk_FunSuppMinimize( p );
Lpk_FunSuppMinimize( pNew );
// update delay and area requirements
pNew->nDelayLim = p->nDelayLim - 1;
if ( p->nVars <= p->nLutK )
{
pNew->nAreaLim = p->nAreaLim - 1;
p->nAreaLim = 1;
}
else if ( pNew->nVars <= pNew->nLutK )
{
pNew->nAreaLim = 1;
p->nAreaLim = p->nAreaLim - 1;
}
else if ( p->nVars < pNew->nVars )
{
pNew->nAreaLim = p->nAreaLim / 2 + p->nAreaLim % 2;
p->nAreaLim = p->nAreaLim / 2 - p->nAreaLim % 2;
}
else // if ( pNew->nVars < p->nVars )
{
pNew->nAreaLim = p->nAreaLim / 2 - p->nAreaLim % 2;
p->nAreaLim = p->nAreaLim / 2 + p->nAreaLim % 2;
}
}
return p;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
......@@ -258,11 +258,6 @@ p->timeCuts += clock() - clk;
if ( p->pPars->fFirst && i == 1 )
break;
if ( p->pObj->Id == 8835 )
{
int x = 0;
}
// compute the truth table
clk = clock();
pTruth = Lpk_CutTruth( p, pCut );
......@@ -312,6 +307,91 @@ p->timeEval += clock() - clk;
/**Function*************************************************************
Synopsis [Performs resynthesis for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Lpk_ResynthesizeNodeNew( Lpk_Man_t * p )
{
static int Count = 0;
Vec_Ptr_t * vLeaves;
Abc_Obj_t * pObjNew;
Lpk_Cut_t * pCut;
unsigned * pTruth;
void * pDsd = NULL;
int i, k, clk;
// compute the cuts
clk = clock();
if ( !Lpk_NodeCuts( p ) )
{
p->timeCuts += clock() - clk;
return 0;
}
p->timeCuts += clock() - clk;
if ( p->pPars->fVeryVerbose )
printf( "Node %5d : Mffc size = %5d. Cuts = %5d.\n", p->pObj->Id, p->nMffc, p->nEvals );
vLeaves = Vec_PtrAlloc( 32 );
// try the good cuts
p->nCutsTotal += p->nCuts;
p->nCutsUseful += p->nEvals;
for ( i = 0; i < p->nEvals; i++ )
{
// get the cut
pCut = p->pCuts + p->pEvals[i];
if ( p->pPars->fFirst && i == 1 )
break;
// collect nodes into the array
Vec_PtrClear( vLeaves );
for ( k = 0; k < (int)pCut->nLeaves; k++ )
Vec_PtrPush( vLeaves, Abc_NtkObj(p->pNtk, pCut->pLeaves[i]) );
// compute the truth table
clk = clock();
pTruth = Lpk_CutTruth( p, pCut );
p->timeTruth += clock() - clk;
if ( p->pPars->fVeryVerbose )
{
// char * pFileName;
int nSuppSize;
Kit_DsdNtk_t * pDsdNtk;
nSuppSize = Extra_TruthSupportSize(pTruth, pCut->nLeaves);
printf( " C%02d: L= %2d/%2d V= %2d/%d N= %d W= %4.2f ",
i, pCut->nLeaves, nSuppSize, pCut->nNodes, pCut->nNodesDup, pCut->nLuts, pCut->Weight );
pDsdNtk = Kit_DsdDecompose( pTruth, pCut->nLeaves );
// Kit_DsdVerify( pDsdNtk, pTruth, pCut->nLeaves );
Kit_DsdPrint( stdout, pDsdNtk );
Kit_DsdNtkFree( pDsdNtk );
// Kit_DsdPrintFromTruth( pTruth, pCut->nLeaves );
// pFileName = Kit_TruthDumpToFile( pTruth, pCut->nLeaves, Count++ );
// printf( "Saved truth table in file \"%s\".\n", pFileName );
}
// update the network
clk = clock();
pObjNew = Lpk_LpkDecompose( p->pNtk, vLeaves, pTruth, p->pPars->nLutSize,
(int)pCut->nNodes - (int)pCut->nNodesDup - 1, Abc_ObjRequiredLevel(p->pObj) );
p->timeEval += clock() - clk;
// perform replacement
if ( pObjNew )
Abc_NtkUpdate( p->pObj, pObjNew, p->vLevels );
}
Vec_PtrFree( vLeaves );
return 1;
}
/**Function*************************************************************
Synopsis [Performs resynthesis for one network.]
Description []
......
......@@ -410,14 +410,6 @@ void Lpk_NodeCutsOne( Lpk_Man_t * p, Lpk_Cut_t * pCut, int Node )
// initialize the set of leaves to the nodes in the cut
assert( p->nCuts < LPK_CUTS_MAX );
pCutNew = p->pCuts + p->nCuts;
/*
if ( p->pObj->Id == 31 && Node == 38 && pCut->pNodes[0] == 31 && pCut->pNodes[1] == 34 && pCut->pNodes[2] == 35 )//p->nCuts == 48 )
{
int x = 0;
printf( "Start:\n" );
Lpk_NodePrintCut( p, pCut );
}
*/
pCutNew->nLeaves = 0;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
if ( pCut->pLeaves[i] != Node )
......@@ -443,47 +435,30 @@ if ( p->pObj->Id == 31 && Node == 38 && pCut->pNodes[0] == 31 && pCut->pNodes[1]
assert( pCutNew->nLeaves <= LPK_SIZE_MAX );
}
/*
printf( " Trying cut: " );
Lpk_NodePrintCut( p, pCutNew, 1 );
printf( "\n" );
*/
// skip the contained cuts
Lpk_NodeCutSignature( pCutNew );
if ( Lpk_NodeCutsOneFilter( p->pCuts, p->nCuts, pCutNew ) )
return;
// update the set of internal nodes
assert( pCut->nNodes < LPK_SIZE_MAX );
memcpy( pCutNew->pNodes, pCut->pNodes, pCut->nNodes * sizeof(int) );
pCutNew->nNodes = pCut->nNodes;
pCutNew->pNodes[ pCutNew->nNodes++ ] = Node;
// add the marked node
pCutNew->nNodesDup = pCut->nNodesDup + !Abc_NodeIsTravIdCurrent(pObj);
/*
if ( p->pObj->Id == 31 && Node == 38 )//p->nCuts == 48 )
{
int x = 0;
printf( "Finish:\n" );
Lpk_NodePrintCut( p, pCutNew );
}
*/
pCutNew->nNodesDup = pCut->nNodesDup;
// check if the node is already there
for ( i = 0; i < (int)pCutNew->nNodes; i++ )
if ( pCutNew->pNodes[i] == Node )
break;
if ( i == (int)pCutNew->nNodes ) // new node
{
pCutNew->pNodes[ pCutNew->nNodes++ ] = Node;
pCutNew->nNodesDup += !Abc_NodeIsTravIdCurrent(pObj);
}
// the number of nodes does not exceed MFFC plus duplications
assert( pCutNew->nNodes <= p->nMffc + pCutNew->nNodesDup );
// add the cut to storage
assert( p->nCuts < LPK_CUTS_MAX );
p->nCuts++;
// assert( pCut->nNodes <= p->nMffc + pCutNew->nNodesDup );
/*
printf( " Creating cut: " );
Lpk_NodePrintCut( p, pCutNew, 1 );
printf( "\n" );
*/
// if ( !(pCut->nNodes <= p->nMffc + pCutNew->nNodesDup) )
// printf( "Assertion in line 477 failed.\n" );
}
/**Function*************************************************************
......@@ -527,13 +502,6 @@ int Lpk_NodeCuts( Lpk_Man_t * p )
// try to expand the fanins of this cut
for ( k = 0; k < (int)pCut->nLeaves; k++ )
{
if ( p->pObj->Id == 28 && i == 273 && k == 13 )
{
Abc_Obj_t * pFanin = Abc_NtkObj(p->pNtk, pCut->pLeaves[k]);
int s = 0;
}
// create a new cut
Lpk_NodeCutsOne( p, pCut, pCut->pLeaves[k] );
// quit if the number of cuts has exceeded the limit
......@@ -559,7 +527,7 @@ int Lpk_NodeCuts( Lpk_Man_t * p )
continue;
// compute the minimum number of LUTs needed to implement this cut
// V = N * (K-1) + 1 ~~~~~ N = Ceiling[(V-1)/(K-1)] = (V-1)/(K-1) + [(V-1)%(K-1) > 0]
pCut->nLuts = (pCut->nLeaves-1)/(p->pPars->nLutSize-1) + ( (pCut->nLeaves-1)%(p->pPars->nLutSize-1) > 0 );
pCut->nLuts = Lpk_LutNumLuts( pCut->nLeaves, p->pPars->nLutSize );
pCut->Weight = (float)1.0 * (pCut->nNodes - pCut->nNodesDup) / pCut->nLuts; //p->pPars->nLutsMax;
if ( pCut->Weight <= 1.001 )
continue;
......
......@@ -117,6 +117,47 @@ struct Lpk_Man_t_
int timeTotal;
};
// preliminary decomposition result
typedef struct Lpk_Res_t_ Lpk_Res_t;
struct Lpk_Res_t_
{
int nBSVars;
unsigned BSVars;
int nCofVars;
char pCofVars[4];
int nSuppSizeS;
int nSuppSizeL;
int DelayEst;
int AreaEst;
};
// function to be decomposed
typedef struct Lpk_Fun_t_ Lpk_Fun_t;
struct Lpk_Fun_t_
{
Vec_Ptr_t * vNodes; // the array of all functions
unsigned int Id : 5; // the ID of this node
unsigned int nVars : 5; // the number of variables
unsigned int nLutK : 4; // the number of LUT inputs
unsigned int nAreaLim : 8; // the area limit (the largest allowed)
unsigned int nDelayLim : 10; // the delay limit (the largest allowed)
char pFanins[16]; // the fanins of this function
char pDelays[16]; // the delays of the inputs
unsigned uSupp; // the support of this component
unsigned pTruth[0]; // the truth table (contains room for three truth tables)
};
#define Lpk_SuppForEachVar( Supp, Var )\
for ( Var = 0; Var < 16; Var++ )\
if ( !(Supp & (1<<Var)) ) {} else
static inline int Lpk_LutNumVars( int nLutsLim, int nLutK ) { return nLutsLim * (nLutK - 1) + 1; }
static inline int Lpk_LutNumLuts( int nVarsMax, int nLutK ) { return (nVarsMax - 1) / (nLutK - 1) + (int)((nVarsMax - 1) % (nLutK - 1) > 0); }
static inline unsigned * Lpk_FunTruth( Lpk_Fun_t * p, int Num ) { assert( Num < 3 ); return p->pTruth + Kit_TruthWordNum(p->nVars) * Num; }
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
......@@ -136,6 +177,24 @@ struct Lpk_Man_t_
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== lpkAbcCore.c ============================================================*/
extern Abc_Obj_t * Lpk_LpkDecompose( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsigned * pTruth, int nLutK, int AreaLim, int DelayLim );
/*=== lpkAbcFun.c ============================================================*/
extern Lpk_Fun_t * Lpk_FunAlloc( int nVars );
extern void Lpk_FunFree( Lpk_Fun_t * p );
extern Lpk_Fun_t * Lpk_FunCreate( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsigned * pTruth, int nLutK, int AreaLim, int DelayLim );
extern Lpk_Fun_t * Lpk_FunDup( Lpk_Fun_t * p, unsigned * pTruth );
extern void Lpk_FunSuppMinimize( Lpk_Fun_t * p );
extern int Lpk_SuppDelay( unsigned uSupp, char * pDelays );
extern int Lpk_SuppToVars( unsigned uBoundSet, char * pVars );
/*=== lpkAbcDsd.c ============================================================*/
extern Lpk_Res_t * Lpk_FunAnalizeDsd( Lpk_Fun_t * p, int nCofDepth );
extern Lpk_Fun_t * Lpk_FunSplitDsd( Lpk_Fun_t * p, char * pCofVars, int nCofVars, unsigned uBoundSet );
/*=== lpkAbcMux.c ============================================================*/
extern int Lpk_FunAnalizeMux( Lpk_Fun_t * p );
extern Lpk_Fun_t * Lpk_FunSplitMux( Lpk_Fun_t * p, int VarPol );
/*=== lpkCut.c =========================================================*/
extern unsigned * Lpk_CutTruth( Lpk_Man_t * p, Lpk_Cut_t * pCut );
extern int Lpk_NodeCuts( Lpk_Man_t * p );
......
......@@ -54,7 +54,7 @@ Lpk_Man_t * Lpk_ManStart( Lpk_Par_t * pPars )
p->vCover = Vec_IntAlloc( 1 << 12 );
for ( i = 0; i < 8; i++ )
p->vSets[i] = Vec_IntAlloc(100);
p->pDsdMan = Kit_DsdManAlloc( pPars->nVarsMax );
p->pDsdMan = Kit_DsdManAlloc( pPars->nVarsMax, 64 );
return p;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment