/**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