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