summaryrefslogtreecommitdiffstats
path: root/src/opt/lpk/lpkAbcDec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/opt/lpk/lpkAbcDec.c')
-rw-r--r--src/opt/lpk/lpkAbcDec.c130
1 files changed, 102 insertions, 28 deletions
diff --git a/src/opt/lpk/lpkAbcDec.c b/src/opt/lpk/lpkAbcDec.c
index e9f8d0df..aa2d4bc0 100644
--- a/src/opt/lpk/lpkAbcDec.c
+++ b/src/opt/lpk/lpkAbcDec.c
@@ -39,17 +39,21 @@
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Lpk_ImplementFun( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Lpk_Fun_t * p )
+Abc_Obj_t * Lpk_ImplementFun( Lpk_Man_t * pMan, Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Lpk_Fun_t * p )
{
extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
unsigned * pTruth;
Abc_Obj_t * pObjNew;
int i;
+ if ( p->fMark )
+ pMan->nMuxes++;
+ else
+ pMan->nDsds++;
// create the new node
pObjNew = Abc_NtkCreateNode( pNtk );
for ( i = 0; i < (int)p->nVars; i++ )
- Abc_ObjAddFanin( pObjNew, Vec_PtrEntry(vLeaves, p->pFanins[i]) );
- Abc_ObjLevelNew( pObjNew );
+ Abc_ObjAddFanin( pObjNew, Abc_ObjRegular(Vec_PtrEntry(vLeaves, p->pFanins[i])) );
+ Abc_ObjSetLevel( pObjNew, Abc_ObjLevelNew(pObjNew) );
// assign the node's function
pTruth = Lpk_FunTruth(p, 0);
if ( p->nVars == 0 )
@@ -78,18 +82,48 @@ Abc_Obj_t * Lpk_ImplementFun( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Lpk_Fun_t *
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Lpk_Implement( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, int nLeavesOld )
+Abc_Obj_t * Lpk_Implement_rec( Lpk_Man_t * pMan, Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Lpk_Fun_t * pFun )
{
- Lpk_Fun_t * pFun;
- Abc_Obj_t * pRes;
+ Abc_Obj_t * pFanin, * pRes;
int i;
- for ( i = Vec_PtrSize(vLeaves) - 1; i >= nLeavesOld; i-- )
+ // prepare the leaves of the function
+ for ( i = 0; i < (int)pFun->nVars; i++ )
{
- pFun = Vec_PtrEntry( vLeaves, i );
- pRes = Lpk_ImplementFun( pNtk, vLeaves, pFun );
- Vec_PtrWriteEntry( vLeaves, i, pRes );
- Lpk_FunFree( pFun );
+ pFanin = Vec_PtrEntry( vLeaves, pFun->pFanins[i] );
+ if ( !Abc_ObjIsComplement(pFanin) )
+ Lpk_Implement_rec( pMan, pNtk, vLeaves, (Lpk_Fun_t *)pFanin );
+ pFanin = Vec_PtrEntry( vLeaves, pFun->pFanins[i] );
+ assert( Abc_ObjIsComplement(pFanin) );
}
+ // construct the function
+ pRes = Lpk_ImplementFun( pMan, pNtk, vLeaves, pFun );
+ // replace the function
+ Vec_PtrWriteEntry( vLeaves, pFun->Id, Abc_ObjNot(pRes) );
+ Lpk_FunFree( pFun );
+ return pRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Implements the function.]
+
+ Description [Returns the node implementing this function.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Obj_t * Lpk_Implement( Lpk_Man_t * pMan, Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, int nLeavesOld )
+{
+ Abc_Obj_t * pFanin, * pRes;
+ int i;
+ assert( nLeavesOld < Vec_PtrSize(vLeaves) );
+ // mark implemented nodes
+ Vec_PtrForEachEntryStop( vLeaves, pFanin, i, nLeavesOld )
+ Vec_PtrWriteEntry( vLeaves, i, Abc_ObjNot(pFanin) );
+ // recursively construct starting from the first entry
+ pRes = Lpk_Implement_rec( pMan, pNtk, vLeaves, Vec_PtrEntry( vLeaves, nLeavesOld ) );
Vec_PtrShrink( vLeaves, nLeavesOld );
return pRes;
}
@@ -107,10 +141,13 @@ Abc_Obj_t * Lpk_Implement( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, int nLeavesOld
SeeAlso []
***********************************************************************/
-int Lpk_Decompose_rec( Lpk_Fun_t * p )
+int Lpk_Decompose_rec( Lpk_Man_t * pMan, Lpk_Fun_t * p )
{
+ static Lpk_Res_t Res0, * pRes0 = &Res0;
Lpk_Res_t * pResMux, * pResDsd;
Lpk_Fun_t * p2;
+ int clk;
+
// is only called for non-trivial blocks
assert( p->nLutK >= 3 && p->nLutK <= 6 );
assert( p->nVars > p->nLutK );
@@ -120,18 +157,37 @@ int Lpk_Decompose_rec( Lpk_Fun_t * p )
// skip if delay bound is exceeded
if ( Lpk_SuppDelay(p->uSupp, p->pDelays) > (int)p->nDelayLim )
return 0;
+
+ // compute supports if needed
+ if ( !p->fSupports )
+ Lpk_FunComputeCofSupps( p );
+
+ // check DSD decomposition
+clk = clock();
+ pResDsd = Lpk_DsdAnalize( pMan, p, pMan->pPars->nVarsShared );
+pMan->timeEvalDsdAn += clock() - clk;
+ if ( pResDsd && (pResDsd->nBSVars == (int)p->nLutK || pResDsd->nBSVars == (int)p->nLutK - 1) &&
+ pResDsd->AreaEst <= (int)p->nAreaLim && pResDsd->DelayEst <= (int)p->nDelayLim )
+ {
+clk = clock();
+ p2 = Lpk_DsdSplit( pMan, p, pResDsd->pCofVars, pResDsd->nCofVars, pResDsd->BSVars );
+pMan->timeEvalDsdSp += clock() - clk;
+ assert( p2->nVars <= (int)p->nLutK );
+ if ( p->nVars > p->nLutK && !Lpk_Decompose_rec( pMan, p ) )
+ return 0;
+ return 1;
+ }
+
// check MUX decomposition
- pResMux = Lpk_MuxAnalize( p );
+clk = clock();
+ pResMux = Lpk_MuxAnalize( pMan, p );
+pMan->timeEvalMuxAn += clock() - clk;
+// pResMux = NULL;
assert( !pResMux || (pResMux->DelayEst <= (int)p->nDelayLim && pResMux->AreaEst <= (int)p->nAreaLim) );
// accept MUX decomposition if it is "good"
if ( pResMux && pResMux->nSuppSizeS <= (int)p->nLutK && pResMux->nSuppSizeL <= (int)p->nLutK )
pResDsd = NULL;
- else
- {
- pResDsd = Lpk_DsdAnalize( p );
- assert( !pResDsd || (pResDsd->DelayEst <= (int)p->nDelayLim && pResDsd->AreaEst <= (int)p->nAreaLim) );
- }
- if ( pResMux && pResDsd )
+ else if ( pResMux && pResDsd )
{
// compare two decompositions
if ( pResMux->AreaEst < pResDsd->AreaEst ||
@@ -144,18 +200,22 @@ int Lpk_Decompose_rec( Lpk_Fun_t * p )
assert( pResMux == NULL || pResDsd == NULL );
if ( pResMux )
{
- p2 = Lpk_MuxSplit( p, pResMux->pCofVars[0], pResMux->Polarity );
- if ( p2->nVars > p->nLutK && !Lpk_Decompose_rec( p2 ) )
+clk = clock();
+ p2 = Lpk_MuxSplit( pMan, p, pResMux->Variable, pResMux->Polarity );
+pMan->timeEvalMuxSp += clock() - clk;
+ if ( p2->nVars > p->nLutK && !Lpk_Decompose_rec( pMan, p2 ) )
return 0;
- if ( p->nVars > p->nLutK && !Lpk_Decompose_rec( p ) )
+ if ( p->nVars > p->nLutK && !Lpk_Decompose_rec( pMan, p ) )
return 0;
return 1;
}
if ( pResDsd )
{
- p2 = Lpk_DsdSplit( p, pResDsd->pCofVars, pResDsd->nCofVars, pResDsd->BSVars );
+clk = clock();
+ p2 = Lpk_DsdSplit( pMan, p, pResDsd->pCofVars, pResDsd->nCofVars, pResDsd->BSVars );
+pMan->timeEvalDsdSp += clock() - clk;
assert( p2->nVars <= (int)p->nLutK );
- if ( p->nVars > p->nLutK && !Lpk_Decompose_rec( p ) )
+ if ( p->nVars > p->nLutK && !Lpk_Decompose_rec( pMan, p ) )
return 0;
return 1;
}
@@ -193,17 +253,31 @@ void Lpk_DecomposeClean( Vec_Ptr_t * vLeaves, int nLeavesOld )
SeeAlso []
***********************************************************************/
-Abc_Obj_t * Lpk_Decompose( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsigned * pTruth, int nLutK, int AreaLim, int DelayLim )
+Abc_Obj_t * Lpk_Decompose( Lpk_Man_t * p, Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsigned * pTruth, unsigned * puSupps, int nLutK, int AreaLim, int DelayLim )
{
Lpk_Fun_t * pFun;
Abc_Obj_t * pObjNew = NULL;
int nLeaves = Vec_PtrSize( vLeaves );
pFun = Lpk_FunCreate( pNtk, vLeaves, pTruth, nLutK, AreaLim, DelayLim );
+ if ( puSupps[0] || puSupps[1] )
+ {
+/*
+ int i;
+ Lpk_FunComputeCofSupps( pFun );
+ for ( i = 0; i < nLeaves; i++ )
+ {
+ assert( pFun->puSupps[2*i+0] == puSupps[2*i+0] );
+ assert( pFun->puSupps[2*i+1] == puSupps[2*i+1] );
+ }
+*/
+ memcpy( pFun->puSupps, puSupps, sizeof(unsigned) * 2 * nLeaves );
+ pFun->fSupports = 1;
+ }
Lpk_FunSuppMinimize( pFun );
if ( pFun->nVars <= pFun->nLutK )
- pObjNew = Lpk_ImplementFun( pNtk, vLeaves, pFun );
- else if ( Lpk_Decompose_rec(pFun) )
- pObjNew = Lpk_Implement( pNtk, vLeaves, nLeaves );
+ pObjNew = Lpk_ImplementFun( p, pNtk, vLeaves, pFun );
+ else if ( Lpk_Decompose_rec(p, pFun) )
+ pObjNew = Lpk_Implement( p, pNtk, vLeaves, nLeaves );
Lpk_DecomposeClean( vLeaves, nLeaves );
return pObjNew;
}