blob: 51de973ae8b98ce7bfe94a7ca431a3c14dcf898c [file] [log] [blame]
/**CFile****************************************************************
FileName [llb1Sched.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [BDD based reachability.]
Synopsis [Partition scheduling algorithm.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: llb1Sched.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "llbInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Swaps two rows.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Llb_MtrSwapColumns( Llb_Mtr_t * p, int iCol1, int iCol2 )
{
Llb_Grp_t * pGemp;
char * pTemp;
int iTemp;
assert( iCol1 >= 0 && iCol1 < p->nCols );
assert( iCol2 >= 0 && iCol2 < p->nCols );
if ( iCol1 == iCol2 )
return;
assert( iCol1 != iCol2 );
// swap col groups
pGemp = p->pColGrps[iCol1];
p->pColGrps[iCol1] = p->pColGrps[iCol2];
p->pColGrps[iCol2] = pGemp;
// swap col vectors
pTemp = p->pMatrix[iCol1];
p->pMatrix[iCol1] = p->pMatrix[iCol2];
p->pMatrix[iCol2] = pTemp;
// swap col sums
iTemp = p->pColSums[iCol1];
p->pColSums[iCol1] = p->pColSums[iCol2];
p->pColSums[iCol2] = iTemp;
}
/**Function*************************************************************
Synopsis [Find columns which brings as few vars as possible.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Llb_MtrFindBestColumn( Llb_Mtr_t * p, int iGrpStart )
{
int Cost, Cost2, CostBest = ABC_INFINITY, Cost2Best = ABC_INFINITY;
int WeightCur, WeightBest = -ABC_INFINITY, iGrp = -1, iGrpBest = -1;
int k, c, iVar, Counter;
// find partition that reduces partial product as much as possible
for ( iVar = 0; iVar < p->nRows - p->nFfs; iVar++ )
{
if ( p->pRowSums[iVar] < 2 )
continue;
// look at present variables that can be quantified
if ( !(p->pProdVars[iVar] == 1 && p->pProdNums[iVar] == 1) )
continue;
// check that it appears in one partition only
Counter = 0;
for ( c = iGrpStart; c < p->nCols-1; c++ )
if ( p->pMatrix[c][iVar] == 1 )
{
iGrp = c;
Counter++;
}
assert( Counter == 1 );
if ( Counter != 1 )
Abc_Print( -1, "Llb_MtrFindBestColumn() Internal error!\n" );
// find weight of this column
WeightCur = 0;
for ( k = 0; k < p->nRows; k++ )
{
// increase weight if variable k will be quantified from partial product
if ( p->pProdVars[k] == 1 && p->pMatrix[iGrp][k] == 1 && p->pProdNums[k] == 1 )
WeightCur += 2;
// decrease weight if variable k will be added to partial product
if ( p->pProdVars[k] == 0 && p->pMatrix[iGrp][k] == 1 )
WeightCur--;
}
if ( WeightCur > 0 && WeightBest < WeightCur )
{
WeightBest = WeightCur;
iGrpBest = iGrp;
}
}
if ( iGrpBest >= 0 )
return iGrpBest;
// could not find the group with any vars to quantify
// select the group that contains as few extra variables as possible
// if there is a tie, select variables that appear in less groups than others
for ( iGrp = iGrpStart; iGrp < p->nCols-1; iGrp++ )
{
Cost = Cost2 = 0;
for ( k = 0; k < p->nRows; k++ )
if ( p->pProdVars[k] == 0 && p->pMatrix[iGrp][k] == 1 )
{
Cost++;
Cost2 += p->pProdNums[k];
}
if ( CostBest > Cost ||
(CostBest == Cost && Cost2 > Cost2Best) )
{
CostBest = Cost;
Cost2Best = Cost2;
iGrpBest = iGrp;
}
}
return iGrpBest;
}
/**Function*************************************************************
Synopsis [Returns the number of variables that will be saved.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Llb_MtrUseSelectedColumn( Llb_Mtr_t * p, int iCol )
{
int iVar;
assert( iCol >= 1 && iCol < p->nCols - 1 );
for ( iVar = 0; iVar < p->nRows; iVar++ )
{
if ( p->pMatrix[iCol][iVar] == 0 )
continue;
if ( p->pProdVars[iVar] == 1 && p->pProdNums[iVar] == 1 )
{
p->pProdVars[iVar] = 0;
p->pProdNums[iVar] = 0;
continue;
}
if ( p->pProdVars[iVar] == 0 )
{
p->pProdVars[iVar] = 1;
p->pProdNums[iVar] = p->pRowSums[iVar];
}
p->pProdNums[iVar]--;
assert( p->pProdNums[iVar] >= 0 );
if ( p->pProdNums[iVar] < 0 )
Abc_Print( -1, "Llb_MtrUseSelectedColumn() Internal error!\n" );
}
}
/**Function*************************************************************
Synopsis [Verify columns.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Llb_MtrVerifyColumns( Llb_Mtr_t * p, int iGrpStart )
{
int iVar, iGrp, Counter;
for ( iVar = 0; iVar < p->nRows; iVar++ )
{
if ( p->pProdVars[iVar] == 0 )
continue;
Counter = 0;
for ( iGrp = iGrpStart; iGrp < p->nCols; iGrp++ )
if ( p->pMatrix[iGrp][iVar] == 1 )
Counter++;
assert( Counter == p->pProdNums[iVar] );
if ( Counter != p->pProdNums[iVar] )
Abc_Print( -1, "Llb_MtrVerifyColumns(): Internal error.\n" );
}
}
/**Function*************************************************************
Synopsis [Matrix reduce.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Llb_MtrSchedule( Llb_Mtr_t * p )
{
int iGrp, iGrpBest, i;
// start partial product
for ( i = 0; i < p->nRows; i++ )
{
if ( i >= p->nPis && i < p->nPis + p->nFfs )
{
p->pProdVars[i] = 1;
p->pProdNums[i] = p->pRowSums[i] - 1;
}
else
{
p->pProdVars[i] = 0;
p->pProdNums[i] = p->pRowSums[i];
}
}
// order the partitions
Llb_MtrVerifyMatrix( p );
for ( iGrp = 1; iGrp < p->nCols-1; iGrp++ )
{
Llb_MtrVerifyColumns( p, iGrp );
iGrpBest = Llb_MtrFindBestColumn( p, iGrp );
Llb_MtrUseSelectedColumn( p, iGrpBest );
Llb_MtrSwapColumns( p, iGrp, iGrpBest );
}
Llb_MtrVerifyMatrix( p );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END