diff options
Diffstat (limited to 'src/base/abci')
-rw-r--r-- | src/base/abci/abc.c | 18 | ||||
-rw-r--r-- | src/base/abci/abcIvy.c | 4 | ||||
-rw-r--r-- | src/base/abci/abcPlace.c | 253 | ||||
-rw-r--r-- | src/base/abci/abcProve.c | 8 | ||||
-rw-r--r-- | src/base/abci/abcRewrite.c | 86 | ||||
-rw-r--r-- | src/base/abci/module.make | 1 |
6 files changed, 314 insertions, 56 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 30602af5..e7f8c8ea 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -2680,6 +2680,7 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) bool fUseZeros; bool fVerbose; bool fVeryVerbose; + bool fPlaceEnable; // external functions extern void Rwr_Precompute(); @@ -2693,8 +2694,9 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) fUseZeros = 0; fVerbose = 0; fVeryVerbose = 0; + fPlaceEnable = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "lxzvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "lxzvwph" ) ) != EOF ) { switch ( c ) { @@ -2713,6 +2715,9 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'w': fVeryVerbose ^= 1; break; + case 'p': + fPlaceEnable ^= 1; + break; case 'h': goto usage; default: @@ -2743,7 +2748,7 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) } // modify the current network - if ( !Abc_NtkRewrite( pNtk, fUpdateLevel, fUseZeros, fVerbose, fVeryVerbose ) ) + if ( !Abc_NtkRewrite( pNtk, fUpdateLevel, fUseZeros, fVerbose, fVeryVerbose, fPlaceEnable ) ) { fprintf( pErr, "Rewriting has failed.\n" ); return 1; @@ -2751,12 +2756,13 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - fprintf( pErr, "usage: rewrite [-lzvwh]\n" ); + fprintf( pErr, "usage: rewrite [-lzvwph]\n" ); fprintf( pErr, "\t performs technology-independent rewriting of the AIG\n" ); fprintf( pErr, "\t-l : toggle preserving the number of levels [default = %s]\n", fUpdateLevel? "yes": "no" ); fprintf( pErr, "\t-z : toggle using zero-cost replacements [default = %s]\n", fUseZeros? "yes": "no" ); fprintf( pErr, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-w : toggle printout subgraph statistics [default = %s]\n", fVeryVerbose? "yes": "no" ); + fprintf( pErr, "\t-p : toggle placement-aware rewriting [default = %s]\n", fPlaceEnable? "yes": "no" ); fprintf( pErr, "\t-h : print the command usage\n"); return 1; } @@ -5424,8 +5430,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) int nLevels; // extern Abc_Ntk_t * Abc_NtkNewAig( Abc_Ntk_t * pNtk ); // extern Abc_Ntk_t * Abc_NtkIvy( Abc_Ntk_t * pNtk ); - extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk ); - extern int Pr_ManProofTest( char * pFileName ); +// extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk ); +// extern int Pr_ManProofTest( char * pFileName ); pNtk = Abc_FrameReadNtk(pAbc); pOut = Abc_FrameReadOut(pAbc); @@ -5520,7 +5526,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); */ // Abc_NtkMaxFlowTest( pNtk ); - Pr_ManProofTest( "trace.cnf" ); +// Pr_ManProofTest( "trace.cnf" ); return 0; usage: diff --git a/src/base/abci/abcIvy.c b/src/base/abci/abcIvy.c index 00f8c183..0f0d9c8b 100644 --- a/src/base/abci/abcIvy.c +++ b/src/base/abci/abcIvy.c @@ -525,10 +525,10 @@ int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars ) if ( pParams->fUseRewriting && Abc_NtkNodeNum(pNtk) > 500 ) { pParams->fUseRewriting = 0; - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 ); Abc_NtkDelete( pNtkTemp ); - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 ); } diff --git a/src/base/abci/abcPlace.c b/src/base/abci/abcPlace.c new file mode 100644 index 00000000..5ceffd6f --- /dev/null +++ b/src/base/abci/abcPlace.c @@ -0,0 +1,253 @@ +/**CFile**************************************************************** + + FileName [abcPlace.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Network and node package.] + + Synopsis [Interface with a placer.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: abcPlace.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "abc.h" + +// placement includes +#include "place_base.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +AbstractCell *abstractCells = NULL; +ConcreteCell *cells = NULL; +ConcreteNet *nets = NULL; +int nAllocSize = 0; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates a new cell.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Abc_PlaceCreateCell( Abc_Obj_t * pObj, int fAnd ) +{ + assert( cells[pObj->Id].m_id == 0 ); + + cells[pObj->Id].m_id = pObj->Id; + cells[pObj->Id].m_label = ""; + cells[pObj->Id].m_parent = &(abstractCells[fAnd]); + cells[pObj->Id].m_fixed = 0; + addConcreteCell(&(cells[pObj->Id])); +} + +/**Function************************************************************* + + Synopsis [Updates the net.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Abc_PlaceUpdateNet( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int k; + // free the old array of net terminals + if ( nets[pObj->Id].m_terms ) + free( nets[pObj->Id].m_terms ); + // fill in the net with the new information + nets[pObj->Id].m_id = pObj->Id; + nets[pObj->Id].m_weight = 1.0; + nets[pObj->Id].m_numTerms = Abc_ObjFanoutNum(pObj); //fanout + nets[pObj->Id].m_terms = ALLOC(ConcreteCell*, Abc_ObjFanoutNum(pObj)); + Abc_ObjForEachFanout( pObj, pFanout, k ) + nets[pObj->Id].m_terms[k] = &(cells[pFanout->Id]); + addConcreteNet(&(nets[pObj->Id])); +} + +/**Function************************************************************* + + Synopsis [Returns the placement cost of the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float Abc_PlaceEvaluateCut( Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins ) +{ + Abc_Obj_t * pObj; +// double x, y; + int i; + Vec_PtrForEachEntry( vFanins, pObj, i ) + { +// pObj->Id + } + return 0.0; +} + +/**Function************************************************************* + + Synopsis [Updates placement after one step of rewriting.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_PlaceUpdate( Vec_Ptr_t * vUpdates, int nNodesOld ) +{ + Abc_Obj_t * pObj, * pFanin; + int i, k; + Vec_Ptr_t * vCells, * vNets; + + // start the arrays of new cells and nets + vCells = Vec_PtrAlloc( 16 ); + vNets = Vec_PtrAlloc( 32 ); + + // go through the modified nodes + Vec_PtrForEachEntry( vUpdates, pObj, i ) + { + if ( pObj->Id > nNodesOld ) // pObj is a new node + { + Abc_PlaceCreateCell( pObj, 1 ); + Abc_PlaceUpdateNet( pObj ); + + // add the new cell and its fanin nets to temporary storage + Vec_PtrPush( vCells, &(cells[pObj->Id]) ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + Vec_PtrPushUnique( vNets, &(nets[pFanin->Id]) ); + } + else // pObj is an old node + { + Abc_PlaceUpdateNet( Abc_ObjFanin0(pObj) ); + Abc_PlaceUpdateNet( Abc_ObjFanin1(pObj) ); + } + } + + // update the placement +// fastPlace( Vec_PtrSize(vCells), (ConcreteCell **)Vec_PtrArray(vCells), +// Vec_PtrSize(vNets), (ConcreteNet **)Vec_PtrArray(vNets) ); + + // clean up + Vec_PtrFree( vCells ); + Vec_PtrFree( vNets ); +} + +/**Function************************************************************* + + Synopsis [This procedure is called before the writing start.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_PlaceBegin( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + + // allocate and clean internal storage + nAllocSize = 5 * Abc_NtkObjNumMax(pNtk); + cells = REALLOC(ConcreteCell, cells, nAllocSize); + nets = REALLOC(ConcreteNet, nets, nAllocSize); + memset( cells, 0, sizeof(ConcreteCell) * nAllocSize ); + memset( nets, 0, sizeof(ConcreteNet) * nAllocSize ); + + // create AbstractCells + // 1: pad + // 2: and + if (!abstractCells) + abstractCells = ALLOC(AbstractCell,2); + + abstractCells[0].m_height = 1.0; + abstractCells[0].m_width = 1.0; + abstractCells[0].m_label = "pio"; + abstractCells[0].m_pad = 1; + + abstractCells[1].m_height = 1.0; + abstractCells[1].m_width = 1.0; + abstractCells[1].m_label = "and"; + abstractCells[1].m_pad = 0; + + // input pads + Abc_NtkForEachCi( pNtk, pObj, i ) + Abc_PlaceCreateCell( pObj, 0 ); + + // ouput pads + Abc_NtkForEachCo( pNtk, pObj, i ) + Abc_PlaceCreateCell( pObj, 0 ); + + // AND nodes + Abc_AigForEachAnd( pNtk, pObj, i ) + Abc_PlaceCreateCell( pObj, 1 ); + + // all nets + Abc_NtkForEachObj( pNtk, pObj, i ) + { + if ( !Abc_ObjIsCi(pObj) && !Abc_ObjIsNode(pObj) ) + continue; + Abc_PlaceUpdateNet( pObj ); + } + + globalPreplace((float)0.8); + globalPlace(); +} + +/**Function************************************************************* + + Synopsis [This procedure is called after the writing completes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_PlaceEnd( Abc_Ntk_t * pNtk ) +{ + int i; + + + // clean up + for ( i = 0; i < nAllocSize; i++ ) + FREE( nets[i].m_terms ); + FREE( abstractCells ); + FREE( cells ); + FREE( nets ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abcProve.c b/src/base/abci/abcProve.c index 6d1ed161..a4220216 100644 --- a/src/base/abci/abcProve.c +++ b/src/base/abci/abcProve.c @@ -133,13 +133,13 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars ) break; */ /* - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 ) break; if ( --Counter == 0 ) break; */ - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 ) break; if ( --Counter == 0 ) @@ -328,9 +328,9 @@ void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, int clk, int fVerbose Abc_Ntk_t * Abc_NtkMiterRwsat( Abc_Ntk_t * pNtk ) { Abc_Ntk_t * pNtkTemp; - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 ); Abc_NtkDelete( pNtkTemp ); - Abc_NtkRewrite( pNtk, 0, 0, 0, 0 ); + Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 ); Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 ); return pNtk; } diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c index e7dbf3a1..a3209275 100644 --- a/src/base/abci/abcRewrite.c +++ b/src/base/abci/abcRewrite.c @@ -36,6 +36,10 @@ static Cut_Man_t * Abc_NtkStartCutManForRewrite( Abc_Ntk_t * pNtk ); static void Abc_NodePrintCuts( Abc_Obj_t * pNode ); static void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ); +extern void Abc_PlaceBegin( Abc_Ntk_t * pNtk ); +extern void Abc_PlaceEnd( Abc_Ntk_t * pNtk ); +extern void Abc_PlaceUpdate( Vec_Ptr_t * vUpdates, int nNodesOld ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -51,18 +55,28 @@ static void Abc_ManShowCutCone( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ); SeeAlso [] ***********************************************************************/ -int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose ) +int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable ) { ProgressBar * pProgress; Cut_Man_t * pManCut; Rwr_Man_t * pManRwr; Abc_Obj_t * pNode; - int i, nNodes, nGain; + Vec_Ptr_t * vUpdates = NULL; + Dec_Graph_t * pGraph; + int i, nNodes, nGain, fCompl; int clk, clkStart = clock(); assert( Abc_NtkIsStrash(pNtk) ); // cleanup the AIG Abc_AigCleanup(pNtk->pManFunc); + + // start placement package + if ( fPlaceEnable ) + { + Abc_PlaceBegin( pNtk ); + vUpdates = Abc_AigUpdateStart( pNtk->pManFunc ); + } + // start the rewriting manager pManRwr = Rwr_ManStart( 0 ); if ( pManRwr == NULL ) @@ -88,61 +102,37 @@ Rwr_ManAddTimeCuts( pManRwr, clock() - clk ); // stop if all nodes have been tried once if ( i >= nNodes ) break; - // skip the constant node -// if ( Abc_NodeIsConst(pNode) ) -// continue; // skip persistant nodes if ( Abc_NodeIsPersistant(pNode) ) continue; // skip the nodes with many fanouts if ( Abc_ObjFanoutNum(pNode) > 1000 ) continue; -//printf( "*******Node %d: \n", pNode->Id ); // for each cut, try to resynthesize it - nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUpdateLevel, fUseZeros ); - if ( nGain > 0 || nGain == 0 && fUseZeros ) - { -// extern void Abc_RwrExpWithCut( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves ); - - Dec_Graph_t * pGraph = Rwr_ManReadDecs(pManRwr); - int fCompl = Rwr_ManReadCompl(pManRwr); + nGain = Rwr_NodeRewrite( pManRwr, pManCut, pNode, fUpdateLevel, fUseZeros, fPlaceEnable ); + if ( !(nGain > 0 || nGain == 0 && fUseZeros) ) + continue; + // if we end up here, a rewriting step is accepted -// Abc_RwrExpWithCut( pNode, Rwr_ManReadLeaves(pManRwr) ); + // get hold of the new subgraph to be added to the AIG + pGraph = Rwr_ManReadDecs(pManRwr); + fCompl = Rwr_ManReadCompl(pManRwr); -/* - { - Abc_Obj_t * pObj; - int i; - printf( "USING: (" ); - Vec_PtrForEachEntry( Rwr_ManReadLeaves(pManRwr), pObj, i ) - printf( "%d ", Abc_ObjFanoutNum(Abc_ObjRegular(pObj)) ); - printf( ") Gain = %d.\n", nGain ); - } -*/ - -// if ( nGain > 0 ) -// Abc_ManShowCutCone( pNode, Rwr_ManReadLeaves(pManRwr) ); + // reset the array of the changed nodes + if ( fPlaceEnable ) + Abc_AigUpdateReset( pNtk->pManFunc ); -/* - if ( nGain > 0 ) - { // print stats on the MFFC - extern void Abc_NodeMffsConeSuppPrint( Abc_Obj_t * pNode ); - printf( "Node %6d : Gain = %4d ", pNode->Id, nGain ); - Abc_NodeMffsConeSuppPrint( pNode ); - } -*/ - // complement the FF if needed - if ( fCompl ) Dec_GraphComplement( pGraph ); + // complement the FF if needed + if ( fCompl ) Dec_GraphComplement( pGraph ); clk = clock(); - Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); + Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); Rwr_ManAddTimeUpdate( pManRwr, clock() - clk ); - if ( fCompl ) Dec_GraphComplement( pGraph ); -// { -// extern int s_TotalChanges; -// s_TotalChanges++; -// } - } + if ( fCompl ) Dec_GraphComplement( pGraph ); + + // use the array of changed nodes to update placement + if ( fPlaceEnable ) + Abc_PlaceUpdate( vUpdates, nNodes ); } Extra_ProgressBarStop( pProgress ); Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart ); @@ -156,6 +146,14 @@ Rwr_ManAddTimeTotal( pManRwr, clock() - clkStart ); Rwr_ManStop( pManRwr ); Cut_ManStop( pManCut ); pNtk->pManCut = NULL; + + // start placement package + if ( fPlaceEnable ) + { + Abc_PlaceEnd( pNtk ); + Abc_AigUpdateStop( pNtk->pManFunc ); + } + // put the nodes into the DFS order and reassign their IDs Abc_NtkReassignIds( pNtk ); // Abc_AigCheckFaninOrder( pNtk->pManFunc ); diff --git a/src/base/abci/module.make b/src/base/abci/module.make index 97f42f0e..4aa05d07 100644 --- a/src/base/abci/module.make +++ b/src/base/abci/module.make @@ -26,6 +26,7 @@ SRC += src/base/abci/abc.c \ src/base/abci/abcNtbdd.c \ src/base/abci/abcOdc.c \ src/base/abci/abcOrder.c \ + src/base/abci/abcPlace.c \ src/base/abci/abcPrint.c \ src/base/abci/abcProve.c \ src/base/abci/abcReconv.c \ |