diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2008-01-30 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2008-01-30 08:01:00 -0800 |
commit | 4d30a1e4f1edecff86d5066ce4653a370e59e5e1 (patch) | |
tree | 366355938a4af0a92f848841ac65374f338d691b /src/opt | |
parent | 6537f941887b06e588d3acfc97b5fdf48875cc4e (diff) | |
download | abc-4d30a1e4f1edecff86d5066ce4653a370e59e5e1.tar.gz abc-4d30a1e4f1edecff86d5066ce4653a370e59e5e1.tar.bz2 abc-4d30a1e4f1edecff86d5066ce4653a370e59e5e1.zip |
Version abc80130
Diffstat (limited to 'src/opt')
100 files changed, 1154 insertions, 20668 deletions
diff --git a/src/opt/cut/abcCut.c b/src/opt/cut/abcCut.c deleted file mode 100644 index 9bbd5790..00000000 --- a/src/opt/cut/abcCut.c +++ /dev/null @@ -1,492 +0,0 @@ -/**CFile**************************************************************** - - FileName [abcCut.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Interface to cut computation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: abcCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "cut.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq ); -static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq ); - - -extern int nTotal, nGood, nEqual; - -// temporary -//Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ) { return NULL; } -Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ) -{ - Vec_Int_t * vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 ); - int i; - Abc_Obj_t * pObj; - -// Abc_NtkForEachCi( pNtk, pObj, i ) -// Vec_IntWriteEntry( vAttrs, pObj->Id, 1 ); - - Abc_NtkForEachObj( pNtk, pObj, i ) - { -// if ( Abc_ObjIsNode(pObj) && (rand() % 4 == 0) ) - if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) ) - Vec_IntWriteEntry( vAttrs, pObj->Id, 1 ); - } - return vAttrs; -} - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) -{ - ProgressBar * pProgress; - Cut_Man_t * p; - Abc_Obj_t * pObj, * pNode; - Vec_Ptr_t * vNodes; - Vec_Int_t * vChoices; - int i; - int clk = clock(); - - extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk ); - extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk ); - - nTotal = nGood = nEqual = 0; - - assert( Abc_NtkIsStrash(pNtk) ); - // start the manager - pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); - p = Cut_ManStart( pParams ); - // compute node attributes if local or global cuts are requested - if ( pParams->fGlobal || pParams->fLocal ) - { - extern Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk ); - Cut_ManSetNodeAttrs( p, Abc_NtkGetNodeAttributes(pNtk) ); - } - // prepare for cut dropping - if ( pParams->fDrop ) - Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) ); - // set cuts for PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - if ( Abc_ObjFanoutNum(pObj) > 0 ) - Cut_NodeSetTriv( p, pObj->Id ); - // compute cuts for internal nodes - vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs - vChoices = Vec_IntAlloc( 100 ); - pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodes) ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - // when we reached a CO, it is time to deallocate the cuts - if ( Abc_ObjIsCo(pObj) ) - { - if ( pParams->fDrop ) - Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); - continue; - } - // skip constant node, it has no cuts -// if ( Abc_NodeIsConst(pObj) ) -// continue; - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // compute the cuts to the internal node - Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree ); - // consider dropping the fanins cuts - if ( pParams->fDrop ) - { - Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); - Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) ); - } - // add cuts due to choices - if ( Abc_AigNodeIsChoice(pObj) ) - { - Vec_IntClear( vChoices ); - for ( pNode = pObj; pNode; pNode = pNode->pData ) - Vec_IntPush( vChoices, pNode->Id ); - Cut_NodeUnionCuts( p, vChoices ); - } - } - Extra_ProgressBarStop( pProgress ); - Vec_PtrFree( vNodes ); - Vec_IntFree( vChoices ); -PRT( "Total", clock() - clk ); -//Abc_NtkPrintCuts( p, pNtk, 0 ); -// Cut_ManPrintStatsToFile( p, pNtk->pSpec, clock() - clk ); - - // temporary printout of stats - if ( nTotal ) - printf( "Total cuts = %d. Good cuts = %d. Ratio = %5.2f\n", nTotal, nGood, ((double)nGood)/nTotal ); - return p; -} - -/**Function************************************************************* - - Synopsis [Cut computation using the oracle.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p ) -{ - Abc_Obj_t * pObj; - Vec_Ptr_t * vNodes; - int i, clk = clock(); - int fDrop = Cut_OracleReadDrop(p); - - assert( Abc_NtkIsStrash(pNtk) ); - - // prepare cut droppping - if ( fDrop ) - Cut_OracleSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) ); - - // set cuts for PIs - Abc_NtkForEachCi( pNtk, pObj, i ) - if ( Abc_ObjFanoutNum(pObj) > 0 ) - Cut_OracleNodeSetTriv( p, pObj->Id ); - - // compute cuts for internal nodes - vNodes = Abc_AigDfs( pNtk, 0, 1 ); // collects POs - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - // when we reached a CO, it is time to deallocate the cuts - if ( Abc_ObjIsCo(pObj) ) - { - if ( fDrop ) - Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); - continue; - } - // skip constant node, it has no cuts -// if ( Abc_NodeIsConst(pObj) ) -// continue; - // compute the cuts to the internal node - Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), - Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); - // consider dropping the fanins cuts - if ( fDrop ) - { - Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) ); - Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId1(pObj) ); - } - } - Vec_PtrFree( vNodes ); -//PRT( "Total", clock() - clk ); -//Abc_NtkPrintCuts_( p, pNtk, 0 ); -} - - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams ) -{ -/* - Cut_Man_t * p; - Abc_Obj_t * pObj, * pNode; - int i, nIters, fStatus; - Vec_Int_t * vChoices; - int clk = clock(); - - assert( Abc_NtkIsSeq(pNtk) ); - assert( pParams->fSeq ); -// assert( Abc_NtkIsDfsOrdered(pNtk) ); - - // start the manager - pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); - pParams->nCutSet = Abc_NtkCutSetNodeNum( pNtk ); - p = Cut_ManStart( pParams ); - - // set cuts for the constant node and the PIs - pObj = Abc_AigConst1(pNtk); - if ( Abc_ObjFanoutNum(pObj) > 0 ) - Cut_NodeSetTriv( p, pObj->Id ); - Abc_NtkForEachPi( pNtk, pObj, i ) - { -//printf( "Setting trivial cut %d.\n", pObj->Id ); - Cut_NodeSetTriv( p, pObj->Id ); - } - // label the cutset nodes and set their number in the array - // assign the elementary cuts to the cutset nodes - Abc_SeqForEachCutsetNode( pNtk, pObj, i ) - { - assert( pObj->fMarkC == 0 ); - pObj->fMarkC = 1; - pObj->pCopy = (Abc_Obj_t *)i; - Cut_NodeSetTriv( p, pObj->Id ); -//printf( "Setting trivial cut %d.\n", pObj->Id ); - } - - // process the nodes - vChoices = Vec_IntAlloc( 100 ); - for ( nIters = 0; nIters < 10; nIters++ ) - { -//printf( "ITERATION %d:\n", nIters ); - // compute the cuts for the internal nodes - Abc_AigForEachAnd( pNtk, pObj, i ) - { - Abc_NodeGetCutsSeq( p, pObj, nIters==0 ); - // add cuts due to choices - if ( Abc_AigNodeIsChoice(pObj) ) - { - Vec_IntClear( vChoices ); - for ( pNode = pObj; pNode; pNode = pNode->pData ) - Vec_IntPush( vChoices, pNode->Id ); - Cut_NodeUnionCutsSeq( p, vChoices, (pObj->fMarkC ? (int)pObj->pCopy : -1), nIters==0 ); - } - } - // merge the new cuts with the old cuts - Abc_NtkForEachPi( pNtk, pObj, i ) - Cut_NodeNewMergeWithOld( p, pObj->Id ); - Abc_AigForEachAnd( pNtk, pObj, i ) - Cut_NodeNewMergeWithOld( p, pObj->Id ); - // for the cutset, transfer temp cuts to new cuts - fStatus = 0; - Abc_SeqForEachCutsetNode( pNtk, pObj, i ) - fStatus |= Cut_NodeTempTransferToNew( p, pObj->Id, i ); - if ( fStatus == 0 ) - break; - } - Vec_IntFree( vChoices ); - - // if the status is not finished, transfer new to old for the cutset - Abc_SeqForEachCutsetNode( pNtk, pObj, i ) - Cut_NodeNewMergeWithOld( p, pObj->Id ); - - // transfer the old cuts to the new positions - Abc_NtkForEachObj( pNtk, pObj, i ) - Cut_NodeOldTransferToNew( p, pObj->Id ); - - // unlabel the cutset nodes - Abc_SeqForEachCutsetNode( pNtk, pObj, i ) - pObj->fMarkC = 0; -if ( pParams->fVerbose ) -{ -PRT( "Total", clock() - clk ); -printf( "Converged after %d iterations.\n", nIters ); -} -//Abc_NtkPrintCuts( p, pNtk, 1 ); - return p; -*/ -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree ) -{ - void * pList; - if ( pList = Abc_NodeReadCuts( p, pObj ) ) - return pList; - Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fDag, fTree ); - Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fDag, fTree ); - return Abc_NodeGetCuts( p, pObj, fDag, fTree ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree ) -{ - Abc_Obj_t * pFanin; - int fDagNode, fTriv, TreeCode = 0; -// assert( Abc_NtkIsStrash(pObj->pNtk) ); - assert( Abc_ObjFaninNum(pObj) == 2 ); - - - // check if the node is a DAG node - fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj)); - // increment the counter of DAG nodes - if ( fDagNode ) Cut_ManIncrementDagNodes( p ); - // add the trivial cut if the node is a DAG node, or if we compute all cuts - fTriv = fDagNode || !fDag; - // check if fanins are DAG nodes - if ( fTree ) - { - pFanin = Abc_ObjFanin0(pObj); - TreeCode |= (Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)); - pFanin = Abc_ObjFanin1(pObj); - TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1); - } - - - // changes due to the global/local cut computation - { - Cut_Params_t * pParams = Cut_ManReadParams(p); - if ( pParams->fLocal ) - { - Vec_Int_t * vNodeAttrs = Cut_ManReadNodeAttrs(p); - fDagNode = Vec_IntEntry( vNodeAttrs, pObj->Id ); - if ( fDagNode ) Cut_ManIncrementDagNodes( p ); -// fTriv = fDagNode || !pParams->fGlobal; - fTriv = !Vec_IntEntry( vNodeAttrs, pObj->Id ); - TreeCode = 0; - pFanin = Abc_ObjFanin0(pObj); - TreeCode |= Vec_IntEntry( vNodeAttrs, pFanin->Id ); - pFanin = Abc_ObjFanin1(pObj); - TreeCode |= (Vec_IntEntry( vNodeAttrs, pFanin->Id ) << 1); - } - } - return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), - Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv, TreeCode ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv ) -{ - int CutSetNum; - assert( Abc_NtkIsSeq(pObj->pNtk) ); - assert( Abc_ObjFaninNum(pObj) == 2 ); - fTriv = pObj->fMarkC ? 0 : fTriv; - CutSetNum = pObj->fMarkC ? (int)pObj->pCopy : -1; - Cut_NodeComputeCutsSeq( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj), - Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), Seq_ObjFaninL0(pObj), Seq_ObjFaninL1(pObj), fTriv, CutSetNum ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj ) -{ - return Cut_NodeReadCutsNew( p, pObj->Id ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj ) -{ - Cut_NodeFreeCuts( p, pObj->Id ); -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq ) -{ - Cut_Man_t * pMan = p; - Cut_Cut_t * pList; - Abc_Obj_t * pObj; - int i; - printf( "Cuts of the network:\n" ); - Abc_NtkForEachObj( pNtk, pObj, i ) - { - pList = Abc_NodeReadCuts( p, pObj ); - printf( "Node %s:\n", Abc_ObjName(pObj) ); - Cut_CutPrintList( pList, fSeq ); - } -} - -/**Function************************************************************* - - Synopsis [Computes the cuts for the network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq ) -{ - Cut_Man_t * pMan = p; - Cut_Cut_t * pList; - Abc_Obj_t * pObj; - pObj = Abc_NtkObj( pNtk, 2 * Abc_NtkObjNum(pNtk) / 3 ); - pList = Abc_NodeReadCuts( p, pObj ); - printf( "Node %s:\n", Abc_ObjName(pObj) ); - Cut_CutPrintList( pList, fSeq ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/cut/cut.h b/src/opt/cut/cut.h index dee05dfc..6719ed4d 100644 --- a/src/opt/cut/cut.h +++ b/src/opt/cut/cut.h @@ -21,10 +21,6 @@ #ifndef __CUT_H__ #define __CUT_H__ -#ifdef __cplusplus -extern "C" { -#endif - //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -33,133 +29,81 @@ extern "C" { /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#define CUT_SIZE_MIN 3 // the min K of the K-feasible cut computation -#define CUT_SIZE_MAX 12 // the max K of the K-feasible cut computation - -#define CUT_SHIFT 8 // the number of bits for storing latch number in the cut leaves -#define CUT_MASK 0xFF // the mask to get the stored latch number - //////////////////////////////////////////////////////////////////////// /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// typedef struct Cut_ManStruct_t_ Cut_Man_t; -typedef struct Cut_OracleStruct_t_ Cut_Oracle_t; typedef struct Cut_CutStruct_t_ Cut_Cut_t; typedef struct Cut_ParamsStruct_t_ Cut_Params_t; struct Cut_ParamsStruct_t_ { - int nVarsMax; // the max cut size ("k" of the k-feasible cuts) - int nKeepMax; // the max number of cuts kept at a node - int nIdsMax; // the max number of IDs of cut objects - int nBitShift; // the number of bits used for the latch counter of an edge - int nCutSet; // the number of nodes in the cut set - int fTruth; // compute truth tables - int fFilter; // filter dominated cuts - int fSeq; // compute sequential cuts - int fDrop; // drop cuts on the fly - int fDag; // compute only DAG cuts - int fTree; // compute only tree cuts - int fGlobal; // compute only global cuts - int fLocal; // compute only local cuts - int fRecord; // record the cut computation flow - int fFancy; // perform fancy computations - int fMap; // computes delay of FPGA mapping with cuts - int fVerbose; // the verbosiness flag + int nVarsMax; // the max cut size ("k" of the k-feasible cuts) + int nKeepMax; // the max number of cuts kept at a node + int nIdsMax; // the max number of IDs of cut objects + int fTruth; // compute truth tables + int fHash; // hash cuts to detect unique + int fFilter; // filter dominated cuts + int fSeq; // compute sequential cuts + int fDrop; // drop cuts on the fly + int fVerbose; // the verbosiness flag }; struct Cut_CutStruct_t_ { - unsigned Num0 : 11; // temporary number - unsigned Num1 : 11; // temporary number + unsigned uTruth : 16; // truth table for 4-input cuts + unsigned uPhase : 7; // the phase when mapping into a canonical form unsigned fSimul : 1; // the value of cut's output at 000.. pattern unsigned fCompl : 1; // the cut is complemented - unsigned nVarsMax : 4; // the max number of vars [4-6] - unsigned nLeaves : 4; // the number of leaves [4-6] - unsigned uSign; // the signature - unsigned uCanon0; // the canonical form - unsigned uCanon1; // the canonical form + unsigned fSeq : 1; // the cut is sequential + unsigned nVarsMax : 3; // the max number of vars [4-6] + unsigned nLeaves : 3; // the number of leaves [4-6] Cut_Cut_t * pNext; // the next cut in the list + void * pData; // the user data int pLeaves[0]; // the array of leaves }; +static inline unsigned * Cut_CutReadTruth( Cut_Cut_t * p ) { if ( p->nVarsMax == 4 ) return (unsigned *)p; return (unsigned *)(p->pLeaves + p->nVarsMax + p->fSeq); } +static inline unsigned Cut_CutReadPhase( Cut_Cut_t * p ) { return p->uPhase; } static inline int Cut_CutReadLeaveNum( Cut_Cut_t * p ) { return p->nLeaves; } static inline int * Cut_CutReadLeaves( Cut_Cut_t * p ) { return p->pLeaves; } -static inline unsigned * Cut_CutReadTruth( Cut_Cut_t * p ) { return (unsigned *)(p->pLeaves + p->nVarsMax); } +static inline void * Cut_CutReadData( Cut_Cut_t * p ) { return p->pData; } + +static inline void Cut_CutWriteData( Cut_Cut_t * p, void * pData ) { p->pData = pData; } static inline void Cut_CutWriteTruth( Cut_Cut_t * p, unsigned * puTruth ) { - int i; - for ( i = (p->nVarsMax <= 5) ? 0 : ((1 << (p->nVarsMax - 5)) - 1); i >= 0; i-- ) - p->pLeaves[p->nVarsMax + i] = (int)puTruth[i]; + if ( p->nVarsMax == 4 ) { p->uTruth = *puTruth; return; } + p->pLeaves[p->nVarsMax + p->fSeq] = (int)puTruth[0]; + if ( p->nVarsMax == 6 ) p->pLeaves[p->nVarsMax + p->fSeq + 1] = (int)puTruth[1]; } //////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// +/// MACRO DEFITIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== cutApi.c ==========================================================*/ -extern Cut_Cut_t * Cut_NodeReadCutsNew( Cut_Man_t * p, int Node ); -extern Cut_Cut_t * Cut_NodeReadCutsOld( Cut_Man_t * p, int Node ); -extern Cut_Cut_t * Cut_NodeReadCutsTemp( Cut_Man_t * p, int Node ); -extern void Cut_NodeWriteCutsNew( Cut_Man_t * p, int Node, Cut_Cut_t * pList ); -extern void Cut_NodeWriteCutsOld( Cut_Man_t * p, int Node, Cut_Cut_t * pList ); -extern void Cut_NodeWriteCutsTemp( Cut_Man_t * p, int Node, Cut_Cut_t * pList ); -extern void Cut_NodeSetTriv( Cut_Man_t * p, int Node ); -extern void Cut_NodeTryDroppingCuts( Cut_Man_t * p, int Node ); -extern void Cut_NodeFreeCuts( Cut_Man_t * p, int Node ); -/*=== cutCut.c ==========================================================*/ -extern void Cut_CutPrint( Cut_Cut_t * pCut, int fSeq ); -extern void Cut_CutPrintList( Cut_Cut_t * pList, int fSeq ); -extern int Cut_CutCountList( Cut_Cut_t * pList ); /*=== cutMan.c ==========================================================*/ extern Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams ); extern void Cut_ManStop( Cut_Man_t * p ); extern void Cut_ManPrintStats( Cut_Man_t * p ); -extern void Cut_ManPrintStatsToFile( Cut_Man_t * p, char * pFileName, int TimeTotal ); extern void Cut_ManSetFanoutCounts( Cut_Man_t * p, Vec_Int_t * vFanCounts ); -extern void Cut_ManSetNodeAttrs( Cut_Man_t * p, Vec_Int_t * vFanCounts ); -extern int Cut_ManReadVarsMax( Cut_Man_t * p ); -extern Cut_Params_t * Cut_ManReadParams( Cut_Man_t * p ); -extern Vec_Int_t * Cut_ManReadNodeAttrs( Cut_Man_t * p ); -extern void Cut_ManIncrementDagNodes( Cut_Man_t * p ); /*=== cutNode.c ==========================================================*/ -extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode ); +extern void Cut_NodeSetTriv( Cut_Man_t * p, int Node ); +extern Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1 ); extern Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes ); -extern Cut_Cut_t * Cut_NodeUnionCutsSeq( Cut_Man_t * p, Vec_Int_t * vNodes, int CutSetNum, int fFirst ); -extern int Cut_ManMappingArea_rec( Cut_Man_t * p, int Node ); -/*=== cutSeq.c ==========================================================*/ -extern void Cut_NodeComputeCutsSeq( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int nLat0, int nLat1, int fTriv, int CutSetNum ); -extern void Cut_NodeNewMergeWithOld( Cut_Man_t * p, int Node ); -extern int Cut_NodeTempTransferToNew( Cut_Man_t * p, int Node, int CutSetNum ); -extern void Cut_NodeOldTransferToNew( Cut_Man_t * p, int Node ); -/*=== cutOracle.c ==========================================================*/ -extern Cut_Oracle_t * Cut_OracleStart( Cut_Man_t * pMan ); -extern void Cut_OracleStop( Cut_Oracle_t * p ); -extern void Cut_OracleSetFanoutCounts( Cut_Oracle_t * p, Vec_Int_t * vFanCounts ); -extern int Cut_OracleReadDrop( Cut_Oracle_t * p ); -extern void Cut_OracleNodeSetTriv( Cut_Oracle_t * p, int Node ); -extern Cut_Cut_t * Cut_OracleComputeCuts( Cut_Oracle_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1 ); -extern void Cut_OracleTryDroppingCuts( Cut_Oracle_t * p, int Node ); -/*=== cutTruth.c ==========================================================*/ -extern void Cut_TruthNCanonicize( Cut_Cut_t * pCut ); -/*=== cutPre22.c ==========================================================*/ -extern void Cut_CellPrecompute(); -extern void Cut_CellLoad(); -extern int Cut_CellIsRunning(); -extern void Cut_CellDumpToFile(); -extern int Cut_CellTruthLookup( unsigned * pTruth, int nVars ); - -#ifdef __cplusplus -} -#endif - -#endif +extern Cut_Cut_t * Cut_NodeReadCuts( Cut_Man_t * p, int Node ); +extern void Cut_NodeWriteCuts( Cut_Man_t * p, int Node, Cut_Cut_t * pList ); +extern void Cut_NodeFreeCuts( Cut_Man_t * p, int Node ); +extern void Cut_NodeSetComputedAsNew( Cut_Man_t * p, int Node ); +extern void Cut_NodeTryDroppingCuts( Cut_Man_t * p, int Node ); +extern void Cut_CutPrint( Cut_Cut_t * pCut ); //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +#endif + diff --git a/src/opt/cut/cutApi.c b/src/opt/cut/cutApi.c deleted file mode 100644 index 980c6b12..00000000 --- a/src/opt/cut/cutApi.c +++ /dev/null @@ -1,197 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutNode.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [K-feasible cut computation package.] - - Synopsis [Procedures to compute cuts for a node.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutNode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "cutInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Returns the pointer to the linked list of cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_NodeReadCutsNew( Cut_Man_t * p, int Node ) -{ - if ( Node >= p->vCutsNew->nSize ) - return NULL; - return Vec_PtrEntry( p->vCutsNew, Node ); -} - -/**Function************************************************************* - - Synopsis [Returns the pointer to the linked list of cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_NodeReadCutsOld( Cut_Man_t * p, int Node ) -{ - assert( Node < p->vCutsOld->nSize ); - return Vec_PtrEntry( p->vCutsOld, Node ); -} - -/**Function************************************************************* - - Synopsis [Returns the pointer to the linked list of cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_NodeReadCutsTemp( Cut_Man_t * p, int Node ) -{ - assert( Node < p->vCutsTemp->nSize ); - return Vec_PtrEntry( p->vCutsTemp, Node ); -} - -/**Function************************************************************* - - Synopsis [Returns the pointer to the linked list of cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_NodeWriteCutsNew( Cut_Man_t * p, int Node, Cut_Cut_t * pList ) -{ - Vec_PtrWriteEntry( p->vCutsNew, Node, pList ); -} - -/**Function************************************************************* - - Synopsis [Returns the pointer to the linked list of cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_NodeWriteCutsOld( Cut_Man_t * p, int Node, Cut_Cut_t * pList ) -{ - Vec_PtrWriteEntry( p->vCutsOld, Node, pList ); -} - -/**Function************************************************************* - - Synopsis [Returns the pointer to the linked list of cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_NodeWriteCutsTemp( Cut_Man_t * p, int Node, Cut_Cut_t * pList ) -{ - Vec_PtrWriteEntry( p->vCutsTemp, Node, pList ); -} - -/**Function************************************************************* - - Synopsis [Sets the trivial cut for the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_NodeSetTriv( Cut_Man_t * p, int Node ) -{ - assert( Cut_NodeReadCutsNew(p, Node) == NULL ); - Cut_NodeWriteCutsNew( p, Node, Cut_CutCreateTriv(p, Node) ); -} - -/**Function************************************************************* - - Synopsis [Consider dropping cuts if they are useless by now.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_NodeTryDroppingCuts( Cut_Man_t * p, int Node ) -{ - int nFanouts; - assert( p->vFanCounts ); - nFanouts = Vec_IntEntry( p->vFanCounts, Node ); - assert( nFanouts > 0 ); - if ( --nFanouts == 0 ) - Cut_NodeFreeCuts( p, Node ); - Vec_IntWriteEntry( p->vFanCounts, Node, nFanouts ); -} - -/**Function************************************************************* - - Synopsis [Deallocates the cuts at the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_NodeFreeCuts( Cut_Man_t * p, int Node ) -{ - Cut_Cut_t * pList, * pCut, * pCut2; - pList = Cut_NodeReadCutsNew( p, Node ); - if ( pList == NULL ) - return; - Cut_ListForEachCutSafe( pList, pCut, pCut2 ) - Cut_CutRecycle( p, pCut ); - Cut_NodeWriteCutsNew( p, Node, NULL ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/cut/cutCut.c b/src/opt/cut/cutCut.c deleted file mode 100644 index 94147278..00000000 --- a/src/opt/cut/cutCut.c +++ /dev/null @@ -1,359 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutNode.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [K-feasible cut computation package.] - - Synopsis [Procedures to compute cuts for a node.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutNode.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "cutInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutAlloc( Cut_Man_t * p ) -{ - Cut_Cut_t * pCut; - // cut allocation - pCut = (Cut_Cut_t *)Extra_MmFixedEntryFetch( p->pMmCuts ); - memset( pCut, 0, sizeof(Cut_Cut_t) ); - pCut->nVarsMax = p->pParams->nVarsMax; - pCut->fSimul = p->fSimul; - // statistics - p->nCutsAlloc++; - p->nCutsCur++; - if ( p->nCutsPeak < p->nCutsAlloc - p->nCutsDealloc ) - p->nCutsPeak = p->nCutsAlloc - p->nCutsDealloc; - return pCut; -} - -/**Function************************************************************* - - Synopsis [Recybles the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CutRecycle( Cut_Man_t * p, Cut_Cut_t * pCut ) -{ - p->nCutsDealloc++; - p->nCutsCur--; - if ( pCut->nLeaves == 1 ) - p->nCutsTriv--; - Extra_MmFixedEntryRecycle( p->pMmCuts, (char *)pCut ); -} - -/**Function************************************************************* - - Synopsis [Compares two cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_CutCompare( Cut_Cut_t * pCut1, Cut_Cut_t * pCut2 ) -{ - int i; - if ( pCut1->nLeaves < pCut2->nLeaves ) - return -1; - if ( pCut1->nLeaves > pCut2->nLeaves ) - return 1; - for ( i = 0; i < (int)pCut1->nLeaves; i++ ) - { - if ( pCut1->pLeaves[i] < pCut2->pLeaves[i] ) - return -1; - if ( pCut1->pLeaves[i] > pCut2->pLeaves[i] ) - return 1; - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Duplicates the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutDupList( Cut_Man_t * p, Cut_Cut_t * pList ) -{ - Cut_Cut_t * pHead = NULL, ** ppTail = &pHead; - Cut_Cut_t * pTemp, * pCopy; - if ( pList == NULL ) - return NULL; - Cut_ListForEachCut( pList, pTemp ) - { - pCopy = (Cut_Cut_t *)Extra_MmFixedEntryFetch( p->pMmCuts ); - memcpy( pCopy, pTemp, p->EntrySize ); - *ppTail = pCopy; - ppTail = &pCopy->pNext; - } - *ppTail = NULL; - return pHead; -} - -/**Function************************************************************* - - Synopsis [Recycles the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CutRecycleList( Cut_Man_t * p, Cut_Cut_t * pList ) -{ - Cut_Cut_t * pCut, * pCut2; - Cut_ListForEachCutSafe( pList, pCut, pCut2 ) - Extra_MmFixedEntryRecycle( p->pMmCuts, (char *)pCut ); -} - -/**Function************************************************************* - - Synopsis [Counts the number of cuts in the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_CutCountList( Cut_Cut_t * pList ) -{ - int Counter = 0; - Cut_ListForEachCut( pList, pList ) - Counter++; - return Counter; -} - -/**Function************************************************************* - - Synopsis [Merges two NULL-terminated linked lists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutMergeLists( Cut_Cut_t * pList1, Cut_Cut_t * pList2 ) -{ - Cut_Cut_t * pList = NULL, ** ppTail = &pList; - Cut_Cut_t * pCut; - while ( pList1 && pList2 ) - { - if ( Cut_CutCompare(pList1, pList2) < 0 ) - { - pCut = pList1; - pList1 = pList1->pNext; - } - else - { - pCut = pList2; - pList2 = pList2->pNext; - } - *ppTail = pCut; - ppTail = &pCut->pNext; - } - *ppTail = pList1? pList1: pList2; - return pList; -} - -/**Function************************************************************* - - Synopsis [Sets the number of the cuts in the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CutNumberList( Cut_Cut_t * pList ) -{ - Cut_Cut_t * pCut; - int i = 0; - Cut_ListForEachCut( pList, pCut ) - pCut->Num0 = i++; -} - -/**Function************************************************************* - - Synopsis [Creates the trivial cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutCreateTriv( Cut_Man_t * p, int Node ) -{ - Cut_Cut_t * pCut; - if ( p->pParams->fSeq ) - Node <<= CUT_SHIFT; - pCut = Cut_CutAlloc( p ); - pCut->nLeaves = 1; - pCut->pLeaves[0] = Node; - pCut->uSign = Cut_NodeSign( Node ); - if ( p->pParams->fTruth ) - { -/* - if ( pCut->nVarsMax == 4 ) - Cut_CutWriteTruth( pCut, p->uTruthVars[0] ); - else - Extra_BitCopy( pCut->nLeaves, p->uTruths[0], (uint8*)Cut_CutReadTruth(pCut) ); -*/ - unsigned * pTruth = Cut_CutReadTruth(pCut); - int i; - for ( i = 0; i < p->nTruthWords; i++ ) - pTruth[i] = 0xAAAAAAAA; - } - p->nCutsTriv++; - return pCut; -} - - -/**Function************************************************************* - - Synopsis [Print the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CutPrint( Cut_Cut_t * pCut, int fSeq ) -{ - int i; - assert( pCut->nLeaves > 0 ); - printf( "%d : {", pCut->nLeaves ); - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - { - if ( fSeq ) - { - printf( " %d", pCut->pLeaves[i] >> CUT_SHIFT ); - if ( pCut->pLeaves[i] & CUT_MASK ) - printf( "(%d)", pCut->pLeaves[i] & CUT_MASK ); - } - else - printf( " %d", pCut->pLeaves[i] ); - } - printf( " }" ); -// printf( "\nSign = " ); -// Extra_PrintBinary( stdout, &pCut->uSign, 32 ); -} - -/**Function************************************************************* - - Synopsis [Print the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CutPrintList( Cut_Cut_t * pList, int fSeq ) -{ - Cut_Cut_t * pCut; - for ( pCut = pList; pCut; pCut = pCut->pNext ) - Cut_CutPrint( pCut, fSeq ), printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Consider dropping cuts if they are useless by now.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CutPrintMerge( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) -{ - printf( "\n" ); - printf( "%d : %5d %5d %5d %5d %5d\n", - pCut0->nLeaves, - pCut0->nLeaves > 0 ? pCut0->pLeaves[0] : -1, - pCut0->nLeaves > 1 ? pCut0->pLeaves[1] : -1, - pCut0->nLeaves > 2 ? pCut0->pLeaves[2] : -1, - pCut0->nLeaves > 3 ? pCut0->pLeaves[3] : -1, - pCut0->nLeaves > 4 ? pCut0->pLeaves[4] : -1 - ); - printf( "%d : %5d %5d %5d %5d %5d\n", - pCut1->nLeaves, - pCut1->nLeaves > 0 ? pCut1->pLeaves[0] : -1, - pCut1->nLeaves > 1 ? pCut1->pLeaves[1] : -1, - pCut1->nLeaves > 2 ? pCut1->pLeaves[2] : -1, - pCut1->nLeaves > 3 ? pCut1->pLeaves[3] : -1, - pCut1->nLeaves > 4 ? pCut1->pLeaves[4] : -1 - ); - if ( pCut == NULL ) - printf( "Cannot merge\n" ); - else - printf( "%d : %5d %5d %5d %5d %5d\n", - pCut->nLeaves, - pCut->nLeaves > 0 ? pCut->pLeaves[0] : -1, - pCut->nLeaves > 1 ? pCut->pLeaves[1] : -1, - pCut->nLeaves > 2 ? pCut->pLeaves[2] : -1, - pCut->nLeaves > 3 ? pCut->pLeaves[3] : -1, - pCut->nLeaves > 4 ? pCut->pLeaves[4] : -1 - ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/cut/cutExpand.c b/src/opt/cut/cutExpand.c deleted file mode 100644 index d389ef7a..00000000 --- a/src/opt/cut/cutExpand.c +++ /dev/null @@ -1,184 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutExpand.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [K-feasible cut computation package.] - - Synopsis [Computes the truth table of the cut after expansion.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutExpand.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "cutInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define CUT_CELL_MVAR 9 - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes the stretching phase of the cut w.r.t. the merged cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline unsigned Cut_TruthPhase( Cut_Cut_t * pCut, Cut_Cut_t * pCut1 ) -{ - unsigned uPhase = 0; - int i, k; - for ( i = k = 0; i < (int)pCut->nLeaves; i++ ) - { - if ( k == (int)pCut1->nLeaves ) - break; - if ( pCut->pLeaves[i] < pCut1->pLeaves[k] ) - continue; - assert( pCut->pLeaves[i] == pCut1->pLeaves[k] ); - uPhase |= (1 << i); - k++; - } - return uPhase; -} - -/**Function************************************************************* - - Synopsis [Computes the truth table of the composition of cuts.] - - Description [Inputs are: - - a factor cut (truth table is stored inside) - - a node in the factor cut - - a tree cut to be substituted (truth table is stored inside) - - the resulting cut (truth table will be filled in). - Note that all cuts, including the resulting one, should be already - computed and the nodes should be stored in the ascending order.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_TruthCompose( Cut_Cut_t * pCutF, int Node, Cut_Cut_t * pCutT, Cut_Cut_t * pCutRes ) -{ - static unsigned uCof0[1<<(CUT_CELL_MVAR-5)]; - static unsigned uCof1[1<<(CUT_CELL_MVAR-5)]; - static unsigned uTemp[1<<(CUT_CELL_MVAR-5)]; - unsigned * pIn, * pOut, * pTemp; - unsigned uPhase; - int NodeIndex, i, k; - - // sanity checks - assert( pCutF->nVarsMax == pCutT->nVarsMax ); - assert( pCutF->nVarsMax == pCutRes->nVarsMax ); - assert( pCutF->nVarsMax <= CUT_CELL_MVAR ); - // the factor cut (pCutF) should have its nodes sorted in the ascending order - assert( pCutF->nLeaves <= pCutF->nVarsMax ); - for ( i = 0; i < (int)pCutF->nLeaves - 1; i++ ) - assert( pCutF->pLeaves[i] < pCutF->pLeaves[i+1] ); - // the tree cut (pCutT) should have its nodes sorted in the ascending order - assert( pCutT->nLeaves <= pCutT->nVarsMax ); - for ( i = 0; i < (int)pCutT->nLeaves - 1; i++ ) - assert( pCutT->pLeaves[i] < pCutT->pLeaves[i+1] ); - // the resulting cut (pCutRes) should have its nodes sorted in the ascending order - assert( pCutRes->nLeaves <= pCutRes->nVarsMax ); - for ( i = 0; i < (int)pCutRes->nLeaves - 1; i++ ) - assert( pCutRes->pLeaves[i] < pCutRes->pLeaves[i+1] ); - // make sure that every node in pCutF (except Node) appears in pCutRes - for ( i = 0; i < (int)pCutF->nLeaves; i++ ) - { - if ( pCutF->pLeaves[i] == Node ) - continue; - for ( k = 0; k < (int)pCutRes->nLeaves; k++ ) - if ( pCutF->pLeaves[i] == pCutRes->pLeaves[k] ) - break; - assert( k < (int)pCutRes->nLeaves ); // node i from pCutF is not found in pCutRes!!! - } - // make sure that every node in pCutT appears in pCutRes - for ( i = 0; i < (int)pCutT->nLeaves; i++ ) - { - for ( k = 0; k < (int)pCutRes->nLeaves; k++ ) - if ( pCutT->pLeaves[i] == pCutRes->pLeaves[k] ) - break; - assert( k < (int)pCutRes->nLeaves ); // node i from pCutT is not found in pCutRes!!! - } - - - // find the index of the given node in the factor cut - NodeIndex = -1; - for ( NodeIndex = 0; NodeIndex < (int)pCutF->nLeaves; NodeIndex++ ) - if ( pCutF->pLeaves[NodeIndex] == Node ) - break; - assert( NodeIndex >= 0 ); // Node should be in pCutF - - // copy the truth table - Extra_TruthCopy( uTemp, Cut_CutReadTruth(pCutF), pCutF->nLeaves ); - - // bubble-move the NodeIndex variable to be the last one (the most significant one) - pIn = uTemp; pOut = uCof0; // uCof0 is used for temporary storage here - for ( i = NodeIndex; i < (int)pCutF->nLeaves - 1; i++ ) - { - Extra_TruthSwapAdjacentVars( pOut, pIn, pCutF->nLeaves, i ); - pTemp = pIn; pIn = pOut; pOut = pTemp; - } - if ( (pCutF->nLeaves - 1 - NodeIndex) & 1 ) - Extra_TruthCopy( pOut, pIn, pCutF->nLeaves ); - // the result of stretching is in uTemp - - // cofactor the factor cut with respect to the node - Extra_TruthCopy( uCof0, uTemp, pCutF->nLeaves ); - Extra_TruthCofactor0( uCof0, pCutF->nLeaves, pCutF->nLeaves-1 ); - Extra_TruthCopy( uCof1, uTemp, pCutF->nLeaves ); - Extra_TruthCofactor1( uCof1, pCutF->nLeaves, pCutF->nLeaves-1 ); - - // temporarily shrink the factor cut's variables by removing Node - for ( i = NodeIndex; i < (int)pCutF->nLeaves - 1; i++ ) - pCutF->pLeaves[i] = pCutF->pLeaves[i+1]; - pCutF->nLeaves--; - - // spread out the cofactors' truth tables to the same var order as the resulting cut - uPhase = Cut_TruthPhase(pCutRes, pCutF); - assert( Extra_WordCountOnes(uPhase) == (int)pCutF->nLeaves ); - Extra_TruthStretch( uTemp, uCof0, pCutF->nLeaves, pCutF->nVarsMax, uPhase ); - Extra_TruthCopy( uCof0, uTemp, pCutF->nVarsMax ); - Extra_TruthStretch( uTemp, uCof1, pCutF->nLeaves, pCutF->nVarsMax, uPhase ); - Extra_TruthCopy( uCof1, uTemp, pCutF->nVarsMax ); - - // spread out the tree cut's truth table to the same var order as the resulting cut - uPhase = Cut_TruthPhase(pCutRes, pCutT); - assert( Extra_WordCountOnes(uPhase) == (int)pCutT->nLeaves ); - Extra_TruthStretch( uTemp, Cut_CutReadTruth(pCutT), pCutT->nLeaves, pCutT->nVarsMax, uPhase ); - - // create the resulting truth table - pTemp = Cut_CutReadTruth(pCutRes); - for ( i = Extra_TruthWordNum(pCutRes->nLeaves)-1; i >= 0; i-- ) - pTemp[i] = (uCof0[i] & ~uTemp[i]) | (uCof1[i] & uTemp[i]); - - // undo the removal of the node from the cut - for ( i = (int)pCutF->nLeaves - 1; i >= NodeIndex; --i ) - pCutF->pLeaves[i+1] = pCutF->pLeaves[i]; - pCutF->pLeaves[NodeIndex] = Node; - pCutF->nLeaves++; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/cut/cutInt.h b/src/opt/cut/cutInt.h index 17f268c7..fe5080b4 100644 --- a/src/opt/cut/cutInt.h +++ b/src/opt/cut/cutInt.h @@ -29,7 +29,6 @@ #include "extra.h" #include "vec.h" #include "cut.h" -#include "cutList.h" //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// @@ -42,103 +41,56 @@ typedef struct Cut_HashTableStruct_t_ Cut_HashTable_t; struct Cut_ManStruct_t_ -{ +{ // user preferences Cut_Params_t * pParams; // computation parameters Vec_Int_t * vFanCounts; // the array of fanout counters - Vec_Int_t * vNodeAttrs; // node attributes (1 = global; 0 = local) // storage for cuts - Vec_Ptr_t * vCutsNew; // new cuts by node ID - Vec_Ptr_t * vCutsOld; // old cuts by node ID - Vec_Ptr_t * vCutsTemp; // temp cuts for cutset nodes by cutset node number + Vec_Ptr_t * vCuts; // cuts by ID + Vec_Ptr_t * vCutsNew; // cuts by ID + Cut_HashTable_t * tTable; // cuts by their leaves (and root) // memory management Extra_MmFixed_t * pMmCuts; int EntrySize; - int nTruthWords; // temporary variables Cut_Cut_t * pReady; Vec_Ptr_t * vTemp; int fCompl0; int fCompl1; int fSimul; - int nNodeCuts; - Cut_Cut_t * pStore0[2]; - Cut_Cut_t * pStore1[2]; - Cut_Cut_t * pCompareOld; - Cut_Cut_t * pCompareNew; - unsigned * puTemp[4]; - // record of the cut computation - Vec_Int_t * vNodeCuts; // the number of cuts for each node - Vec_Int_t * vNodeStarts; // the number of the starting cut of each node - Vec_Int_t * vCutPairs; // the pairs of parent cuts for each cut - // minimum delay mapping with the given cuts - Vec_Ptr_t * vCutsMax; - Vec_Int_t * vDelays; - Vec_Int_t * vDelays2; - int nDelayMin; + // precomputations + unsigned uTruthVars[6][2]; + unsigned short ** pPerms43; + unsigned ** pPerms53; + unsigned ** pPerms54; // statistics int nCutsCur; int nCutsAlloc; int nCutsDealloc; int nCutsPeak; int nCutsTriv; - int nCutsFilter; - int nCutsLimit; + int nCutsNode; int nNodes; - int nNodesDag; - int nNodesNoCuts; // runtime int timeMerge; int timeUnion; int timeTruth; int timeFilter; int timeHash; - int timeMap; }; -// iterator through all the cuts of the list -#define Cut_ListForEachCut( pList, pCut ) \ - for ( pCut = pList; \ - pCut; \ - pCut = pCut->pNext ) -#define Cut_ListForEachCutStop( pList, pCut, pStop ) \ - for ( pCut = pList; \ - pCut != pStop; \ - pCut = pCut->pNext ) -#define Cut_ListForEachCutSafe( pList, pCut, pCut2 ) \ - for ( pCut = pList, \ - pCut2 = pCut? pCut->pNext: NULL; \ - pCut; \ - pCut = pCut2, \ - pCut2 = pCut? pCut->pNext: NULL ) - //////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// +/// MACRO DEFITIONS /// //////////////////////////////////////////////////////////////////////// -// computes signature of the node -static inline unsigned Cut_NodeSign( int Node ) { return (1 << (Node % 31)); } -static inline int Cut_TruthWords( int nVarsMax ) { return nVarsMax <= 5 ? 1 : (1 << (nVarsMax - 5)); } - //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -/*=== cutCut.c ==========================================================*/ -extern Cut_Cut_t * Cut_CutAlloc( Cut_Man_t * p ); -extern void Cut_CutRecycle( Cut_Man_t * p, Cut_Cut_t * pCut ); -extern int Cut_CutCompare( Cut_Cut_t * pCut1, Cut_Cut_t * pCut2 ); -extern Cut_Cut_t * Cut_CutDupList( Cut_Man_t * p, Cut_Cut_t * pList ); -extern void Cut_CutRecycleList( Cut_Man_t * p, Cut_Cut_t * pList ); -extern Cut_Cut_t * Cut_CutMergeLists( Cut_Cut_t * pList1, Cut_Cut_t * pList2 ); -extern void Cut_CutNumberList( Cut_Cut_t * pList ); -extern Cut_Cut_t * Cut_CutCreateTriv( Cut_Man_t * p, int Node ); -extern void Cut_CutPrintMerge( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ); /*=== cutMerge.c ==========================================================*/ extern Cut_Cut_t * Cut_CutMergeTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ); /*=== cutNode.c ==========================================================*/ -extern void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fCompl0, int fCompl1, Cut_Cut_t * pList0, Cut_Cut_t * pList1, int fTriv, int TreeCode ); -extern int Cut_CutListVerify( Cut_Cut_t * pList ); +extern Cut_Cut_t * Cut_CutAlloc( Cut_Man_t * p ); /*=== cutTable.c ==========================================================*/ extern Cut_HashTable_t * Cut_TableStart( int Size ); extern void Cut_TableStop( Cut_HashTable_t * pTable ); @@ -146,12 +98,11 @@ extern int Cut_TableLookup( Cut_HashTable_t * pTable, Cut_Cut_t extern void Cut_TableClear( Cut_HashTable_t * pTable ); extern int Cut_TableReadTime( Cut_HashTable_t * pTable ); /*=== cutTruth.c ==========================================================*/ -extern void Cut_TruthComputeOld( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 ); -extern void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 ); - -#endif +extern void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ); //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +#endif + diff --git a/src/opt/cut/cutList.h b/src/opt/cut/cutList.h index a03ec9d5..eb008ef9 100644 --- a/src/opt/cut/cutList.h +++ b/src/opt/cut/cutList.h @@ -36,12 +36,12 @@ typedef struct Cut_ListStruct_t_ Cut_List_t; struct Cut_ListStruct_t_ { - Cut_Cut_t * pHead[CUT_SIZE_MAX+1]; - Cut_Cut_t ** ppTail[CUT_SIZE_MAX+1]; + Cut_Cut_t * pHead[7]; + Cut_Cut_t ** ppTail[7]; }; //////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// +/// MACRO DEFITIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// @@ -50,7 +50,7 @@ struct Cut_ListStruct_t_ /**Function************************************************************* - Synopsis [Start the cut list.] + Synopsis [] Description [] @@ -62,7 +62,7 @@ struct Cut_ListStruct_t_ static inline void Cut_ListStart( Cut_List_t * p ) { int i; - for ( i = 1; i <= CUT_SIZE_MAX; i++ ) + for ( i = 1; i <= 6; i++ ) { p->pHead[i] = 0; p->ppTail[i] = &p->pHead[i]; @@ -71,7 +71,7 @@ static inline void Cut_ListStart( Cut_List_t * p ) /**Function************************************************************* - Synopsis [Adds one cut to the cut list.] + Synopsis [] Description [] @@ -82,100 +82,14 @@ static inline void Cut_ListStart( Cut_List_t * p ) ***********************************************************************/ static inline void Cut_ListAdd( Cut_List_t * p, Cut_Cut_t * pCut ) { - assert( pCut->nLeaves > 0 && pCut->nLeaves <= CUT_SIZE_MAX ); + assert( pCut->nLeaves > 0 && pCut->nLeaves < 7 ); *p->ppTail[pCut->nLeaves] = pCut; p->ppTail[pCut->nLeaves] = &pCut->pNext; } /**Function************************************************************* - Synopsis [Adds one cut to the cut list while preserving order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Cut_ListAdd2( Cut_List_t * p, Cut_Cut_t * pCut ) -{ - extern int Cut_CutCompare( Cut_Cut_t * pCut1, Cut_Cut_t * pCut2 ); - Cut_Cut_t * pTemp, ** ppSpot; - assert( pCut->nLeaves > 0 && pCut->nLeaves <= CUT_SIZE_MAX ); - if ( p->pHead[pCut->nLeaves] != NULL ) - { - ppSpot = &p->pHead[pCut->nLeaves]; - for ( pTemp = p->pHead[pCut->nLeaves]; pTemp; pTemp = pTemp->pNext ) - { - if ( Cut_CutCompare(pCut, pTemp) < 0 ) - { - *ppSpot = pCut; - pCut->pNext = pTemp; - return; - } - else - ppSpot = &pTemp->pNext; - } - } - *p->ppTail[pCut->nLeaves] = pCut; - p->ppTail[pCut->nLeaves] = &pCut->pNext; -} - -/**Function************************************************************* - - Synopsis [Derive the super list from the linked list of cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Cut_ListDerive( Cut_List_t * p, Cut_Cut_t * pList ) -{ - Cut_Cut_t * pPrev; - int nLeaves; - Cut_ListStart( p ); - while ( pList != NULL ) - { - nLeaves = pList->nLeaves; - p->pHead[nLeaves] = pList; - for ( pPrev = pList, pList = pList->pNext; pList; pPrev = pList, pList = pList->pNext ) - if ( nLeaves < (int)pList->nLeaves ) - break; - p->ppTail[nLeaves] = &pPrev->pNext; - pPrev->pNext = NULL; - } -} - -/**Function************************************************************* - - Synopsis [Adds the second list to the first list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Cut_ListAddList( Cut_List_t * pOld, Cut_List_t * pNew ) -{ - int i; - for ( i = 1; i <= CUT_SIZE_MAX; i++ ) - { - if ( pNew->pHead[i] == NULL ) - continue; - *pOld->ppTail[i] = pNew->pHead[i]; - pOld->ppTail[i] = pNew->ppTail[i]; - } -} - -/**Function************************************************************* - - Synopsis [Returns the cut list linked into one sequence of cuts.] + Synopsis [] Description [] @@ -186,22 +100,16 @@ static inline void Cut_ListAddList( Cut_List_t * pOld, Cut_List_t * pNew ) ***********************************************************************/ static inline Cut_Cut_t * Cut_ListFinish( Cut_List_t * p ) { - Cut_Cut_t * pHead = NULL, ** ppTail = &pHead; int i; - for ( i = 1; i <= CUT_SIZE_MAX; i++ ) - { - if ( p->pHead[i] == NULL ) - continue; - *ppTail = p->pHead[i]; - ppTail = p->ppTail[i]; - } - *ppTail = NULL; - return pHead; + for ( i = 1; i < 6; i++ ) + *p->ppTail[i] = p->pHead[i+1]; + *p->ppTail[6] = NULL; + return p->pHead[1]; } -#endif - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +#endif + diff --git a/src/opt/cut/cutMan.c b/src/opt/cut/cutMan.c index 8593ef93..4ad3a66a 100644 --- a/src/opt/cut/cutMan.c +++ b/src/opt/cut/cutMan.c @@ -24,10 +24,8 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern void Npn_StartTruth8( uint8 uTruths[][32] ); - //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -45,65 +43,47 @@ Cut_Man_t * Cut_ManStart( Cut_Params_t * pParams ) { Cut_Man_t * p; int clk = clock(); -// extern int nTruthDsd; -// nTruthDsd = 0; - assert( pParams->nVarsMax >= 3 && pParams->nVarsMax <= CUT_SIZE_MAX ); + assert( pParams->nVarsMax >= 4 && pParams->nVarsMax <= 6 ); p = ALLOC( Cut_Man_t, 1 ); memset( p, 0, sizeof(Cut_Man_t) ); // set and correct parameters p->pParams = pParams; - // prepare storage for cuts - p->vCutsNew = Vec_PtrAlloc( pParams->nIdsMax ); - Vec_PtrFill( p->vCutsNew, pParams->nIdsMax, NULL ); - // prepare storage for sequential cuts + if ( p->pParams->fSeq ) + p->pParams->fHash = 1; + // space for cuts + p->vCuts = Vec_PtrAlloc( pParams->nIdsMax ); + Vec_PtrFill( p->vCuts, pParams->nIdsMax, NULL ); if ( pParams->fSeq ) { - p->pParams->fFilter = 1; - p->vCutsOld = Vec_PtrAlloc( pParams->nIdsMax ); - Vec_PtrFill( p->vCutsOld, pParams->nIdsMax, NULL ); - p->vCutsTemp = Vec_PtrAlloc( pParams->nCutSet ); - Vec_PtrFill( p->vCutsTemp, pParams->nCutSet, NULL ); - if ( pParams->fTruth && pParams->nVarsMax > 5 ) - { - pParams->fTruth = 0; - printf( "Skipping computation of truth tables for sequential cuts with more than 5 inputs.\n" ); - } + p->vCutsNew = Vec_PtrAlloc( pParams->nIdsMax ); + Vec_PtrFill( p->vCuts, pParams->nIdsMax, NULL ); } + // hash tables + if ( pParams->fHash ) + p->tTable = Cut_TableStart( p->pParams->nKeepMax ); // entry size - p->EntrySize = sizeof(Cut_Cut_t) + pParams->nVarsMax * sizeof(int); - if ( pParams->fTruth ) - { - if ( pParams->nVarsMax > 14 ) - { - pParams->fTruth = 0; - printf( "Skipping computation of truth table for more than %d inputs.\n", 14 ); - } - else - { - p->nTruthWords = Cut_TruthWords( pParams->nVarsMax ); - p->EntrySize += p->nTruthWords * sizeof(unsigned); - } - p->puTemp[0] = ALLOC( unsigned, 4 * p->nTruthWords ); - p->puTemp[1] = p->puTemp[0] + p->nTruthWords; - p->puTemp[2] = p->puTemp[1] + p->nTruthWords; - p->puTemp[3] = p->puTemp[2] + p->nTruthWords; - } - // enable cut computation recording - if ( pParams->fRecord ) - { - p->vNodeCuts = Vec_IntStart( pParams->nIdsMax ); - p->vNodeStarts = Vec_IntStart( pParams->nIdsMax ); - p->vCutPairs = Vec_IntAlloc( 0 ); - } - // allocate storage for delays - if ( pParams->fMap && !p->pParams->fSeq ) - { - p->vDelays = Vec_IntStart( pParams->nIdsMax ); - p->vDelays2 = Vec_IntStart( pParams->nIdsMax ); - p->vCutsMax = Vec_PtrStart( pParams->nIdsMax ); - } + p->EntrySize = sizeof(Cut_Cut_t) + (pParams->nVarsMax + pParams->fSeq) * sizeof(int); + if ( pParams->nVarsMax == 5 ) + p->EntrySize += sizeof(unsigned); + else if ( pParams->nVarsMax == 6 ) + p->EntrySize += 2 * sizeof(unsigned); // memory for cuts p->pMmCuts = Extra_MmFixedStart( p->EntrySize ); + // precomputations +// if ( pParams->fTruth && pParams->nVarsMax == 4 ) +// p->pPerms43 = Extra_TruthPerm43(); +// else if ( pParams->fTruth ) +// { +// p->pPerms53 = Extra_TruthPerm53(); +// p->pPerms54 = Extra_TruthPerm54(); +// } + p->uTruthVars[0][1] = p->uTruthVars[0][0] = 0xAAAAAAAA; // 1010 1010 1010 1010 1010 1010 1010 1010 + p->uTruthVars[1][1] = p->uTruthVars[1][0] = 0xCCCCCCCC; // 1010 1010 1010 1010 1010 1010 1010 1010 + p->uTruthVars[2][1] = p->uTruthVars[2][0] = 0xF0F0F0F0; // 1111 0000 1111 0000 1111 0000 1111 0000 + p->uTruthVars[3][1] = p->uTruthVars[3][0] = 0xFF00FF00; // 1111 1111 0000 0000 1111 1111 0000 0000 + p->uTruthVars[4][1] = p->uTruthVars[4][0] = 0xFFFF0000; // 1111 1111 1111 1111 0000 0000 0000 0000 + p->uTruthVars[5][0] = 0x00000000; + p->uTruthVars[5][1] = 0xFFFFFFFF; p->vTemp = Vec_PtrAlloc( 100 ); return p; } @@ -123,29 +103,23 @@ void Cut_ManStop( Cut_Man_t * p ) { Cut_Cut_t * pCut; int i; -// extern int nTruthDsd; -// printf( "Decomposable cuts = %d.\n", nTruthDsd ); - - Vec_PtrForEachEntry( p->vCutsNew, pCut, i ) + Vec_PtrForEachEntry( p->vCuts, pCut, i ) + { if ( pCut != NULL ) { int k = 0; } - if ( p->vCutsNew ) Vec_PtrFree( p->vCutsNew ); - if ( p->vCutsOld ) Vec_PtrFree( p->vCutsOld ); - if ( p->vCutsTemp ) Vec_PtrFree( p->vCutsTemp ); - if ( p->vFanCounts ) Vec_IntFree( p->vFanCounts ); - if ( p->vTemp ) Vec_PtrFree( p->vTemp ); - - if ( p->vCutsMax ) Vec_PtrFree( p->vCutsMax ); - if ( p->vDelays ) Vec_IntFree( p->vDelays ); - if ( p->vDelays2 ) Vec_IntFree( p->vDelays2 ); - if ( p->vNodeCuts ) Vec_IntFree( p->vNodeCuts ); - if ( p->vNodeStarts ) Vec_IntFree( p->vNodeStarts ); - if ( p->vCutPairs ) Vec_IntFree( p->vCutPairs ); - if ( p->puTemp[0] ) free( p->puTemp[0] ); - - Extra_MmFixedStop( p->pMmCuts ); + } + + if ( p->vCutsNew ) Vec_PtrFree( p->vCutsNew ); + if ( p->vCuts ) Vec_PtrFree( p->vCuts ); + if ( p->vFanCounts ) Vec_IntFree( p->vFanCounts ); + if ( p->pPerms43 ) free( p->pPerms43 ); + if ( p->pPerms53 ) free( p->pPerms53 ); + if ( p->pPerms54 ) free( p->pPerms54 ); + if ( p->vTemp ) Vec_PtrFree( p->vTemp ); + if ( p->tTable ) Cut_TableStop( p->tTable ); + Extra_MmFixedStop( p->pMmCuts, 0 ); free( p ); } @@ -162,66 +136,21 @@ void Cut_ManStop( Cut_Man_t * p ) ***********************************************************************/ void Cut_ManPrintStats( Cut_Man_t * p ) { - if ( p->pReady ) - { - Cut_CutRecycle( p, p->pReady ); - p->pReady = NULL; - } printf( "Cut computation statistics:\n" ); printf( "Current cuts = %8d. (Trivial = %d.)\n", p->nCutsCur-p->nCutsTriv, p->nCutsTriv ); printf( "Peak cuts = %8d.\n", p->nCutsPeak ); printf( "Total allocated = %8d.\n", p->nCutsAlloc ); printf( "Total deallocated = %8d.\n", p->nCutsDealloc ); - printf( "Cuts filtered = %8d.\n", p->nCutsFilter ); - printf( "Nodes saturated = %8d. (Max cuts = %d.)\n", p->nCutsLimit, p->pParams->nKeepMax ); printf( "Cuts per node = %8.1f\n", ((float)(p->nCutsCur-p->nCutsTriv))/p->nNodes ); printf( "The cut size = %8d bytes.\n", p->EntrySize ); printf( "Peak memory = %8.2f Mb.\n", (float)p->nCutsPeak * p->EntrySize / (1<<20) ); - printf( "Total nodes = %8d.\n", p->nNodes ); - if ( p->pParams->fDag || p->pParams->fTree ) - { - printf( "DAG nodes = %8d.\n", p->nNodesDag ); - printf( "Tree nodes = %8d.\n", p->nNodes - p->nNodesDag ); - } - printf( "Nodes w/o cuts = %8d.\n", p->nNodesNoCuts ); - if ( p->pParams->fMap && !p->pParams->fSeq ) - printf( "Mapping delay = %8d.\n", p->nDelayMin ); - PRT( "Merge ", p->timeMerge ); PRT( "Union ", p->timeUnion ); + PRT( "Hash ", Cut_TableReadTime(p->tTable) ); PRT( "Filter", p->timeFilter ); PRT( "Truth ", p->timeTruth ); - PRT( "Map ", p->timeMap ); -// printf( "Nodes = %d. Multi = %d. Cuts = %d. Multi = %d.\n", -// p->nNodes, p->nNodesMulti, p->nCutsCur-p->nCutsTriv, p->nCutsMulti ); -// printf( "Count0 = %d. Count1 = %d. Count2 = %d.\n\n", p->Count0, p->Count1, p->Count2 ); } - -/**Function************************************************************* - - Synopsis [Prints some interesting stats.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_ManPrintStatsToFile( Cut_Man_t * p, char * pFileName, int TimeTotal ) -{ - FILE * pTable; - pTable = fopen( "cut_stats.txt", "a+" ); - fprintf( pTable, "%-20s ", pFileName ); - fprintf( pTable, "%8d ", p->nNodes ); - fprintf( pTable, "%6.1f ", ((float)(p->nCutsCur))/p->nNodes ); - fprintf( pTable, "%6.2f ", ((float)(100.0 * p->nCutsLimit))/p->nNodes ); - fprintf( pTable, "%6.2f ", (float)p->nCutsPeak * p->EntrySize / (1<<20) ); - fprintf( pTable, "%6.2f ", (float)(TimeTotal)/(float)(CLOCKS_PER_SEC) ); - fprintf( pTable, "\n" ); - fclose( pTable ); -} /**Function************************************************************* @@ -239,86 +168,6 @@ void Cut_ManSetFanoutCounts( Cut_Man_t * p, Vec_Int_t * vFanCounts ) p->vFanCounts = vFanCounts; } -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_ManSetNodeAttrs( Cut_Man_t * p, Vec_Int_t * vNodeAttrs ) -{ - p->vNodeAttrs = vNodeAttrs; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_ManReadVarsMax( Cut_Man_t * p ) -{ - return p->pParams->nVarsMax; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Params_t * Cut_ManReadParams( Cut_Man_t * p ) -{ - return p->pParams; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Cut_ManReadNodeAttrs( Cut_Man_t * p ) -{ - return p->vNodeAttrs; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_ManIncrementDagNodes( Cut_Man_t * p ) -{ - p->nNodesDag++; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/cut/cutMerge.c b/src/opt/cut/cutMerge.c index d8a9989c..ba1afce4 100644 --- a/src/opt/cut/cutMerge.c +++ b/src/opt/cut/cutMerge.c @@ -25,7 +25,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -39,7 +39,7 @@ SeeAlso [] ***********************************************************************/ -Cut_Cut_t * Cut_CutMergeTwo2( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) +Cut_Cut_t * Cut_CutMergeTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) { static int M[7][3] = {{0},{0},{0},{0},{0},{0},{0}}; Cut_Cut_t * pRes; @@ -164,7 +164,7 @@ Cut_Cut_t * Cut_CutMergeTwo2( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut SeeAlso [] ***********************************************************************/ -Cut_Cut_t * Cut_CutMergeTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) +Cut_Cut_t * Cut_CutMergeTwo2( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) { Cut_Cut_t * pRes; int * pLeaves; @@ -526,7 +526,7 @@ Cut_Cut_t * Cut_CutMergeTwo5( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut return NULL; } pRes = Cut_CutAlloc( p ); - pRes->Num1 = uSign1; + pRes->uTruth = (uSign1 << 8); } for ( i = 0; i < (int)pCut0->nLeaves; i++ ) pRes->pLeaves[i] = pCut0->pLeaves[i]; @@ -645,8 +645,7 @@ Cut_Cut_t * Cut_CutMergeTwo5( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut } assert( Count == nNodes ); pRes->nLeaves = nNodes; - pRes->Num1 = uSign1; - pRes->Num0 = uSign0; + pRes->uTruth = (uSign1 << 8) | uSign0; return pRes; } diff --git a/src/opt/cut/cutNode.c b/src/opt/cut/cutNode.c index 1f93b14b..8d16ac8a 100644 --- a/src/opt/cut/cutNode.c +++ b/src/opt/cut/cutNode.c @@ -19,21 +19,42 @@ ***********************************************************************/ #include "cutInt.h" +#include "cutList.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static int Cut_NodeMapping( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 ); -static int Cut_NodeMapping2( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 ); +static inline Cut_Cut_t * Cut_CutCreateTriv( Cut_Man_t * p, int Node ); +static inline void Cut_CutRecycle( Cut_Man_t * p, Cut_Cut_t * pCut ); +static inline int Cut_CutProcessTwo( Cut_Man_t * p, int Root, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, Cut_List_t * pSuperList ); + +static void Cut_CutPrintMerge( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ); +static void Cut_CutFilter( Cut_Man_t * p, Cut_Cut_t * pList ); + +// iterator through all the cuts of the list +#define Cut_ListForEachCut( pList, pCut ) \ + for ( pCut = pList; \ + pCut; \ + pCut = pCut->pNext ) +#define Cut_ListForEachCutStop( pList, pCut, pStop ) \ + for ( pCut = pList; \ + pCut != pStop; \ + pCut = pCut->pNext ) +#define Cut_ListForEachCutSafe( pList, pCut, pCut2 ) \ + for ( pCut = pList, \ + pCut2 = pCut? pCut->pNext: NULL; \ + pCut; \ + pCut = pCut2, \ + pCut2 = pCut? pCut->pNext: NULL ) //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Returns 1 if pDom is contained in pCut.] + Synopsis [Returns the pointer to the linked list of cuts.] Description [] @@ -42,24 +63,16 @@ static int Cut_NodeMapping2( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Nod SeeAlso [] ***********************************************************************/ -static inline int Cut_CutCheckDominance( Cut_Cut_t * pDom, Cut_Cut_t * pCut ) +Cut_Cut_t * Cut_NodeReadCuts( Cut_Man_t * p, int Node ) { - int i, k; - for ( i = 0; i < (int)pDom->nLeaves; i++ ) - { - for ( k = 0; k < (int)pCut->nLeaves; k++ ) - if ( pDom->pLeaves[i] == pCut->pLeaves[k] ) - break; - if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut - return 0; - } - // every node in pDom is contained in pCut - return 1; + if ( Node >= p->vCuts->nSize ) + return NULL; + return Vec_PtrEntry( p->vCuts, Node ); } /**Function************************************************************* - Synopsis [Filters cuts using dominance.] + Synopsis [Returns the pointer to the linked list of cuts.] Description [] @@ -68,293 +81,14 @@ static inline int Cut_CutCheckDominance( Cut_Cut_t * pDom, Cut_Cut_t * pCut ) SeeAlso [] ***********************************************************************/ -static inline void Cut_CutFilter( Cut_Man_t * p, Cut_Cut_t * pList ) -{ - Cut_Cut_t * pListR, ** ppListR = &pListR; - Cut_Cut_t * pCut, * pCut2, * pDom, * pPrev; - // save the first cut - *ppListR = pList, ppListR = &pList->pNext; - // try to filter out other cuts - pPrev = pList; - Cut_ListForEachCutSafe( pList->pNext, pCut, pCut2 ) - { - assert( pCut->nLeaves > 1 ); - // go through all the previous cuts up to pCut - Cut_ListForEachCutStop( pList->pNext, pDom, pCut ) - { - if ( pDom->nLeaves > pCut->nLeaves ) - continue; - if ( (pDom->uSign & pCut->uSign) != pDom->uSign ) - continue; - if ( Cut_CutCheckDominance( pDom, pCut ) ) - break; - } - if ( pDom != pCut ) // pDom is contained in pCut - recycle pCut - { - // make sure cuts are connected after removing - pPrev->pNext = pCut->pNext; - // recycle the cut - Cut_CutRecycle( p, pCut ); - } - else // pDom is NOT contained in pCut - save pCut - { - *ppListR = pCut, ppListR = &pCut->pNext; - pPrev = pCut; - } - } - *ppListR = NULL; -} - -/**Function************************************************************* - - Synopsis [Checks equality of one cut.] - - Description [Returns 1 if the cut is removed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Cut_CutFilterOneEqual( Cut_Man_t * p, Cut_List_t * pSuperList, Cut_Cut_t * pCut ) +void Cut_NodeWriteCuts( Cut_Man_t * p, int Node, Cut_Cut_t * pList ) { - Cut_Cut_t * pTemp; - Cut_ListForEachCut( pSuperList->pHead[pCut->nLeaves], pTemp ) - { - // skip the non-contained cuts - if ( pCut->uSign != pTemp->uSign ) - continue; - // check containment seriously - if ( Cut_CutCheckDominance( pTemp, pCut ) ) - { - p->nCutsFilter++; - Cut_CutRecycle( p, pCut ); - return 1; - } - } - return 0; + Vec_PtrWriteEntry( p->vCuts, Node, pList ); } /**Function************************************************************* - Synopsis [Checks containment for one cut.] - - Description [Returns 1 if the cut is removed.] - - SideEffects [May remove other cuts in the set.] - - SeeAlso [] - -***********************************************************************/ -static inline int Cut_CutFilterOne( Cut_Man_t * p, Cut_List_t * pSuperList, Cut_Cut_t * pCut ) -{ - Cut_Cut_t * pTemp, * pTemp2, ** ppTail; - int a; - - // check if this cut is filtered out by smaller cuts - for ( a = 2; a <= (int)pCut->nLeaves; a++ ) - { - Cut_ListForEachCut( pSuperList->pHead[a], pTemp ) - { - // skip the non-contained cuts - if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign ) - continue; - // check containment seriously - if ( Cut_CutCheckDominance( pTemp, pCut ) ) - { - p->nCutsFilter++; - Cut_CutRecycle( p, pCut ); - return 1; - } - } - } - - // filter out other cuts using this one - for ( a = pCut->nLeaves + 1; a <= (int)pCut->nVarsMax; a++ ) - { - ppTail = pSuperList->pHead + a; - Cut_ListForEachCutSafe( pSuperList->pHead[a], pTemp, pTemp2 ) - { - // skip the non-contained cuts - if ( (pTemp->uSign & pCut->uSign) != pCut->uSign ) - { - ppTail = &pTemp->pNext; - continue; - } - // check containment seriously - if ( Cut_CutCheckDominance( pCut, pTemp ) ) - { - p->nCutsFilter++; - p->nNodeCuts--; - // move the head - if ( pSuperList->pHead[a] == pTemp ) - pSuperList->pHead[a] = pTemp->pNext; - // move the tail - if ( pSuperList->ppTail[a] == &pTemp->pNext ) - pSuperList->ppTail[a] = ppTail; - // skip the given cut in the list - *ppTail = pTemp->pNext; - // recycle pTemp - Cut_CutRecycle( p, pTemp ); - } - else - ppTail = &pTemp->pNext; - } - assert( ppTail == pSuperList->ppTail[a] ); - assert( *ppTail == NULL ); - } - - return 0; -} - -/**Function************************************************************* - - Synopsis [Checks if the cut is local and can be removed.] - - Description [Returns 1 if the cut is removed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Cut_CutFilterGlobal( Cut_Man_t * p, Cut_Cut_t * pCut ) -{ - int a; - if ( pCut->nLeaves == 1 ) - return 0; - for ( a = 0; a < (int)pCut->nLeaves; a++ ) - if ( Vec_IntEntry( p->vNodeAttrs, pCut->pLeaves[a] ) ) // global - return 0; - // there is no global nodes, the cut should be removed - p->nCutsFilter++; - Cut_CutRecycle( p, pCut ); - return 1; -} - - -/**Function************************************************************* - - Synopsis [Checks containment for one cut.] - - Description [Returns 1 if the cut is removed.] - - SideEffects [May remove other cuts in the set.] - - SeeAlso [] - -***********************************************************************/ -static inline int Cut_CutFilterOld( Cut_Man_t * p, Cut_Cut_t * pList, Cut_Cut_t * pCut ) -{ - Cut_Cut_t * pPrev, * pTemp, * pTemp2, ** ppTail; - - // check if this cut is filtered out by smaller cuts - pPrev = NULL; - Cut_ListForEachCut( pList, pTemp ) - { - if ( pTemp->nLeaves > pCut->nLeaves ) - break; - pPrev = pTemp; - // skip the non-contained cuts - if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign ) - continue; - // check containment seriously - if ( Cut_CutCheckDominance( pTemp, pCut ) ) - { - p->nCutsFilter++; - Cut_CutRecycle( p, pCut ); - return 1; - } - } - assert( pPrev->pNext == pTemp ); - - // filter out other cuts using this one - ppTail = &pPrev->pNext; - Cut_ListForEachCutSafe( pTemp, pTemp, pTemp2 ) - { - // skip the non-contained cuts - if ( (pTemp->uSign & pCut->uSign) != pCut->uSign ) - { - ppTail = &pTemp->pNext; - continue; - } - // check containment seriously - if ( Cut_CutCheckDominance( pCut, pTemp ) ) - { - p->nCutsFilter++; - p->nNodeCuts--; - // skip the given cut in the list - *ppTail = pTemp->pNext; - // recycle pTemp - Cut_CutRecycle( p, pTemp ); - } - else - ppTail = &pTemp->pNext; - } - assert( *ppTail == NULL ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Processes two cuts.] - - Description [Returns 1 if the limit has been reached.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Cut_CutProcessTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, Cut_List_t * pSuperList ) -{ - Cut_Cut_t * pCut; - // merge the cuts - if ( pCut0->nLeaves >= pCut1->nLeaves ) - pCut = Cut_CutMergeTwo( p, pCut0, pCut1 ); - else - pCut = Cut_CutMergeTwo( p, pCut1, pCut0 ); - if ( pCut == NULL ) - return 0; - assert( p->pParams->fSeq || pCut->nLeaves > 1 ); - // set the signature - pCut->uSign = pCut0->uSign | pCut1->uSign; - if ( p->pParams->fRecord ) - pCut->Num0 = pCut0->Num0, pCut->Num1 = pCut1->Num0; - // check containment - if ( p->pParams->fFilter ) - { - if ( Cut_CutFilterOne(p, pSuperList, pCut) ) -// if ( Cut_CutFilterOneEqual(p, pSuperList, pCut) ) - return 0; - if ( p->pParams->fSeq ) - { - if ( p->pCompareOld && Cut_CutFilterOld(p, p->pCompareOld, pCut) ) - return 0; - if ( p->pCompareNew && Cut_CutFilterOld(p, p->pCompareNew, pCut) ) - return 0; - } - } - - if ( p->pParams->fGlobal ) - { - assert( p->vNodeAttrs != NULL ); - if ( Cut_CutFilterGlobal( p, pCut ) ) - return 0; - } - - // compute the truth table - if ( p->pParams->fTruth ) - Cut_TruthCompute( p, pCut, pCut0, pCut1, p->fCompl0, p->fCompl1 ); - // add to the list - Cut_ListAdd( pSuperList, pCut ); - // return status (0 if okay; 1 if exceeded the limit) - return ++p->nNodeCuts == p->pParams->nKeepMax; -} - -/**Function************************************************************* - - Synopsis [Computes the cuts by merging cuts at two nodes.] + Synopsis [Sets the trivial cut for the node.] Description [] @@ -363,68 +97,15 @@ static inline int Cut_CutProcessTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t SeeAlso [] ***********************************************************************/ -Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode ) +void Cut_NodeSetTriv( Cut_Man_t * p, int Node ) { - Cut_List_t Super, * pSuper = &Super; - Cut_Cut_t * pList, * pCut; - int clk; - // start the number of cuts at the node - p->nNodes++; - p->nNodeCuts = 0; - // prepare information for recording - if ( p->pParams->fRecord ) - { - Cut_CutNumberList( Cut_NodeReadCutsNew(p, Node0) ); - Cut_CutNumberList( Cut_NodeReadCutsNew(p, Node1) ); - } - // compute the cuts -clk = clock(); - Cut_ListStart( pSuper ); - Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, Cut_NodeReadCutsNew(p, Node0), Cut_NodeReadCutsNew(p, Node1), fTriv, TreeCode ); - pList = Cut_ListFinish( pSuper ); -p->timeMerge += clock() - clk; - // verify the result of cut computation -// Cut_CutListVerify( pList ); - // performing the recording - if ( p->pParams->fRecord ) - { - Vec_IntWriteEntry( p->vNodeStarts, Node, Vec_IntSize(p->vCutPairs) ); - Cut_ListForEachCut( pList, pCut ) - Vec_IntPush( p->vCutPairs, ((pCut->Num1 << 16) | pCut->Num0) ); - Vec_IntWriteEntry( p->vNodeCuts, Node, Vec_IntSize(p->vCutPairs) - Vec_IntEntry(p->vNodeStarts, Node) ); - } - // check if the node is over the list - if ( p->nNodeCuts == p->pParams->nKeepMax ) - p->nCutsLimit++; - // set the list at the node - Vec_PtrFillExtra( p->vCutsNew, Node + 1, NULL ); - assert( Cut_NodeReadCutsNew(p, Node) == NULL ); - ///// -// pList->pNext = NULL; - ///// - Cut_NodeWriteCutsNew( p, Node, pList ); - // filter the cuts -//clk = clock(); -// if ( p->pParams->fFilter ) -// Cut_CutFilter( p, pList0 ); -//p->timeFilter += clock() - clk; - // perform mapping of this node with these cuts -clk = clock(); - if ( p->pParams->fMap && !p->pParams->fSeq ) - { -// int Delay1, Delay2; -// Delay1 = Cut_NodeMapping( p, pList, Node, Node0, Node1 ); -// Delay2 = Cut_NodeMapping2( p, pList, Node, Node0, Node1 ); -// assert( Delay1 >= Delay2 ); - Cut_NodeMapping( p, pList, Node, Node0, Node1 ); - } -p->timeMap += clock() - clk; - return pList; + assert( Cut_NodeReadCuts(p, Node) == NULL ); + Cut_NodeWriteCuts( p, Node, Cut_CutCreateTriv(p, Node) ); } /**Function************************************************************* - Synopsis [Returns optimum delay mapping.] + Synopsis [Deallocates the cuts at the node.] Description [] @@ -433,96 +114,21 @@ p->timeMap += clock() - clk; SeeAlso [] ***********************************************************************/ -int Cut_NodeMapping2( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 ) +void Cut_NodeFreeCuts( Cut_Man_t * p, int Node ) { - Cut_Cut_t * pCut; - int DelayMin, DelayCur, i; - if ( pCuts == NULL ) - p->nDelayMin = -1; - if ( p->nDelayMin == -1 ) - return -1; - DelayMin = 1000000; - Cut_ListForEachCut( pCuts, pCut ) - { - if ( pCut->nLeaves == 1 ) - continue; - DelayCur = 0; - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - if ( DelayCur < Vec_IntEntry(p->vDelays, pCut->pLeaves[i]) ) - DelayCur = Vec_IntEntry(p->vDelays, pCut->pLeaves[i]); - if ( DelayMin > DelayCur ) - DelayMin = DelayCur; - } - if ( DelayMin == 1000000 ) - { - p->nDelayMin = -1; - return -1; - } - DelayMin++; - Vec_IntWriteEntry( p->vDelays, Node, DelayMin ); - if ( p->nDelayMin < DelayMin ) - p->nDelayMin = DelayMin; - return DelayMin; + Cut_Cut_t * pList, * pCut, * pCut2; + pList = Cut_NodeReadCuts( p, Node ); + if ( pList == NULL ) + return; + Cut_ListForEachCutSafe( pList, pCut, pCut2 ) + Cut_CutRecycle( p, pCut ); + Cut_NodeWriteCuts( p, Node, NULL ); } -/**Function************************************************************* - - Synopsis [Returns optimum delay mapping using the largest cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_NodeMapping( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 ) -{ - Cut_Cut_t * pCut0, * pCut1, * pCut; - int Delay0, Delay1, Delay; - // get the fanin cuts - Delay0 = Vec_IntEntry( p->vDelays2, Node0 ); - Delay1 = Vec_IntEntry( p->vDelays2, Node1 ); - pCut0 = (Delay0 == 0) ? Vec_PtrEntry( p->vCutsNew, Node0 ) : Vec_PtrEntry( p->vCutsMax, Node0 ); - pCut1 = (Delay1 == 0) ? Vec_PtrEntry( p->vCutsNew, Node1 ) : Vec_PtrEntry( p->vCutsMax, Node1 ); - if ( Delay0 == Delay1 ) - Delay = (Delay0 == 0) ? Delay0 + 1: Delay0; - else if ( Delay0 > Delay1 ) - { - Delay = Delay0; - pCut1 = Vec_PtrEntry( p->vCutsNew, Node1 ); - assert( pCut1->nLeaves == 1 ); - } - else // if ( Delay0 < Delay1 ) - { - Delay = Delay1; - pCut0 = Vec_PtrEntry( p->vCutsNew, Node0 ); - assert( pCut0->nLeaves == 1 ); - } - // merge the cuts - if ( pCut0->nLeaves < pCut1->nLeaves ) - pCut = Cut_CutMergeTwo( p, pCut1, pCut0 ); - else - pCut = Cut_CutMergeTwo( p, pCut0, pCut1 ); - if ( pCut == NULL ) - { - Delay++; - pCut = Cut_CutAlloc( p ); - pCut->nLeaves = 2; - pCut->pLeaves[0] = Node0 < Node1 ? Node0 : Node1; - pCut->pLeaves[1] = Node0 < Node1 ? Node1 : Node0; - } - assert( Delay > 0 ); - Vec_IntWriteEntry( p->vDelays2, Node, Delay ); - Vec_PtrWriteEntry( p->vCutsMax, Node, pCut ); - if ( p->nDelayMin < Delay ) - p->nDelayMin = Delay; - return Delay; -} /**Function************************************************************* - Synopsis [Computes area after mapping.] + Synopsis [] Description [] @@ -531,23 +137,10 @@ int Cut_NodeMapping( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int SeeAlso [] ***********************************************************************/ -int Cut_ManMappingArea_rec( Cut_Man_t * p, int Node ) +void Cut_NodeSetComputedAsNew( Cut_Man_t * p, int Node ) { - Cut_Cut_t * pCut; - int i, Counter; - if ( p->vCutsMax == NULL ) - return 0; - pCut = Vec_PtrEntry( p->vCutsMax, Node ); - if ( pCut == NULL || pCut->nLeaves == 1 ) - return 0; - Counter = 0; - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - Counter += Cut_ManMappingArea_rec( p, pCut->pLeaves[i] ); - Vec_PtrWriteEntry( p->vCutsMax, Node, NULL ); - return 1 + Counter; } - /**Function************************************************************* Synopsis [Computes the cuts by merging cuts at two nodes.] @@ -559,43 +152,24 @@ int Cut_ManMappingArea_rec( Cut_Man_t * p, int Node ) SeeAlso [] ***********************************************************************/ -void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fCompl0, int fCompl1, Cut_Cut_t * pList0, Cut_Cut_t * pList1, int fTriv, int TreeCode ) +Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1 ) { - Cut_Cut_t * pStop0, * pStop1, * pTemp0, * pTemp1, * pStore0, * pStore1; - int i, nCutsOld, Limit; - // start with the elementary cut - if ( fTriv ) - { -// printf( "Creating trivial cut %d.\n", Node ); - pTemp0 = Cut_CutCreateTriv( p, Node ); - Cut_ListAdd( pSuper, pTemp0 ); - p->nNodeCuts++; - } + Cut_List_t SuperList; + Cut_Cut_t * pList0, * pList1, * pStop0, * pStop1, * pTemp0, * pTemp1; + int i, Limit = p->pParams->nVarsMax; + int clk = clock(); + assert( p->pParams->nVarsMax <= 6 ); + // start the new list + Cut_ListStart( &SuperList ); // get the cut lists of children - if ( pList0 == NULL || pList1 == NULL || (p->pParams->fLocal && TreeCode) ) - return; - - // remember the old number of cuts - nCutsOld = p->nCutsCur; - Limit = p->pParams->nVarsMax; + pList0 = Cut_NodeReadCuts( p, Node0 ); + pList1 = Cut_NodeReadCuts( p, Node1 ); + assert( pList0 && pList1 ); // get the simultation bit of the node p->fSimul = (fCompl0 ^ pList0->fSimul) & (fCompl1 ^ pList1->fSimul); // set temporary variables p->fCompl0 = fCompl0; p->fCompl1 = fCompl1; - // if tree cuts are computed, make sure only the unit cuts propagate over the DAG nodes - if ( TreeCode & 1 ) - { - assert( pList0->nLeaves == 1 ); - pStore0 = pList0->pNext; - pList0->pNext = NULL; - } - if ( TreeCode & 2 ) - { - assert( pList1->nLeaves == 1 ); - pStore1 = pList1->pNext; - pList1->pNext = NULL; - } // find the point in the list where the max-var cuts begin Cut_ListForEachCut( pList0, pStop0 ) if ( pStop0->nLeaves == (unsigned)Limit ) @@ -603,54 +177,101 @@ void Cut_NodeDoComputeCuts( Cut_Man_t * p, Cut_List_t * pSuper, int Node, int fC Cut_ListForEachCut( pList1, pStop1 ) if ( pStop1->nLeaves == (unsigned)Limit ) break; - + // start with the elementary cut + pTemp0 = Cut_CutCreateTriv( p, Node ); + Cut_ListAdd( &SuperList, pTemp0 ); + p->nCutsNode = 1; // small by small Cut_ListForEachCutStop( pList0, pTemp0, pStop0 ) Cut_ListForEachCutStop( pList1, pTemp1, pStop1 ) - { - if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) ) - goto Quits; - } - // small by large - Cut_ListForEachCutStop( pList0, pTemp0, pStop0 ) + if ( Cut_CutProcessTwo( p, Node, pTemp0, pTemp1, &SuperList ) ) + goto finish; + // all by large + Cut_ListForEachCut( pList0, pTemp0 ) Cut_ListForEachCut( pStop1, pTemp1 ) - { - if ( (pTemp0->uSign & pTemp1->uSign) != pTemp0->uSign ) - continue; - if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) ) - goto Quits; - } - // small by large - Cut_ListForEachCutStop( pList1, pTemp1, pStop1 ) + if ( Cut_CutProcessTwo( p, Node, pTemp0, pTemp1, &SuperList ) ) + goto finish; + // all by large + Cut_ListForEachCut( pList1, pTemp1 ) Cut_ListForEachCut( pStop0, pTemp0 ) - { - if ( (pTemp0->uSign & pTemp1->uSign) != pTemp1->uSign ) - continue; - if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) ) - goto Quits; - } + if ( Cut_CutProcessTwo( p, Node, pTemp0, pTemp1, &SuperList ) ) + goto finish; // large by large Cut_ListForEachCut( pStop0, pTemp0 ) Cut_ListForEachCut( pStop1, pTemp1 ) { assert( pTemp0->nLeaves == (unsigned)Limit && pTemp1->nLeaves == (unsigned)Limit ); - if ( pTemp0->uSign != pTemp1->uSign ) - continue; for ( i = 0; i < Limit; i++ ) if ( pTemp0->pLeaves[i] != pTemp1->pLeaves[i] ) break; if ( i < Limit ) continue; - if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) ) - goto Quits; - } - if ( p->nNodeCuts == 0 ) - p->nNodesNoCuts++; -Quits: - if ( TreeCode & 1 ) - pList0->pNext = pStore0; - if ( TreeCode & 2 ) - pList1->pNext = pStore1; + if ( Cut_CutProcessTwo( p, Node, pTemp0, pTemp1, &SuperList ) ) + goto finish; + } +finish : + // set the list at the node + Vec_PtrFillExtra( p->vCuts, Node + 1, NULL ); + assert( Cut_NodeReadCuts(p, Node) == NULL ); + pList0 = Cut_ListFinish( &SuperList ); + Cut_NodeWriteCuts( p, Node, pList0 ); + // clear the hash table + if ( p->pParams->fHash && !p->pParams->fSeq ) + Cut_TableClear( p->tTable ); + // consider dropping the fanins cuts + if ( p->pParams->fDrop ) + { + Cut_NodeTryDroppingCuts( p, Node0 ); + Cut_NodeTryDroppingCuts( p, Node1 ); + } +p->timeMerge += clock() - clk; + // filter the cuts +clk = clock(); + if ( p->pParams->fFilter ) + Cut_CutFilter( p, pList0 ); +p->timeFilter += clock() - clk; + p->nNodes++; + return pList0; +} + +/**Function************************************************************* + + Synopsis [Processes two cuts.] + + Description [Returns 1 if the limit has been reached.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cut_CutProcessTwo( Cut_Man_t * p, int Root, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, Cut_List_t * pSuperList ) +{ + Cut_Cut_t * pCut; + // merge the cuts + if ( pCut0->nLeaves >= pCut1->nLeaves ) + pCut = Cut_CutMergeTwo( p, pCut0, pCut1 ); + else + pCut = Cut_CutMergeTwo( p, pCut1, pCut0 ); + if ( pCut == NULL ) + return 0; + assert( pCut->nLeaves > 1 ); + // add the root if sequential + if ( p->pParams->fSeq ) + pCut->pLeaves[pCut->nLeaves] = Root; + // check the lookup table + if ( p->pParams->fHash && Cut_TableLookup( p->tTable, pCut, !p->pParams->fSeq ) ) + { + Cut_CutRecycle( p, pCut ); + return 0; + } + // compute the truth table + if ( p->pParams->fTruth ) + Cut_TruthCompute( p, pCut, pCut0, pCut1 ); + // add to the list + Cut_ListAdd( pSuperList, pCut ); + // return status (0 if okay; 1 if exceeded the limit) + return ++p->nCutsNode == p->pParams->nKeepMax; } /**Function************************************************************* @@ -666,32 +287,33 @@ Quits: ***********************************************************************/ Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes ) { - Cut_List_t Super, * pSuper = &Super; + Cut_List_t SuperList; Cut_Cut_t * pList, * pListStart, * pCut, * pCut2, * pTop; int i, k, Node, Root, Limit = p->pParams->nVarsMax; int clk = clock(); + assert( p->pParams->nVarsMax <= 6 ); + // start the new list - Cut_ListStart( pSuper ); + Cut_ListStart( &SuperList ); // remember the root node to save the resulting cuts Root = Vec_IntEntry( vNodes, 0 ); - p->nNodeCuts = 1; + p->nCutsNode = 1; // collect small cuts first Vec_PtrClear( p->vTemp ); Vec_IntForEachEntry( vNodes, Node, i ) { // get the cuts of this node - pList = Cut_NodeReadCutsNew( p, Node ); - Cut_NodeWriteCutsNew( p, Node, NULL ); + pList = Cut_NodeReadCuts( p, Node ); + Cut_NodeWriteCuts( p, Node, NULL ); assert( pList ); // remember the starting point pListStart = pList->pNext; - pList->pNext = NULL; // save or recycle the elementary cut if ( i == 0 ) - Cut_ListAdd( pSuper, pList ), pTop = pList; + Cut_ListAdd( &SuperList, pList ), pTop = pList; else Cut_CutRecycle( p, pList ); // save all the cuts that are smaller than the limit @@ -702,19 +324,20 @@ Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes ) Vec_PtrPush( p->vTemp, pCut ); break; } - // check containment - if ( p->pParams->fFilter && Cut_CutFilterOne( p, pSuper, pCut ) ) + // check hash tables + if ( p->pParams->fHash && Cut_TableLookup( p->tTable, pCut, !p->pParams->fSeq ) ) + { + Cut_CutRecycle( p, pCut ); continue; + } // set the complemented bit by comparing the first cut with the current cut pCut->fCompl = pTop->fSimul ^ pCut->fSimul; - pListStart = pCut->pNext; - pCut->pNext = NULL; // add to the list - Cut_ListAdd( pSuper, pCut ); - if ( ++p->nNodeCuts == p->pParams->nKeepMax ) + Cut_ListAdd( &SuperList, pCut ); + if ( ++p->nCutsNode == p->pParams->nKeepMax ) { // recycle the rest of the cuts of this node - Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) + Cut_ListForEachCutSafe( pCut->pNext, pCut, pCut2 ) Cut_CutRecycle( p, pCut ); // recycle all cuts of other nodes Vec_IntForEachEntryStart( vNodes, Node, k, i+1 ) @@ -726,25 +349,25 @@ Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes ) goto finish; } } - } + } // collect larger cuts next Vec_PtrForEachEntry( p->vTemp, pList, i ) { Cut_ListForEachCutSafe( pList, pCut, pCut2 ) { - // check containment - if ( p->pParams->fFilter && Cut_CutFilterOne( p, pSuper, pCut ) ) + if ( p->pParams->fHash && Cut_TableLookup( p->tTable, pCut, !p->pParams->fSeq ) ) + { + Cut_CutRecycle( p, pCut ); continue; + } // set the complemented bit pCut->fCompl = pTop->fSimul ^ pCut->fSimul; - pListStart = pCut->pNext; - pCut->pNext = NULL; // add to the list - Cut_ListAdd( pSuper, pCut ); - if ( ++p->nNodeCuts == p->pParams->nKeepMax ) + Cut_ListAdd( &SuperList, pCut ); + if ( ++p->nCutsNode == p->pParams->nKeepMax ) { // recycle the rest of the cuts - Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) + Cut_ListForEachCutSafe( pCut->pNext, pCut, pCut2 ) Cut_CutRecycle( p, pCut ); // recycle the saved cuts of other nodes Vec_PtrForEachEntryStart( p->vTemp, pList, k, i+1 ) @@ -756,22 +379,25 @@ Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes ) } finish : // set the cuts at the node - assert( Cut_NodeReadCutsNew(p, Root) == NULL ); - pList = Cut_ListFinish( pSuper ); - Cut_NodeWriteCutsNew( p, Root, pList ); + assert( Cut_NodeReadCuts(p, Root) == NULL ); + pList = Cut_ListFinish( &SuperList ); + Cut_NodeWriteCuts( p, Root, pList ); + // clear the hash table + if ( p->pParams->fHash && !p->pParams->fSeq ) + Cut_TableClear( p->tTable ); p->timeUnion += clock() - clk; // filter the cuts -//clk = clock(); -// if ( p->pParams->fFilter ) -// Cut_CutFilter( p, pList ); -//p->timeFilter += clock() - clk; +clk = clock(); + if ( p->pParams->fFilter ) + Cut_CutFilter( p, pList ); +p->timeFilter += clock() - clk; p->nNodes -= vNodes->nSize - 1; return pList; } /**Function************************************************************* - Synopsis [Computes the cuts by unioning cuts at a choice node.] + Synopsis [Start the cut computation.] Description [] @@ -780,182 +406,157 @@ p->timeUnion += clock() - clk; SeeAlso [] ***********************************************************************/ -Cut_Cut_t * Cut_NodeUnionCutsSeq( Cut_Man_t * p, Vec_Int_t * vNodes, int CutSetNum, int fFirst ) +Cut_Cut_t * Cut_CutAlloc( Cut_Man_t * p ) { - Cut_List_t Super, * pSuper = &Super; - Cut_Cut_t * pList, * pListStart, * pCut, * pCut2, * pTop; - int i, k, Node, Root, Limit = p->pParams->nVarsMax; - int clk = clock(); + Cut_Cut_t * pCut; + // cut allocation + pCut = (Cut_Cut_t *)Extra_MmFixedEntryFetch( p->pMmCuts ); + memset( pCut, 0, sizeof(Cut_Cut_t) ); + pCut->nVarsMax = p->pParams->nVarsMax; + pCut->fSeq = p->pParams->fSeq; + pCut->fSimul = p->fSimul; + // statistics + p->nCutsAlloc++; + p->nCutsCur++; + if ( p->nCutsPeak < p->nCutsAlloc - p->nCutsDealloc ) + p->nCutsPeak = p->nCutsAlloc - p->nCutsDealloc; + return pCut; +} - // start the new list - Cut_ListStart( pSuper ); +/**Function************************************************************* - // remember the root node to save the resulting cuts - Root = Vec_IntEntry( vNodes, 0 ); - p->nNodeCuts = 1; + Synopsis [Start the cut computation.] - // store the original lists for comparison - p->pCompareOld = Cut_NodeReadCutsOld( p, Root ); - p->pCompareNew = (CutSetNum >= 0)? Cut_NodeReadCutsNew( p, Root ) : NULL; + Description [] + + SideEffects [] - // get the topmost cut - pTop = NULL; - if ( (pTop = Cut_NodeReadCutsOld( p, Root )) == NULL ) - pTop = Cut_NodeReadCutsNew( p, Root ); - assert( pTop != NULL ); + SeeAlso [] - // collect small cuts first - Vec_PtrClear( p->vTemp ); - Vec_IntForEachEntry( vNodes, Node, i ) - { - // get the cuts of this node - if ( i == 0 && CutSetNum >= 0 ) - { - pList = Cut_NodeReadCutsTemp( p, CutSetNum ); - Cut_NodeWriteCutsTemp( p, CutSetNum, NULL ); - } - else - { - pList = Cut_NodeReadCutsNew( p, Node ); - Cut_NodeWriteCutsNew( p, Node, NULL ); - } - if ( pList == NULL ) - continue; +***********************************************************************/ +Cut_Cut_t * Cut_CutCreateTriv( Cut_Man_t * p, int Node ) +{ + Cut_Cut_t * pCut; + pCut = Cut_CutAlloc( p ); + pCut->nLeaves = 1; + pCut->pLeaves[0] = Node; + if ( p->pParams->fTruth ) + Cut_CutWriteTruth( pCut, p->uTruthVars[0] ); + p->nCutsTriv++; + return pCut; +} - // process the cuts - if ( fFirst ) - { - // remember the starting point - pListStart = pList->pNext; - pList->pNext = NULL; - // save or recycle the elementary cut - if ( i == 0 ) - Cut_ListAdd( pSuper, pList ); - else - Cut_CutRecycle( p, pList ); - } - else - pListStart = pList; +/**Function************************************************************* - // save all the cuts that are smaller than the limit - Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) - { - if ( pCut->nLeaves == (unsigned)Limit ) - { - Vec_PtrPush( p->vTemp, pCut ); - break; - } - // check containment -// if ( p->pParams->fFilter && Cut_CutFilterOne( p, pSuper, pCut ) ) -// continue; - if ( p->pParams->fFilter ) - { - if ( Cut_CutFilterOne(p, pSuper, pCut) ) - continue; - if ( p->pParams->fSeq ) - { - if ( p->pCompareOld && Cut_CutFilterOld(p, p->pCompareOld, pCut) ) - continue; - if ( p->pCompareNew && Cut_CutFilterOld(p, p->pCompareNew, pCut) ) - continue; - } - } + Synopsis [Start the cut computation.] - // set the complemented bit by comparing the first cut with the current cut - pCut->fCompl = pTop->fSimul ^ pCut->fSimul; - pListStart = pCut->pNext; - pCut->pNext = NULL; - // add to the list - Cut_ListAdd( pSuper, pCut ); - if ( ++p->nNodeCuts == p->pParams->nKeepMax ) - { - // recycle the rest of the cuts of this node - Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) - Cut_CutRecycle( p, pCut ); - // recycle all cuts of other nodes - Vec_IntForEachEntryStart( vNodes, Node, k, i+1 ) - Cut_NodeFreeCuts( p, Node ); - // recycle the saved cuts of other nodes - Vec_PtrForEachEntry( p->vTemp, pList, k ) - Cut_ListForEachCutSafe( pList, pCut, pCut2 ) - Cut_CutRecycle( p, pCut ); - goto finish; - } - } - } - // collect larger cuts next - Vec_PtrForEachEntry( p->vTemp, pList, i ) - { - Cut_ListForEachCutSafe( pList, pCut, pCut2 ) - { - // check containment -// if ( p->pParams->fFilter && Cut_CutFilterOne( p, pSuper, pCut ) ) -// continue; - if ( p->pParams->fFilter ) - { - if ( Cut_CutFilterOne(p, pSuper, pCut) ) - continue; - if ( p->pParams->fSeq ) - { - if ( p->pCompareOld && Cut_CutFilterOld(p, p->pCompareOld, pCut) ) - continue; - if ( p->pCompareNew && Cut_CutFilterOld(p, p->pCompareNew, pCut) ) - continue; - } - } + Description [] + + SideEffects [] - // set the complemented bit - pCut->fCompl = pTop->fSimul ^ pCut->fSimul; - pListStart = pCut->pNext; - pCut->pNext = NULL; - // add to the list - Cut_ListAdd( pSuper, pCut ); - if ( ++p->nNodeCuts == p->pParams->nKeepMax ) - { - // recycle the rest of the cuts - Cut_ListForEachCutSafe( pListStart, pCut, pCut2 ) - Cut_CutRecycle( p, pCut ); - // recycle the saved cuts of other nodes - Vec_PtrForEachEntryStart( p->vTemp, pList, k, i+1 ) - Cut_ListForEachCutSafe( pList, pCut, pCut2 ) - Cut_CutRecycle( p, pCut ); - goto finish; - } - } - } -finish : - // set the cuts at the node - pList = Cut_ListFinish( pSuper ); + SeeAlso [] - // set the lists at the node -// assert( Cut_NodeReadCutsNew(p, Root) == NULL ); -// Cut_NodeWriteCutsNew( p, Root, pList ); - if ( CutSetNum >= 0 ) - { - assert( Cut_NodeReadCutsTemp(p, CutSetNum) == NULL ); - Cut_NodeWriteCutsTemp( p, CutSetNum, pList ); - } - else - { - assert( Cut_NodeReadCutsNew(p, Root) == NULL ); - Cut_NodeWriteCutsNew( p, Root, pList ); - } +***********************************************************************/ +void Cut_CutRecycle( Cut_Man_t * p, Cut_Cut_t * pCut ) +{ + p->nCutsDealloc++; + p->nCutsCur--; + if ( pCut->nLeaves == 1 ) + p->nCutsTriv--; + Extra_MmFixedEntryRecycle( p->pMmCuts, (char *)pCut ); +} -p->timeUnion += clock() - clk; - // filter the cuts -//clk = clock(); -// if ( p->pParams->fFilter ) -// Cut_CutFilter( p, pList ); -//p->timeFilter += clock() - clk; -// if ( fFirst ) -// p->nNodes -= vNodes->nSize - 1; - return pList; + +/**Function************************************************************* + + Synopsis [Consider dropping cuts if they are useless by now.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_NodeTryDroppingCuts( Cut_Man_t * p, int Node ) +{ + int nFanouts; + assert( p->vFanCounts ); + nFanouts = Vec_IntEntry( p->vFanCounts, Node ); + assert( nFanouts > 0 ); + if ( --nFanouts == 0 ) + Cut_NodeFreeCuts( p, Node ); + Vec_IntWriteEntry( p->vFanCounts, Node, nFanouts ); +} + +/**Function************************************************************* + + Synopsis [Print the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_CutPrint( Cut_Cut_t * pCut ) +{ + int i; + assert( pCut->nLeaves > 0 ); + printf( "%d : {", pCut->nLeaves ); + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + printf( " %d", pCut->pLeaves[i] ); + printf( " }" ); +} + +/**Function************************************************************* + + Synopsis [Consider dropping cuts if they are useless by now.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_CutPrintMerge( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) +{ + printf( "\n" ); + printf( "%d : %5d %5d %5d %5d %5d\n", + pCut0->nLeaves, + pCut0->nLeaves > 0 ? pCut0->pLeaves[0] : -1, + pCut0->nLeaves > 1 ? pCut0->pLeaves[1] : -1, + pCut0->nLeaves > 2 ? pCut0->pLeaves[2] : -1, + pCut0->nLeaves > 3 ? pCut0->pLeaves[3] : -1, + pCut0->nLeaves > 4 ? pCut0->pLeaves[4] : -1 + ); + printf( "%d : %5d %5d %5d %5d %5d\n", + pCut1->nLeaves, + pCut1->nLeaves > 0 ? pCut1->pLeaves[0] : -1, + pCut1->nLeaves > 1 ? pCut1->pLeaves[1] : -1, + pCut1->nLeaves > 2 ? pCut1->pLeaves[2] : -1, + pCut1->nLeaves > 3 ? pCut1->pLeaves[3] : -1, + pCut1->nLeaves > 4 ? pCut1->pLeaves[4] : -1 + ); + if ( pCut == NULL ) + printf( "Cannot merge\n" ); + else + printf( "%d : %5d %5d %5d %5d %5d\n", + pCut->nLeaves, + pCut->nLeaves > 0 ? pCut->pLeaves[0] : -1, + pCut->nLeaves > 1 ? pCut->pLeaves[1] : -1, + pCut->nLeaves > 2 ? pCut->pLeaves[2] : -1, + pCut->nLeaves > 3 ? pCut->pLeaves[3] : -1, + pCut->nLeaves > 4 ? pCut->pLeaves[4] : -1 + ); } /**Function************************************************************* - Synopsis [Verifies that the list contains only non-dominated cuts.] + Synopsis [Filter the cuts using dominance.] Description [] @@ -964,27 +565,62 @@ p->timeUnion += clock() - clk; SeeAlso [] ***********************************************************************/ -int Cut_CutListVerify( Cut_Cut_t * pList ) +void Cut_CutFilter( Cut_Man_t * p, Cut_Cut_t * pList ) { - Cut_Cut_t * pCut, * pDom; - Cut_ListForEachCut( pList, pCut ) + Cut_Cut_t * pListR, ** ppListR = &pListR; + Cut_Cut_t * pCut, * pCut2, * pDom, * pPrev; + int i, k; + // save the first cut + *ppListR = pList, ppListR = &pList->pNext; + // try to filter out other cuts + pPrev = pList; + Cut_ListForEachCutSafe( pList->pNext, pCut, pCut2 ) { - Cut_ListForEachCutStop( pList, pDom, pCut ) + assert( pCut->nLeaves > 1 ); + // go through all the previous cuts up to pCut + Cut_ListForEachCutStop( pList->pNext, pDom, pCut ) { - if ( Cut_CutCheckDominance( pDom, pCut ) ) + if ( pDom->nLeaves >= pCut->nLeaves ) + continue; + // check if every node in pDom is contained in pCut + for ( i = 0; i < (int)pDom->nLeaves; i++ ) { - int x = 0; - printf( "******************* These are contained cuts:\n" ); - Cut_CutPrint( pDom, 1 ); - Cut_CutPrint( pDom, 1 ); - - return 0; + for ( k = 0; k < (int)pCut->nLeaves; k++ ) + if ( pDom->pLeaves[i] == pCut->pLeaves[k] ) + break; + if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut + break; } + if ( i == (int)pDom->nLeaves ) // every node in pDom is contained in pCut + break; + } + if ( pDom != pCut ) // pDom is contained in pCut - recycle pCut + { + // make sure cuts are connected after removing + pPrev->pNext = pCut->pNext; +/* + // report + printf( "Recycling cut: " ); + Cut_CutPrint( pCut ); + printf( "\n" ); + printf( "As contained in: " ); + Cut_CutPrint( pDom ); + printf( "\n" ); +*/ + // recycle the cut + Cut_CutRecycle( p, pCut ); + } + else // pDom is NOT contained in pCut - save pCut + { + *ppListR = pCut, ppListR = &pCut->pNext; + pPrev = pCut; } } - return 1; + *ppListR = NULL; } + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/cut/cutOracle.c b/src/opt/cut/cutOracle.c deleted file mode 100644 index 3eb4462b..00000000 --- a/src/opt/cut/cutOracle.c +++ /dev/null @@ -1,428 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutOracle.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [K-feasible cut computation package.] - - Synopsis [Procedures to compute cuts for a node using the oracle.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutOracle.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "cutInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -struct Cut_OracleStruct_t_ -{ - // cut comptupatation parameters - Cut_Params_t * pParams; - Vec_Int_t * vFanCounts; - int fSimul; - // storage for cuts - Vec_Ptr_t * vCutsNew; - Vec_Ptr_t * vCuts0; - Vec_Ptr_t * vCuts1; - // oracle info - Vec_Int_t * vNodeCuts; - Vec_Int_t * vNodeStarts; - Vec_Int_t * vCutPairs; - // memory management - Extra_MmFixed_t * pMmCuts; - int EntrySize; - int nTruthWords; - // stats - int timeTotal; - int nCuts; - int nCutsTriv; -}; - -static Cut_Cut_t * Cut_CutStart( Cut_Oracle_t * p ); -static Cut_Cut_t * Cut_CutTriv( Cut_Oracle_t * p, int Node ); -static Cut_Cut_t * Cut_CutMerge( Cut_Oracle_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts the cut oracle.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Oracle_t * Cut_OracleStart( Cut_Man_t * pMan ) -{ - Cut_Oracle_t * p; - int clk = clock(); - - assert( pMan->pParams->nVarsMax >= 3 && pMan->pParams->nVarsMax <= CUT_SIZE_MAX ); - assert( pMan->pParams->fRecord ); - - p = ALLOC( Cut_Oracle_t, 1 ); - memset( p, 0, sizeof(Cut_Oracle_t) ); - - // set and correct parameters - p->pParams = pMan->pParams; - - // transfer the recording info - p->vNodeCuts = pMan->vNodeCuts; pMan->vNodeCuts = NULL; - p->vNodeStarts = pMan->vNodeStarts; pMan->vNodeStarts = NULL; - p->vCutPairs = pMan->vCutPairs; pMan->vCutPairs = NULL; - - // prepare storage for cuts - p->vCutsNew = Vec_PtrAlloc( p->pParams->nIdsMax ); - Vec_PtrFill( p->vCutsNew, p->pParams->nIdsMax, NULL ); - p->vCuts0 = Vec_PtrAlloc( 100 ); - p->vCuts1 = Vec_PtrAlloc( 100 ); - - // entry size - p->EntrySize = sizeof(Cut_Cut_t) + p->pParams->nVarsMax * sizeof(int); - if ( p->pParams->fTruth ) - { - if ( p->pParams->nVarsMax > 8 ) - { - p->pParams->fTruth = 0; - printf( "Skipping computation of truth table for more than 8 inputs.\n" ); - } - else - { - p->nTruthWords = Cut_TruthWords( p->pParams->nVarsMax ); - p->EntrySize += p->nTruthWords * sizeof(unsigned); - } - } - // memory for cuts - p->pMmCuts = Extra_MmFixedStart( p->EntrySize ); - return p; -} -/**Function************************************************************* - - Synopsis [Stop the cut oracle.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_OracleStop( Cut_Oracle_t * p ) -{ - Cut_Cut_t * pCut; - int i; - -// if ( p->pParams->fVerbose ) - { - printf( "Cut computation statistics with oracle:\n" ); - printf( "Current cuts = %8d. (Trivial = %d.)\n", p->nCuts-p->nCutsTriv, p->nCutsTriv ); - PRT( "Total time ", p->timeTotal ); - } - - Vec_PtrForEachEntry( p->vCutsNew, pCut, i ) - if ( pCut != NULL ) - { - int k = 0; - } - if ( p->vCuts0 ) Vec_PtrFree( p->vCuts0 ); - if ( p->vCuts1 ) Vec_PtrFree( p->vCuts1 ); - if ( p->vCutsNew ) Vec_PtrFree( p->vCutsNew ); - if ( p->vFanCounts ) Vec_IntFree( p->vFanCounts ); - - if ( p->vNodeCuts ) Vec_IntFree( p->vNodeCuts ); - if ( p->vNodeStarts ) Vec_IntFree( p->vNodeStarts ); - if ( p->vCutPairs ) Vec_IntFree( p->vCutPairs ); - - Extra_MmFixedStop( p->pMmCuts ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_OracleSetFanoutCounts( Cut_Oracle_t * p, Vec_Int_t * vFanCounts ) -{ - p->vFanCounts = vFanCounts; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_OracleReadDrop( Cut_Oracle_t * p ) -{ - return p->pParams->fDrop; -} - -/**Function************************************************************* - - Synopsis [Sets the trivial cut for the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_OracleNodeSetTriv( Cut_Oracle_t * p, int Node ) -{ - assert( Vec_PtrEntry( p->vCutsNew, Node ) == NULL ); - Vec_PtrWriteEntry( p->vCutsNew, Node, Cut_CutTriv(p, Node) ); -} - - - -/**Function************************************************************* - - Synopsis [Allocates the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutStart( Cut_Oracle_t * p ) -{ - Cut_Cut_t * pCut; - // cut allocation - pCut = (Cut_Cut_t *)Extra_MmFixedEntryFetch( p->pMmCuts ); - memset( pCut, 0, sizeof(Cut_Cut_t) ); - pCut->nVarsMax = p->pParams->nVarsMax; - pCut->fSimul = p->fSimul; - p->nCuts++; - return pCut; -} - -/**Function************************************************************* - - Synopsis [Creates the trivial cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutTriv( Cut_Oracle_t * p, int Node ) -{ - Cut_Cut_t * pCut; - pCut = Cut_CutStart( p ); - pCut->nLeaves = 1; - pCut->pLeaves[0] = Node; - if ( p->pParams->fTruth ) - { - unsigned * pTruth = Cut_CutReadTruth(pCut); - int i; - for ( i = 0; i < p->nTruthWords; i++ ) - pTruth[i] = 0xAAAAAAAA; - } - p->nCutsTriv++; - return pCut; -} - -/**Function************************************************************* - - Synopsis [Merges two cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutMerge( Cut_Oracle_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) -{ - Cut_Cut_t * pCut; - int Limit, i, k, c; - // create the leaves of the new cut - pCut = Cut_CutStart( p ); - Limit = p->pParams->nVarsMax; - for ( i = k = c = 0; c < Limit; c++ ) - { - if ( k == (int)pCut1->nLeaves ) - { - if ( i == (int)pCut0->nLeaves ) - { - pCut->nLeaves = c; - return pCut; - } - pCut->pLeaves[c] = pCut0->pLeaves[i++]; - continue; - } - if ( i == (int)pCut0->nLeaves ) - { - if ( k == (int)pCut1->nLeaves ) - { - pCut->nLeaves = c; - return pCut; - } - pCut->pLeaves[c] = pCut1->pLeaves[k++]; - continue; - } - if ( pCut0->pLeaves[i] < pCut1->pLeaves[k] ) - { - pCut->pLeaves[c] = pCut0->pLeaves[i++]; - continue; - } - if ( pCut0->pLeaves[i] > pCut1->pLeaves[k] ) - { - pCut->pLeaves[c] = pCut1->pLeaves[k++]; - continue; - } - pCut->pLeaves[c] = pCut0->pLeaves[i++]; - k++; - } - assert( i == (int)pCut0->nLeaves && k == (int)pCut1->nLeaves ); - pCut->nLeaves = c; - return pCut; -} - -/**Function************************************************************* - - Synopsis [Reconstruct the cuts of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_OracleComputeCuts( Cut_Oracle_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1 ) -{ - Cut_Cut_t * pList = NULL, ** ppTail = &pList; - Cut_Cut_t * pCut, * pCut0, * pCut1, * pList0, * pList1; - int iCutStart, nCuts, i, Entry; - int clk = clock(); - - // get the cuts of the children - pList0 = Vec_PtrEntry( p->vCutsNew, Node0 ); - pList1 = Vec_PtrEntry( p->vCutsNew, Node1 ); - assert( pList0 && pList1 ); - - // get the complemented attribute of the cut - p->fSimul = (fCompl0 ^ pList0->fSimul) & (fCompl1 ^ pList1->fSimul); - - // collect the cuts - Vec_PtrClear( p->vCuts0 ); - Cut_ListForEachCut( pList0, pCut ) - Vec_PtrPush( p->vCuts0, pCut ); - Vec_PtrClear( p->vCuts1 ); - Cut_ListForEachCut( pList1, pCut ) - Vec_PtrPush( p->vCuts1, pCut ); - - // get the first and last cuts of this node - nCuts = Vec_IntEntry(p->vNodeCuts, Node); - iCutStart = Vec_IntEntry(p->vNodeStarts, Node); - - // create trivial cut - assert( Vec_IntEntry(p->vCutPairs, iCutStart) == 0 ); - pCut = Cut_CutTriv( p, Node ); - *ppTail = pCut; - ppTail = &pCut->pNext; - // create other cuts - for ( i = 1; i < nCuts; i++ ) - { - Entry = Vec_IntEntry( p->vCutPairs, iCutStart + i ); - pCut0 = Vec_PtrEntry( p->vCuts0, Entry & 0xFFFF ); - pCut1 = Vec_PtrEntry( p->vCuts1, Entry >> 16 ); - pCut = Cut_CutMerge( p, pCut0, pCut1 ); - *ppTail = pCut; - ppTail = &pCut->pNext; - // compute the truth table - if ( p->pParams->fTruth ) - Cut_TruthComputeOld( pCut, pCut0, pCut1, fCompl0, fCompl1 ); - } - *ppTail = NULL; - - // write the new cut - assert( Vec_PtrEntry( p->vCutsNew, Node ) == NULL ); - Vec_PtrWriteEntry( p->vCutsNew, Node, pList ); -p->timeTotal += clock() - clk; - return pList; -} - -/**Function************************************************************* - - Synopsis [Deallocates the cuts at the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_OracleFreeCuts( Cut_Oracle_t * p, int Node ) -{ - Cut_Cut_t * pList, * pCut, * pCut2; - pList = Vec_PtrEntry( p->vCutsNew, Node ); - if ( pList == NULL ) - return; - Cut_ListForEachCutSafe( pList, pCut, pCut2 ) - Extra_MmFixedEntryRecycle( p->pMmCuts, (char *)pCut ); - Vec_PtrWriteEntry( p->vCutsNew, Node, pList ); -} - -/**Function************************************************************* - - Synopsis [Consider dropping cuts if they are useless by now.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_OracleTryDroppingCuts( Cut_Oracle_t * p, int Node ) -{ - int nFanouts; - assert( p->vFanCounts ); - nFanouts = Vec_IntEntry( p->vFanCounts, Node ); - assert( nFanouts > 0 ); - if ( --nFanouts == 0 ) - Cut_OracleFreeCuts( p, Node ); - Vec_IntWriteEntry( p->vFanCounts, Node, nFanouts ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/cut/cutPre22.c b/src/opt/cut/cutPre22.c deleted file mode 100644 index 5cb87a9c..00000000 --- a/src/opt/cut/cutPre22.c +++ /dev/null @@ -1,988 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutPre22.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Precomputes truth tables for the 2x2 macro cell.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutPre22.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "cutInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define CUT_CELL_MVAR 9 - -typedef struct Cut_Cell_t_ Cut_Cell_t; -typedef struct Cut_CMan_t_ Cut_CMan_t; - -struct Cut_Cell_t_ -{ - Cut_Cell_t * pNext; // pointer to the next cell in the table - Cut_Cell_t * pNextVar; // pointer to the next cell of this support size - Cut_Cell_t * pParent; // pointer to the cell used to derive this one - int nUsed; // the number of times the cell is used - char Box[4]; // functions in the boxes - unsigned nVars : 4; // the number of variables - unsigned CrossBar0 : 4; // the variable set equal - unsigned CrossBar1 : 4; // the variable set equal - unsigned CrossBarPhase : 2; // the phase of the cross bar (0, 1, or 2) - unsigned CanonPhase : 18; // the canonical phase - char CanonPerm[CUT_CELL_MVAR+3]; // semicanonical permutation - short Store[2*CUT_CELL_MVAR]; // minterm counts in the cofactors - unsigned uTruth[1<<(CUT_CELL_MVAR-5)]; // the current truth table -}; - -struct Cut_CMan_t_ -{ - // storage for canonical cells - Extra_MmFixed_t * pMem; - st_table * tTable; - Cut_Cell_t * pSameVar[CUT_CELL_MVAR+1]; - // elementary truth tables - unsigned uInputs[CUT_CELL_MVAR][1<<(CUT_CELL_MVAR-5)]; - // temporary truth tables - unsigned uTemp1[22][1<<(CUT_CELL_MVAR-5)]; - unsigned uTemp2[22][1<<(CUT_CELL_MVAR-5)]; - unsigned uTemp3[22][1<<(CUT_CELL_MVAR-5)]; - unsigned uFinal[1<<(CUT_CELL_MVAR-5)]; - unsigned puAux[1<<(CUT_CELL_MVAR-5)]; - // statistical variables - int nTotal; - int nGood; - int nVarCounts[CUT_CELL_MVAR+1]; - int nSymGroups[CUT_CELL_MVAR+1]; - int nSymGroupsE[CUT_CELL_MVAR+1]; - int timeCanon; - int timeSupp; - int timeTable; - int nCellFound; - int nCellNotFound; -}; - -// NP-classes of functions of 3 variables (22) -static char * s_NP3[22] = { - " 0\n", // 00 const 0 // 0 vars - " 1\n", // 01 const 1 // 0 vars - "1 1\n", // 02 a // 1 vars - "11 1\n", // 03 ab // 2 vars - "11 0\n", // 04 (ab)' // 2 vars - "10 1\n01 1\n", // 05 a<+>b // 2 vars - "111 1\n", // 06 0s abc // 3 vars - "111 0\n", // 07 (abc)' // - "11- 1\n1-1 1\n", // 08 1p a(b+c) // - "11- 0\n1-1 0\n", // 09 (a(b+c))' // - "111 1\n100 1\n010 1\n001 1\n", // 10 2s a<+>b<+>c // - "10- 0\n1-0 0\n011 0\n", // 11 3p a<+>bc // - "101 1\n110 1\n", // 12 4p a(b<+>c) // - "101 0\n110 0\n", // 13 (a(b<+>c))' // - "11- 1\n1-1 1\n-11 1\n", // 14 5s ab+bc+ac // - "111 1\n000 1\n", // 15 6s abc+a'b'c' // - "111 0\n000 0\n", // 16 (abc+a'b'c')' // - "11- 1\n-11 1\n0-1 1\n", // 17 7 ab+bc+a'c // - "011 1\n101 1\n110 1\n", // 18 8s a'bc+ab'c+abc' // - "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')' // - "100 1\n-11 1\n", // 20 9p ab'c'+bc // - "100 0\n-11 0\n" // 21 (ab'c'+bc)' // -}; - -// NP-classes of functions of 3 variables (22) -static char * s_NP3Names[22] = { - " const 0 ", - " const 1 ", - " a ", - " ab ", - " (ab)' ", - " a<+>b ", - "0s abc ", - " (abc)' ", - "1p a(b+c) ", - " (a(b+c))' ", - "2s a<+>b<+>c ", - "3p a<+>bc ", - "4p a(b<+>c) ", - " (a(b<+>c))' ", - "5s ab+bc+ac ", - "6s abc+a'b'c' ", - " (abc+a'b'c')' ", - "7 ab+bc+a'c ", - "8s a'bc+ab'c+abc' ", - " (a'bc+ab'c+abc')' ", - "9p ab'c'+bc ", - " (ab'c'+bc)' " -}; - -// the number of variables in each function -static int s_NP3VarNums[22] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; - -// NPN classes of functions of exactly 3 inputs (10) -static int s_NPNe3[10] = { 6, 8, 10, 11, 12, 14, 15, 17, 18, 20 }; - -// NPN classes of functions of exactly 3 inputs that are symmetric (5) -static int s_NPNe3s[10] = { 6, 10, 14, 15, 18 }; - -// NPN classes of functions of exactly 3 inputs (4) -static int s_NPNe3p[10] = { 8, 11, 12, 20 }; - -static Cut_CMan_t * Cut_CManStart(); -static void Cut_CManStop( Cut_CMan_t * p ); -static void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type ); -static void Cut_CellCanonicize( Cut_CMan_t * p, Cut_Cell_t * pCell ); -static int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell ); -static void Cut_CellSuppMin( Cut_Cell_t * pCell ); -static void Cut_CellCrossBar( Cut_Cell_t * pCell ); - - -static Cut_CMan_t * s_pCMan = NULL; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Start the precomputation manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CellLoad() -{ - FILE * pFile; - char * pFileName = "cells22_daomap_iwls.txt"; - char pString[1000]; - Cut_CMan_t * p; - Cut_Cell_t * pCell; - int Length; //, i; - pFile = fopen( pFileName, "r" ); - if ( pFile == NULL ) - { - printf( "Cannot open file \"%s\".\n", pFileName ); - return; - } - // start the manager - p = Cut_CManStart(); - // load truth tables - while ( fgets(pString, 1000, pFile) ) - { - Length = strlen(pString); - pString[Length--] = 0; - if ( Length == 0 ) - continue; - // derive the cell - pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); - memset( pCell, 0, sizeof(Cut_Cell_t) ); - pCell->nVars = Extra_Base2Log(Length*4); - pCell->nUsed = 1; -// Extra_TruthCopy( pCell->uTruth, pTruth, nVars ); - Extra_ReadHexadecimal( pCell->uTruth, pString, pCell->nVars ); - Cut_CellSuppMin( pCell ); -/* - // set the elementary permutation - for ( i = 0; i < (int)pCell->nVars; i++ ) - pCell->CanonPerm[i] = i; - // canonicize - pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); -*/ - // add to the table - p->nTotal++; - -// Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); printf( "\n" ); -// if ( p->nTotal == 500 ) -// break; - - if ( !Cut_CellTableLookup( p, pCell ) ) // new cell - p->nGood++; - } - printf( "Read %d cells from file \"%s\". Added %d cells to the table.\n", p->nTotal, pFileName, p->nGood ); - fclose( pFile ); -// return p; -} - -/**Function************************************************************* - - Synopsis [Precomputes truth tables for the 2x2 macro cell.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CellPrecompute() -{ - Cut_CMan_t * p; - Cut_Cell_t * pCell, * pTemp; - int i1, i2, i3, i, j, k, c, clk = clock(), clk2 = clock(); - - p = Cut_CManStart(); - - // precompute truth tables - for ( i = 0; i < 22; i++ ) - Cut_CellTruthElem( p->uInputs[0], p->uInputs[1], p->uInputs[2], p->uTemp1[i], 9, i ); - for ( i = 0; i < 22; i++ ) - Cut_CellTruthElem( p->uInputs[3], p->uInputs[4], p->uInputs[5], p->uTemp2[i], 9, i ); - for ( i = 0; i < 22; i++ ) - Cut_CellTruthElem( p->uInputs[6], p->uInputs[7], p->uInputs[8], p->uTemp3[i], 9, i ); -/* - if ( k == 8 && ((i1 == 6 && i2 == 14 && i3 == 20) || (i1 == 20 && i2 == 6 && i3 == 14)) ) - { - Extra_PrintBinary( stdout, &pCell->CanonPhase, pCell->nVars+1 ); printf( " : " ); - for ( i = 0; i < pCell->nVars; i++ ) - printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] ); - Extra_PrintHexadecimal( stdout, pCell->uTruth, pCell->nVars ); - printf( "\n" ); - } -*/ -/* - // go through symmetric roots - for ( k = 0; k < 5; k++ ) - for ( i1 = 0; i1 < 22; i1++ ) - for ( i2 = i1; i2 < 22; i2++ ) - for ( i3 = i2; i3 < 22; i3++ ) - { - // derive the cell - pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); - memset( pCell, 0, sizeof(Cut_Cell_t) ); - pCell->nVars = 9; - pCell->Box[0] = s_NPNe3s[k]; - pCell->Box[1] = i1; - pCell->Box[2] = i2; - pCell->Box[3] = i3; - // fill in the truth table - Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3s[k] ); - // canonicize - Cut_CellCanonicize( pCell ); - - // add to the table - p->nTotal++; - if ( Cut_CellTableLookup( p, pCell ) ) // already exists - Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); - else - p->nGood++; - } - - // go through partially symmetric roots - for ( k = 0; k < 4; k++ ) - for ( i1 = 0; i1 < 22; i1++ ) - for ( i2 = 0; i2 < 22; i2++ ) - for ( i3 = i2; i3 < 22; i3++ ) - { - // derive the cell - pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); - memset( pCell, 0, sizeof(Cut_Cell_t) ); - pCell->nVars = 9; - pCell->Box[0] = s_NPNe3p[k]; - pCell->Box[1] = i1; - pCell->Box[2] = i2; - pCell->Box[3] = i3; - // fill in the truth table - Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3p[k] ); - // canonicize - Cut_CellCanonicize( pCell ); - - // add to the table - p->nTotal++; - if ( Cut_CellTableLookup( p, pCell ) ) // already exists - Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); - else - p->nGood++; - } - - // go through non-symmetric functions - for ( i1 = 0; i1 < 22; i1++ ) - for ( i2 = 0; i2 < 22; i2++ ) - for ( i3 = 0; i3 < 22; i3++ ) - { - // derive the cell - pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); - memset( pCell, 0, sizeof(Cut_Cell_t) ); - pCell->nVars = 9; - pCell->Box[0] = 17; - pCell->Box[1] = i1; - pCell->Box[2] = i2; - pCell->Box[3] = i3; - // fill in the truth table - Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, 17 ); - // canonicize - Cut_CellCanonicize( pCell ); - - // add to the table - p->nTotal++; - if ( Cut_CellTableLookup( p, pCell ) ) // already exists - Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); - else - p->nGood++; - } -*/ - - // go through non-symmetric functions - for ( k = 0; k < 10; k++ ) - for ( i1 = 0; i1 < 22; i1++ ) - for ( i2 = 0; i2 < 22; i2++ ) - for ( i3 = 0; i3 < 22; i3++ ) - { - // derive the cell - pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); - memset( pCell, 0, sizeof(Cut_Cell_t) ); - pCell->nVars = 9; - pCell->Box[0] = s_NPNe3[k]; - pCell->Box[1] = i1; - pCell->Box[2] = i2; - pCell->Box[3] = i3; - // set the elementary permutation - for ( i = 0; i < (int)pCell->nVars; i++ ) - pCell->CanonPerm[i] = i; - // fill in the truth table - Cut_CellTruthElem( p->uTemp1[i1], p->uTemp2[i2], p->uTemp3[i3], pCell->uTruth, 9, s_NPNe3[k] ); - // minimize the support - Cut_CellSuppMin( pCell ); - - // canonicize - pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); - - // add to the table - p->nTotal++; - if ( Cut_CellTableLookup( p, pCell ) ) // already exists - Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); - else - { - p->nGood++; - p->nVarCounts[pCell->nVars]++; - - if ( pCell->nVars ) - for ( i = 0; i < (int)pCell->nVars-1; i++ ) - { - if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric - continue; - // i and i+1 can be symmetric - // find the end of this group - for ( j = i+1; j < (int)pCell->nVars; j++ ) - if ( pCell->Store[2*i] != pCell->Store[2*j] ) - break; - - if ( pCell->Store[2*i] == pCell->Store[2*i+1] ) - p->nSymGroupsE[j-i]++; - else - p->nSymGroups[j-i]++; - i = j - 1; - } -/* - if ( pCell->nVars == 3 ) - { - Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" ); - for ( i = 0; i < (int)pCell->nVars; i++ ) - printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] ); - printf( "\n" ); - } -*/ - } - } - - printf( "BASIC: Total = %d. Good = %d. Entry = %d. ", p->nTotal, p->nGood, sizeof(Cut_Cell_t) ); - PRT( "Time", clock() - clk ); - printf( "Cells: " ); - for ( i = 0; i <= 9; i++ ) - printf( "%d=%d ", i, p->nVarCounts[i] ); - printf( "\nDiffs: " ); - for ( i = 0; i <= 9; i++ ) - printf( "%d=%d ", i, p->nSymGroups[i] ); - printf( "\nEquals: " ); - for ( i = 0; i <= 9; i++ ) - printf( "%d=%d ", i, p->nSymGroupsE[i] ); - printf( "\n" ); - - // continue adding new cells using support - for ( k = CUT_CELL_MVAR; k > 3; k-- ) - { - for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar ) - for ( i1 = 0; i1 < k; i1++ ) - for ( i2 = i1+1; i2 < k; i2++ ) - for ( c = 0; c < 3; c++ ) - { - // derive the cell - pCell = (Cut_Cell_t *)Extra_MmFixedEntryFetch( p->pMem ); - memset( pCell, 0, sizeof(Cut_Cell_t) ); - pCell->nVars = pTemp->nVars; - pCell->pParent = pTemp; - // set the elementary permutation - for ( i = 0; i < (int)pCell->nVars; i++ ) - pCell->CanonPerm[i] = i; - // fill in the truth table - Extra_TruthCopy( pCell->uTruth, pTemp->uTruth, pTemp->nVars ); - // create the cross-bar - pCell->CrossBar0 = i1; - pCell->CrossBar1 = i2; - pCell->CrossBarPhase = c; - Cut_CellCrossBar( pCell ); - // minimize the support -//clk2 = clock(); - Cut_CellSuppMin( pCell ); -//p->timeSupp += clock() - clk2; - // canonicize -//clk2 = clock(); - pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); -//p->timeCanon += clock() - clk2; - - // add to the table -//clk2 = clock(); - p->nTotal++; - if ( Cut_CellTableLookup( p, pCell ) ) // already exists - Extra_MmFixedEntryRecycle( p->pMem, (char *)pCell ); - else - { - p->nGood++; - p->nVarCounts[pCell->nVars]++; - - for ( i = 0; i < (int)pCell->nVars-1; i++ ) - { - if ( pCell->Store[2*i] != pCell->Store[2*(i+1)] ) // i and i+1 cannot be symmetric - continue; - // i and i+1 can be symmetric - // find the end of this group - for ( j = i+1; j < (int)pCell->nVars; j++ ) - if ( pCell->Store[2*i] != pCell->Store[2*j] ) - break; - - if ( pCell->Store[2*i] == pCell->Store[2*i+1] ) - p->nSymGroupsE[j-i]++; - else - p->nSymGroups[j-i]++; - i = j - 1; - } -/* - if ( pCell->nVars == 3 ) - { - Extra_PrintBinary( stdout, pCell->uTruth, 32 ); printf( "\n" ); - for ( i = 0; i < (int)pCell->nVars; i++ ) - printf( "%d=%d/%d ", pCell->CanonPerm[i], pCell->Store[2*i], pCell->Store[2*i+1] ); - printf( "\n" ); - } -*/ - } -//p->timeTable += clock() - clk2; - } - - printf( "VAR %d: Total = %d. Good = %d. Entry = %d. ", k, p->nTotal, p->nGood, sizeof(Cut_Cell_t) ); - PRT( "Time", clock() - clk ); - printf( "Cells: " ); - for ( i = 0; i <= 9; i++ ) - printf( "%d=%d ", i, p->nVarCounts[i] ); - printf( "\nDiffs: " ); - for ( i = 0; i <= 9; i++ ) - printf( "%d=%d ", i, p->nSymGroups[i] ); - printf( "\nEquals: " ); - for ( i = 0; i <= 9; i++ ) - printf( "%d=%d ", i, p->nSymGroupsE[i] ); - printf( "\n" ); - } -// printf( "\n" ); - PRT( "Supp ", p->timeSupp ); - PRT( "Canon", p->timeCanon ); - PRT( "Table", p->timeTable ); -// Cut_CManStop( p ); -} - -/**Function************************************************************* - - Synopsis [Check the table.] - - Description [Returns 1 if such a truth table already exists.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_CellTableLookup( Cut_CMan_t * p, Cut_Cell_t * pCell ) -{ - Cut_Cell_t ** pSlot, * pTemp; - unsigned Hash; - Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum( pCell->nVars ) ); - if ( !st_find_or_add( p->tTable, (char *)Hash, (char ***)&pSlot ) ) - *pSlot = NULL; - for ( pTemp = *pSlot; pTemp; pTemp = pTemp->pNext ) - { - if ( pTemp->nVars != pCell->nVars ) - continue; - if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) ) - return 1; - } - // the entry is new - pCell->pNext = *pSlot; - *pSlot = pCell; - // add it to the variable support list - pCell->pNextVar = p->pSameVar[pCell->nVars]; - p->pSameVar[pCell->nVars] = pCell; - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CellSuppMin( Cut_Cell_t * pCell ) -{ - static unsigned uTemp[1<<(CUT_CELL_MVAR-5)]; - unsigned * pIn, * pOut, * pTemp; - int i, k, Counter, Temp; - - // go backward through the support variables and remove redundant - for ( k = pCell->nVars - 1; k >= 0; k-- ) - if ( !Extra_TruthVarInSupport(pCell->uTruth, pCell->nVars, k) ) - { - // shift all the variables above this one - Counter = 0; - pIn = pCell->uTruth; pOut = uTemp; - for ( i = k; i < (int)pCell->nVars - 1; i++ ) - { - Extra_TruthSwapAdjacentVars( pOut, pIn, pCell->nVars, i ); - pTemp = pIn; pIn = pOut; pOut = pTemp; - // swap the support vars - Temp = pCell->CanonPerm[i]; - pCell->CanonPerm[i] = pCell->CanonPerm[i+1]; - pCell->CanonPerm[i+1] = Temp; - Counter++; - } - // return the function back into its place - if ( Counter & 1 ) - Extra_TruthCopy( pOut, pIn, pCell->nVars ); - // remove one variable - pCell->nVars--; -// Extra_PrintBinary( stdout, pCell->uTruth, (1<<pCell->nVars) ); printf( "\n" ); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CellCrossBar( Cut_Cell_t * pCell ) -{ - static unsigned uTemp0[1<<(CUT_CELL_MVAR-5)]; - static unsigned uTemp1[1<<(CUT_CELL_MVAR-5)]; - Extra_TruthCopy( uTemp0, pCell->uTruth, pCell->nVars ); - Extra_TruthCopy( uTemp1, pCell->uTruth, pCell->nVars ); - if ( pCell->CanonPhase == 0 ) - { - Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 ); - Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 ); - Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 ); - Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 ); - } - else if ( pCell->CanonPhase == 1 ) - { - Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar0 ); - Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar1 ); - Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar0 ); - Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar1 ); - } - else if ( pCell->CanonPhase == 2 ) - { - Extra_TruthCofactor0( uTemp0, pCell->nVars, pCell->CrossBar0 ); - Extra_TruthCofactor1( uTemp0, pCell->nVars, pCell->CrossBar1 ); - Extra_TruthCofactor1( uTemp1, pCell->nVars, pCell->CrossBar0 ); - Extra_TruthCofactor0( uTemp1, pCell->nVars, pCell->CrossBar1 ); - } - else assert( 0 ); - Extra_TruthMux( pCell->uTruth, uTemp0, uTemp1, pCell->nVars, pCell->CrossBar0 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CellTruthElem( unsigned * InA, unsigned * InB, unsigned * InC, unsigned * pOut, int nVars, int Type ) -{ - int nWords = Extra_TruthWordNum( nVars ); - int i; - - assert( Type < 22 ); - switch ( Type ) - { - // " 0\n", // 00 const 0 - case 0: - for ( i = 0; i < nWords; i++ ) - pOut[i] = 0; - return; - // " 1\n", // 01 const 1 - case 1: - for ( i = 0; i < nWords; i++ ) - pOut[i] = 0xFFFFFFFF; - return; - // "1 1\n", // 02 a - case 2: - for ( i = 0; i < nWords; i++ ) - pOut[i] = InA[i]; - return; - // "11 1\n", // 03 ab - case 3: - for ( i = 0; i < nWords; i++ ) - pOut[i] = InA[i] & InB[i]; - return; - // "11 0\n", // 04 (ab)' - case 4: - for ( i = 0; i < nWords; i++ ) - pOut[i] = ~(InA[i] & InB[i]); - return; - // "10 1\n01 1\n", // 05 a<+>b - case 5: - for ( i = 0; i < nWords; i++ ) - pOut[i] = InA[i] ^ InB[i]; - return; - // "111 1\n", // 06 + abc - case 6: - for ( i = 0; i < nWords; i++ ) - pOut[i] = InA[i] & InB[i] & InC[i]; - return; - // "111 0\n", // 07 (abc)' - case 7: - for ( i = 0; i < nWords; i++ ) - pOut[i] = ~(InA[i] & InB[i] & InC[i]); - return; - // "11- 1\n1-1 1\n", // 08 + a(b+c) - case 8: - for ( i = 0; i < nWords; i++ ) - pOut[i] = InA[i] & (InB[i] | InC[i]); - return; - // "11- 0\n1-1 0\n", // 09 (a(b+c))' - case 9: - for ( i = 0; i < nWords; i++ ) - pOut[i] = ~(InA[i] & (InB[i] | InC[i])); - return; - // "111 1\n100 1\n010 1\n001 1\n", // 10 + a<+>b<+>c - case 10: - for ( i = 0; i < nWords; i++ ) - pOut[i] = InA[i] ^ InB[i] ^ InC[i]; - return; - // "10- 0\n1-0 0\n011 0\n", // 11 + a<+>bc - case 11: - for ( i = 0; i < nWords; i++ ) - pOut[i] = InA[i] ^ (InB[i] & InC[i]); - return; - // "101 1\n110 1\n", // 12 + a(b<+>c) - case 12: - for ( i = 0; i < nWords; i++ ) - pOut[i] = InA[i] & (InB[i] ^ InC[i]); - return; - // "101 0\n110 0\n", // 13 (a(b<+>c))' - case 13: - for ( i = 0; i < nWords; i++ ) - pOut[i] = ~(InA[i] & (InB[i] ^ InC[i])); - return; - // "11- 1\n1-1 1\n-11 1\n", // 14 + ab+bc+ac - case 14: - for ( i = 0; i < nWords; i++ ) - pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (InA[i] & InC[i]); - return; - // "111 1\n000 1\n", // 15 + abc+a'b'c' - case 15: - for ( i = 0; i < nWords; i++ ) - pOut[i] = (InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i]); - return; - // "111 0\n000 0\n", // 16 (abc+a'b'c')' - case 16: - for ( i = 0; i < nWords; i++ ) - pOut[i] = ~((InA[i] & InB[i] & InC[i]) | (~InA[i] & ~InB[i] & ~InC[i])); - return; - // "11- 1\n-11 1\n0-1 1\n", // 17 + ab+bc+a'c - case 17: - for ( i = 0; i < nWords; i++ ) - pOut[i] = (InA[i] & InB[i]) | (InB[i] & InC[i]) | (~InA[i] & InC[i]); - return; - // "011 1\n101 1\n110 1\n", // 18 + a'bc+ab'c+abc' - case 18: - for ( i = 0; i < nWords; i++ ) - pOut[i] = (~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i]); - return; - // "011 0\n101 0\n110 0\n", // 19 (a'bc+ab'c+abc')' - case 19: - for ( i = 0; i < nWords; i++ ) - pOut[i] = ~((~InA[i] & InB[i] & InC[i]) | (InA[i] & ~InB[i] & InC[i]) | (InA[i] & InB[i] & ~InC[i])); - return; - // "100 1\n-11 1\n", // 20 + ab'c'+bc - case 20: - for ( i = 0; i < nWords; i++ ) - pOut[i] = (InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i]); - return; - // "100 0\n-11 0\n" // 21 (ab'c'+bc)' - case 21: - for ( i = 0; i < nWords; i++ ) - pOut[i] = ~((InA[i] & ~InB[i] & ~InC[i]) | (InB[i] & InC[i])); - return; - } -} - - -/**Function************************************************************* - - Synopsis [Start the precomputation manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_CMan_t * Cut_CManStart() -{ - Cut_CMan_t * p; - int i, k; - // start the manager - assert( sizeof(unsigned) == 4 ); - p = ALLOC( Cut_CMan_t, 1 ); - memset( p, 0, sizeof(Cut_CMan_t) ); - // start the table and the memory manager - p->tTable = st_init_table(st_ptrcmp,st_ptrhash); - p->pMem = Extra_MmFixedStart( sizeof(Cut_Cell_t) ); - // set elementary truth tables - for ( k = 0; k < CUT_CELL_MVAR; k++ ) - for ( i = 0; i < (1<<CUT_CELL_MVAR); i++ ) - if ( i & (1 << k) ) - p->uInputs[k][i>>5] |= (1 << (i&31)); - s_pCMan = p; - return p; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CManStop( Cut_CMan_t * p ) -{ - st_free_table( p->tTable ); - Extra_MmFixedStop( p->pMem ); - free( p ); -} -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_CellIsRunning() -{ - return s_pCMan != NULL; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_CellDumpToFile() -{ - FILE * pFile; - Cut_CMan_t * p = s_pCMan; - Cut_Cell_t * pTemp; - char * pFileName = "celllib22.txt"; - int NumUsed[10][5] = {{0}}; - int BoxUsed[22][5] = {{0}}; - int i, k, Counter; - int clk = clock(); - - if ( p == NULL ) - { - printf( "Cut_CellDumpToFile: Cell manager is not defined.\n" ); - return; - } - - // count the number of cells used - for ( k = CUT_CELL_MVAR; k >= 0; k-- ) - { - for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar ) - { - if ( pTemp->nUsed == 0 ) - NumUsed[k][0]++; - else if ( pTemp->nUsed < 10 ) - NumUsed[k][1]++; - else if ( pTemp->nUsed < 100 ) - NumUsed[k][2]++; - else if ( pTemp->nUsed < 1000 ) - NumUsed[k][3]++; - else - NumUsed[k][4]++; - - for ( i = 0; i < 4; i++ ) - if ( pTemp->nUsed == 0 ) - BoxUsed[ pTemp->Box[i] ][0]++; - else if ( pTemp->nUsed < 10 ) - BoxUsed[ pTemp->Box[i] ][1]++; - else if ( pTemp->nUsed < 100 ) - BoxUsed[ pTemp->Box[i] ][2]++; - else if ( pTemp->nUsed < 1000 ) - BoxUsed[ pTemp->Box[i] ][3]++; - else - BoxUsed[ pTemp->Box[i] ][4]++; - } - } - - printf( "Functions found = %10d. Functions not found = %10d.\n", p->nCellFound, p->nCellNotFound ); - for ( k = 0; k <= CUT_CELL_MVAR; k++ ) - { - printf( "%3d : ", k ); - for ( i = 0; i < 5; i++ ) - printf( "%8d ", NumUsed[k][i] ); - printf( "\n" ); - } - printf( "Box usage:\n" ); - for ( k = 0; k < 22; k++ ) - { - printf( "%3d : ", k ); - for ( i = 0; i < 5; i++ ) - printf( "%8d ", BoxUsed[k][i] ); - printf( " %s", s_NP3Names[k] ); - printf( "\n" ); - } - - pFile = fopen( pFileName, "w" ); - if ( pFile == NULL ) - { - printf( "Cut_CellDumpToFile: Cannout open output file.\n" ); - return; - } - - Counter = 0; - for ( k = 0; k <= CUT_CELL_MVAR; k++ ) - { - for ( pTemp = p->pSameVar[k]; pTemp; pTemp = pTemp->pNextVar ) - if ( pTemp->nUsed > 0 ) - { - Extra_PrintHexadecimal( pFile, pTemp->uTruth, (k <= 5? 5 : k) ); - fprintf( pFile, "\n" ); - Counter++; - } - fprintf( pFile, "\n" ); - } - fclose( pFile ); - - printf( "Library composed of %d functions is written into file \"%s\". ", Counter, pFileName ); - - PRT( "Time", clock() - clk ); -} - - -/**Function************************************************************* - - Synopsis [Looks up if the given function exists in the hash table.] - - Description [If the function exists, returns 1, meaning that it can be - implemented using two levels of 3-input LUTs. If the function does not - exist, return 0.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_CellTruthLookup( unsigned * pTruth, int nVars ) -{ - Cut_CMan_t * p = s_pCMan; - Cut_Cell_t * pTemp; - Cut_Cell_t Cell, * pCell = &Cell; - unsigned Hash; - int i; - - // cell manager is not defined - if ( p == NULL ) - { - printf( "Cut_CellTruthLookup: Cell manager is not defined.\n" ); - return 0; - } - - // canonicize - memset( pCell, 0, sizeof(Cut_Cell_t) ); - pCell->nVars = nVars; - Extra_TruthCopy( pCell->uTruth, pTruth, nVars ); - Cut_CellSuppMin( pCell ); - // set the elementary permutation - for ( i = 0; i < (int)pCell->nVars; i++ ) - pCell->CanonPerm[i] = i; - // canonicize - pCell->CanonPhase = Extra_TruthSemiCanonicize( pCell->uTruth, p->puAux, pCell->nVars, pCell->CanonPerm, pCell->Store ); - - - // check if the cell exists - Hash = Extra_TruthHash( pCell->uTruth, Extra_TruthWordNum(pCell->nVars) ); - if ( st_lookup( p->tTable, (char *)Hash, (char **)&pTemp ) ) - { - for ( ; pTemp; pTemp = pTemp->pNext ) - { - if ( pTemp->nVars != pCell->nVars ) - continue; - if ( Extra_TruthIsEqual(pTemp->uTruth, pCell->uTruth, pCell->nVars) ) - { - pTemp->nUsed++; - p->nCellFound++; - return 1; - } - } - } - p->nCellNotFound++; - return 0; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/cut/cutSeq.c b/src/opt/cut/cutSeq.c index d36f94f7..869bd7b3 100644 --- a/src/opt/cut/cutSeq.c +++ b/src/opt/cut/cutSeq.c @@ -25,12 +25,12 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Shifts all cut leaves of the node by the given number of latches.] + Synopsis [] Description [] @@ -39,186 +39,6 @@ SeeAlso [] ***********************************************************************/ -static inline void Cut_NodeShiftCutLeaves( Cut_Cut_t * pList, int nLat ) -{ - Cut_Cut_t * pTemp; - int i; - // shift the cuts by as many latches - Cut_ListForEachCut( pList, pTemp ) - { - pTemp->uSign = 0; - for ( i = 0; i < (int)pTemp->nLeaves; i++ ) - { - pTemp->pLeaves[i] += nLat; - pTemp->uSign |= Cut_NodeSign( pTemp->pLeaves[i] ); - } - } -} - -/**Function************************************************************* - - Synopsis [Computes sequential cuts for the node from its fanins.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_NodeComputeCutsSeq( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int nLat0, int nLat1, int fTriv, int CutSetNum ) -{ - Cut_List_t Super, * pSuper = &Super; - Cut_Cut_t * pListNew; - int clk; - - // get the number of cuts at the node - p->nNodeCuts = Cut_CutCountList( Cut_NodeReadCutsOld(p, Node) ); - if ( p->nNodeCuts >= p->pParams->nKeepMax ) - return; - - // count only the first visit - if ( p->nNodeCuts == 0 ) - p->nNodes++; - - // store the fanin lists - p->pStore0[0] = Cut_NodeReadCutsOld( p, Node0 ); - p->pStore0[1] = Cut_NodeReadCutsNew( p, Node0 ); - p->pStore1[0] = Cut_NodeReadCutsOld( p, Node1 ); - p->pStore1[1] = Cut_NodeReadCutsNew( p, Node1 ); - - // duplicate the cut lists if fanin nodes are non-standard - if ( Node == Node0 || Node == Node1 || Node0 == Node1 ) - { - p->pStore0[0] = Cut_CutDupList( p, p->pStore0[0] ); - p->pStore0[1] = Cut_CutDupList( p, p->pStore0[1] ); - p->pStore1[0] = Cut_CutDupList( p, p->pStore1[0] ); - p->pStore1[1] = Cut_CutDupList( p, p->pStore1[1] ); - } - - // shift the cuts by as many latches and recompute signatures - if ( nLat0 ) Cut_NodeShiftCutLeaves( p->pStore0[0], nLat0 ); - if ( nLat0 ) Cut_NodeShiftCutLeaves( p->pStore0[1], nLat0 ); - if ( nLat1 ) Cut_NodeShiftCutLeaves( p->pStore1[0], nLat1 ); - if ( nLat1 ) Cut_NodeShiftCutLeaves( p->pStore1[1], nLat1 ); - - // store the original lists for comparison - p->pCompareOld = Cut_NodeReadCutsOld( p, Node ); - p->pCompareNew = Cut_NodeReadCutsNew( p, Node ); - - // merge the old and the new -clk = clock(); - Cut_ListStart( pSuper ); - Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[0], p->pStore1[1], 0, 0 ); - Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[0], 0, 0 ); - Cut_NodeDoComputeCuts( p, pSuper, Node, fCompl0, fCompl1, p->pStore0[1], p->pStore1[1], fTriv, 0 ); - pListNew = Cut_ListFinish( pSuper ); -p->timeMerge += clock() - clk; - - // shift the cuts by as many latches and recompute signatures - if ( Node == Node0 || Node == Node1 || Node0 == Node1 ) - { - Cut_CutRecycleList( p, p->pStore0[0] ); - Cut_CutRecycleList( p, p->pStore0[1] ); - Cut_CutRecycleList( p, p->pStore1[0] ); - Cut_CutRecycleList( p, p->pStore1[1] ); - } - else - { - if ( nLat0 ) Cut_NodeShiftCutLeaves( p->pStore0[0], -nLat0 ); - if ( nLat0 ) Cut_NodeShiftCutLeaves( p->pStore0[1], -nLat0 ); - if ( nLat1 ) Cut_NodeShiftCutLeaves( p->pStore1[0], -nLat1 ); - if ( nLat1 ) Cut_NodeShiftCutLeaves( p->pStore1[1], -nLat1 ); - } - - // set the lists at the node - if ( CutSetNum >= 0 ) - { - assert( Cut_NodeReadCutsTemp(p, CutSetNum) == NULL ); - Cut_NodeWriteCutsTemp( p, CutSetNum, pListNew ); - } - else - { - assert( Cut_NodeReadCutsNew(p, Node) == NULL ); - Cut_NodeWriteCutsNew( p, Node, pListNew ); - } - - // mark the node if we exceeded the number of cuts - if ( p->nNodeCuts >= p->pParams->nKeepMax ) - p->nCutsLimit++; -} - -/**Function************************************************************* - - Synopsis [Merges the new cuts with the old cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_NodeNewMergeWithOld( Cut_Man_t * p, int Node ) -{ - Cut_Cut_t * pListOld, * pListNew, * pList; - // get the new cuts - pListNew = Cut_NodeReadCutsNew( p, Node ); - if ( pListNew == NULL ) - return; - Cut_NodeWriteCutsNew( p, Node, NULL ); - // get the old cuts - pListOld = Cut_NodeReadCutsOld( p, Node ); - if ( pListOld == NULL ) - { - Cut_NodeWriteCutsOld( p, Node, pListNew ); - return; - } - // merge the lists - pList = Cut_CutMergeLists( pListOld, pListNew ); - Cut_NodeWriteCutsOld( p, Node, pList ); -} - - -/**Function************************************************************* - - Synopsis [Transfers the temporary cuts to be the new cuts.] - - Description [Returns 1 if something was transferred.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_NodeTempTransferToNew( Cut_Man_t * p, int Node, int CutSetNum ) -{ - Cut_Cut_t * pList; - pList = Cut_NodeReadCutsTemp( p, CutSetNum ); - Cut_NodeWriteCutsTemp( p, CutSetNum, NULL ); - Cut_NodeWriteCutsNew( p, Node, pList ); - return pList != NULL; -} - -/**Function************************************************************* - - Synopsis [Transfers the old cuts to be the new cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_NodeOldTransferToNew( Cut_Man_t * p, int Node ) -{ - Cut_Cut_t * pList; - pList = Cut_NodeReadCutsOld( p, Node ); - Cut_NodeWriteCutsOld( p, Node, NULL ); - Cut_NodeWriteCutsNew( p, Node, pList ); -// Cut_CutListVerify( pList ); -} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/opt/cut/cutTable.c b/src/opt/cut/cutTable.c new file mode 100644 index 00000000..5dfaca7b --- /dev/null +++ b/src/opt/cut/cutTable.c @@ -0,0 +1,253 @@ +/**CFile**************************************************************** + + FileName [cutTable.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [K-feasible cut computation package.] + + Synopsis [Hashing cuts to prevent duplication.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cutTable.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "cutInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +struct Cut_HashTableStruct_t_ +{ + int nBins; + Cut_Cut_t ** pBins; + int nEntries; + int * pPlaces; + int nPlaces; + int timeLookup; +}; + +// iterator through all the cuts of the list +#define Cut_TableListForEachCut( pList, pCut ) \ + for ( pCut = pList; \ + pCut; \ + pCut = pCut->pData ) +#define Cut_TableListForEachCutSafe( pList, pCut, pCut2 ) \ + for ( pCut = pList, \ + pCut2 = pCut? pCut->pData: NULL; \ + pCut; \ + pCut = pCut2, \ + pCut2 = pCut? pCut->pData: NULL ) + +// primes used to compute the hash key +static int s_HashPrimes[10] = { 109, 499, 557, 619, 631, 709, 797, 881, 907, 991 }; + +// hashing function +static inline unsigned Cut_HashKey( Cut_Cut_t * pCut ) +{ + unsigned i, uRes = pCut->nLeaves * s_HashPrimes[9]; + for ( i = 0; i < pCut->nLeaves + pCut->fSeq; i++ ) + uRes += s_HashPrimes[i] * pCut->pLeaves[i]; + return uRes; +} + +// hashing function +static inline int Cut_CompareTwo( Cut_Cut_t * pCut1, Cut_Cut_t * pCut2 ) +{ + unsigned i; + if ( pCut1->nLeaves != pCut2->nLeaves ) + return 1; + for ( i = 0; i < pCut1->nLeaves; i++ ) + if ( pCut1->pLeaves[i] != pCut2->pLeaves[i] ) + return 1; + return 0; +} + +static void Cut_TableResize( Cut_HashTable_t * pTable ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Starts the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cut_HashTable_t * Cut_TableStart( int Size ) +{ + Cut_HashTable_t * pTable; + pTable = ALLOC( Cut_HashTable_t, 1 ); + memset( pTable, 0, sizeof(Cut_HashTable_t) ); + // allocate the table + pTable->nBins = Cudd_PrimeCopy( Size ); + pTable->pBins = ALLOC( Cut_Cut_t *, pTable->nBins ); + memset( pTable->pBins, 0, sizeof(Cut_Cut_t *) * pTable->nBins ); + pTable->pPlaces = ALLOC( int, pTable->nBins ); + return pTable; +} + +/**Function************************************************************* + + Synopsis [Stops the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_TableStop( Cut_HashTable_t * pTable ) +{ + FREE( pTable->pPlaces ); + free( pTable->pBins ); + free( pTable ); +} + +/**Function************************************************************* + + Synopsis [Check the existence of a cut in the lookup table] + + Description [Returns 1 if the entry is found.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cut_TableLookup( Cut_HashTable_t * pTable, Cut_Cut_t * pCut, int fStore ) +{ + Cut_Cut_t * pEnt; + unsigned Key; + int clk = clock(); + + Key = Cut_HashKey(pCut) % pTable->nBins; + Cut_TableListForEachCut( pTable->pBins[Key], pEnt ) + { + if ( !Cut_CompareTwo( pEnt, pCut ) ) + { +pTable->timeLookup += clock() - clk; + return 1; + } + } + if ( pTable->nEntries > 2 * pTable->nBins ) + { + Cut_TableResize( pTable ); + Key = Cut_HashKey(pCut) % pTable->nBins; + } + // remember the place + if ( fStore && pTable->pBins[Key] == NULL ) + pTable->pPlaces[ pTable->nPlaces++ ] = Key; + // add the cut to the table + pCut->pData = pTable->pBins[Key]; + pTable->pBins[Key] = pCut; + pTable->nEntries++; +pTable->timeLookup += clock() - clk; + return 0; +} + + +/**Function************************************************************* + + Synopsis [Stops the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_TableClear( Cut_HashTable_t * pTable ) +{ + int i; + assert( pTable->nPlaces <= pTable->nBins ); + for ( i = 0; i < pTable->nPlaces; i++ ) + { + assert( pTable->pBins[ pTable->pPlaces[i] ] ); + pTable->pBins[ pTable->pPlaces[i] ] = NULL; + } + pTable->nPlaces = 0; + pTable->nEntries = 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_TableResize( Cut_HashTable_t * pTable ) +{ + Cut_Cut_t ** pBinsNew; + Cut_Cut_t * pEnt, * pEnt2; + int nBinsNew, Counter, i, clk; + unsigned Key; + +clk = clock(); + // get the new table size + nBinsNew = Cudd_PrimeCopy( 3 * pTable->nBins ); + // allocate a new array + pBinsNew = ALLOC( Cut_Cut_t *, nBinsNew ); + memset( pBinsNew, 0, sizeof(Cut_Cut_t *) * nBinsNew ); + // rehash the entries from the old table + Counter = 0; + for ( i = 0; i < pTable->nBins; i++ ) + Cut_TableListForEachCutSafe( pTable->pBins[i], pEnt, pEnt2 ) + { + Key = Cut_HashKey(pEnt) % nBinsNew; + pEnt->pData = pBinsNew[Key]; + pBinsNew[Key] = pEnt; + Counter++; + } + assert( Counter == pTable->nEntries ); +// printf( "Increasing the structural table size from %6d to %6d. ", pMan->nBins, nBinsNew ); +// PRT( "Time", clock() - clk ); + // replace the table and the parameters + free( pTable->pBins ); + pTable->pBins = pBinsNew; + pTable->nBins = nBinsNew; +} + +/**Function************************************************************* + + Synopsis [Stops the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cut_TableReadTime( Cut_HashTable_t * pTable ) +{ + if ( pTable == NULL ) + return 0; + return pTable->timeLookup; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/opt/cut/cutTruth.c b/src/opt/cut/cutTruth.c index c3514ad7..efacd456 100644 --- a/src/opt/cut/cutTruth.c +++ b/src/opt/cut/cutTruth.c @@ -20,27 +20,21 @@ #include "cutInt.h" -/* - Truth tables computed in this package are represented as bit-strings - stored in the cut data structure. Cuts of any number of inputs have - the truth table with 2^k bits, where k is the max number of cut inputs. -*/ - //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern int nTotal = 0; -extern int nGood = 0; -extern int nEqual = 0; +static void Cut_TruthCompute4( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ); +static void Cut_TruthCompute5( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ); +static void Cut_TruthCompute6( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Computes the stretching phase of the cut w.r.t. the merged cut.] + Synopsis [Performs truth table computation.] Description [] @@ -70,42 +64,23 @@ static inline unsigned Cut_TruthPhase( Cut_Cut_t * pCut, Cut_Cut_t * pCut1 ) Synopsis [Performs truth table computation.] - Description [This procedure cannot be used while recording oracle - because it will overwrite Num0 and Num1.] + Description [] SideEffects [] SeeAlso [] ***********************************************************************/ -void Cut_TruthNCanonicize( Cut_Cut_t * pCut ) +void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) { - unsigned uTruth; - unsigned * uCanon2; - char * pPhases2; - assert( pCut->nVarsMax < 6 ); - - // get the direct truth table - uTruth = *Cut_CutReadTruth(pCut); - - // compute the direct truth table - Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 ); -// uCanon[0] = uCanon2[0]; -// uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0]; -// uPhases[0] = pPhases2[0]; - pCut->uCanon0 = uCanon2[0]; - pCut->Num0 = pPhases2[0]; - - // get the complemented truth table - uTruth = ~*Cut_CutReadTruth(pCut); - - // compute the direct truth table - Extra_TruthCanonFastN( pCut->nVarsMax, pCut->nLeaves, &uTruth, &uCanon2, &pPhases2 ); -// uCanon[0] = uCanon2[0]; -// uCanon[1] = (p->nVarsMax == 6)? uCanon2[1] : uCanon2[0]; -// uPhases[0] = pPhases2[0]; - pCut->uCanon1 = uCanon2[0]; - pCut->Num1 = pPhases2[0]; +int clk = clock(); + if ( pCut->nVarsMax == 4 ) + Cut_TruthCompute4( p, pCut, pCut0, pCut1 ); + else if ( pCut->nVarsMax == 5 ) + Cut_TruthCompute5( p, pCut, pCut0, pCut1 ); + else // if ( pCut->nVarsMax == 6 ) + Cut_TruthCompute6( p, pCut, pCut0, pCut1 ); +p->timeTruth += clock() - clk; } /**Function************************************************************* @@ -119,44 +94,28 @@ void Cut_TruthNCanonicize( Cut_Cut_t * pCut ) SeeAlso [] ***********************************************************************/ -void Cut_TruthComputeOld( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 ) +void Cut_TruthCompute4( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) { - static unsigned uTruth0[8], uTruth1[8]; - int nTruthWords = Cut_TruthWords( pCut->nVarsMax ); - unsigned * pTruthRes; - int i, uPhase; + unsigned * puTruthCut0, * puTruthCut1; + unsigned uTruth0, uTruth1, uPhase; - // permute the first table - uPhase = Cut_TruthPhase( pCut, pCut0 ); - Extra_TruthExpand( pCut->nVarsMax, nTruthWords, Cut_CutReadTruth(pCut0), uPhase, uTruth0 ); - if ( fCompl0 ) - { - for ( i = 0; i < nTruthWords; i++ ) - uTruth0[i] = ~uTruth0[i]; - } + puTruthCut0 = Cut_CutReadTruth(pCut0); + puTruthCut1 = Cut_CutReadTruth(pCut1); - // permute the second table - uPhase = Cut_TruthPhase( pCut, pCut1 ); - Extra_TruthExpand( pCut->nVarsMax, nTruthWords, Cut_CutReadTruth(pCut1), uPhase, uTruth1 ); - if ( fCompl1 ) - { - for ( i = 0; i < nTruthWords; i++ ) - uTruth1[i] = ~uTruth1[i]; - } + uPhase = Cut_TruthPhase( pCut, pCut0 ); + uTruth0 = Extra_TruthPerm4One( *puTruthCut0, uPhase ); + uTruth0 = p->fCompl0? ~uTruth0: uTruth0; - // write the resulting table - pTruthRes = Cut_CutReadTruth(pCut); + uPhase = Cut_TruthPhase( pCut, pCut1 ); + uTruth1 = Extra_TruthPerm4One( *puTruthCut1, uPhase ); + uTruth1 = p->fCompl1? ~uTruth1: uTruth1; + uTruth1 = uTruth0 & uTruth1; if ( pCut->fCompl ) - { - for ( i = 0; i < nTruthWords; i++ ) - pTruthRes[i] = ~(uTruth0[i] & uTruth1[i]); - } - else - { - for ( i = 0; i < nTruthWords; i++ ) - pTruthRes[i] = uTruth0[i] & uTruth1[i]; - } + uTruth1 = ~uTruth1; + if ( pCut->nVarsMax == 4 ) + uTruth1 &= 0xFFFF; + Cut_CutWriteTruth( pCut, &uTruth1 ); } /**Function************************************************************* @@ -170,55 +129,192 @@ void Cut_TruthComputeOld( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 SeeAlso [] ***********************************************************************/ -void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 ) +void Cut_TruthCompute5( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) { - // permute the first table - if ( fCompl0 ) - Extra_TruthNot( p->puTemp[0], Cut_CutReadTruth(pCut0), pCut->nVarsMax ); - else - Extra_TruthCopy( p->puTemp[0], Cut_CutReadTruth(pCut0), pCut->nVarsMax ); - Extra_TruthStretch( p->puTemp[2], p->puTemp[0], pCut0->nLeaves, pCut->nVarsMax, Cut_TruthPhase(pCut, pCut0) ); - // permute the second table - if ( fCompl1 ) - Extra_TruthNot( p->puTemp[1], Cut_CutReadTruth(pCut1), pCut->nVarsMax ); - else - Extra_TruthCopy( p->puTemp[1], Cut_CutReadTruth(pCut1), pCut->nVarsMax ); - Extra_TruthStretch( p->puTemp[3], p->puTemp[1], pCut1->nLeaves, pCut->nVarsMax, Cut_TruthPhase(pCut, pCut1) ); - // produce the resulting table + unsigned * puTruthCut0, * puTruthCut1; + unsigned uTruth0, uTruth1, uPhase; + + puTruthCut0 = Cut_CutReadTruth(pCut0); + puTruthCut1 = Cut_CutReadTruth(pCut1); + + uPhase = Cut_TruthPhase( pCut, pCut0 ); + uTruth0 = Extra_TruthPerm5One( *puTruthCut0, uPhase ); + uTruth0 = p->fCompl0? ~uTruth0: uTruth0; + + uPhase = Cut_TruthPhase( pCut, pCut1 ); + uTruth1 = Extra_TruthPerm5One( *puTruthCut1, uPhase ); + uTruth1 = p->fCompl1? ~uTruth1: uTruth1; + + uTruth1 = uTruth0 & uTruth1; if ( pCut->fCompl ) - Extra_TruthNand( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax ); - else - Extra_TruthAnd( Cut_CutReadTruth(pCut), p->puTemp[2], p->puTemp[3], pCut->nVarsMax ); + uTruth1 = ~uTruth1; + Cut_CutWriteTruth( pCut, &uTruth1 ); +} + +/**Function************************************************************* -// Ivy_TruthTestOne( *Cut_CutReadTruth(pCut) ); + Synopsis [Performs truth table computation.] - // quit if no fancy computation is needed - if ( !p->pParams->fFancy ) - return; + Description [] + + SideEffects [] - if ( pCut->nLeaves != 7 ) - return; + SeeAlso [] - // count the total number of truth tables computed - nTotal++; +***********************************************************************/ +void Cut_TruthCompute6( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) +{ + unsigned * puTruthCut0, * puTruthCut1; + unsigned uTruth0[2], uTruth1[2], uPhase; - // MAPPING INTO ALTERA 6-2 LOGIC BLOCKS - // call this procedure to find the minimum number of common variables in the cofactors - // if this number is less or equal than 3, the cut can be implemented using the 6-2 logic block - if ( Extra_TruthMinCofSuppOverlap( Cut_CutReadTruth(pCut), pCut->nVarsMax, NULL ) <= 4 ) - nGood++; + puTruthCut0 = Cut_CutReadTruth(pCut0); + puTruthCut1 = Cut_CutReadTruth(pCut1); + + uPhase = Cut_TruthPhase( pCut, pCut0 ); + Extra_TruthPerm6One( puTruthCut0, uPhase, uTruth0 ); + uTruth0[0] = p->fCompl0? ~uTruth0[0]: uTruth0[0]; + uTruth0[1] = p->fCompl0? ~uTruth0[1]: uTruth0[1]; - // MAPPING INTO ACTEL 2x2 CELLS - // call this procedure to see if a semi-canonical form can be found in the lookup table - // (if it exists, then a two-level 3-input LUT implementation of the cut exists) - // Before this procedure is called, cell manager should be defined by calling - // Cut_CellLoad (make sure file "cells22_daomap_iwls.txt" is available in the working dir) -// if ( Cut_CellIsRunning() && pCut->nVarsMax <= 9 ) -// nGood += Cut_CellTruthLookup( Cut_CutReadTruth(pCut), pCut->nVarsMax ); + uPhase = Cut_TruthPhase( pCut, pCut1 ); + Extra_TruthPerm6One( puTruthCut1, uPhase, uTruth1 ); + uTruth1[0] = p->fCompl1? ~uTruth1[0]: uTruth1[0]; + uTruth1[1] = p->fCompl1? ~uTruth1[1]: uTruth1[1]; + + uTruth1[0] = uTruth0[0] & uTruth1[0]; + uTruth1[1] = uTruth0[1] & uTruth1[1]; + if ( pCut->fCompl ) + { + uTruth1[0] = ~uTruth0[0]; + uTruth1[1] = ~uTruth0[1]; + } + Cut_CutWriteTruth( pCut, uTruth1 ); } + + + +/**Function************************************************************* + + Synopsis [Performs truth table computation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cut_TruthComputeOld( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) +{ + unsigned uTruth0, uTruth1, uPhase; + int clk = clock(); + + assert( pCut->nVarsMax < 6 ); + + // assign the truth table + if ( pCut0->nLeaves == pCut->nLeaves ) + uTruth0 = *Cut_CutReadTruth(pCut0); + else + { + assert( pCut0->nLeaves < pCut->nLeaves ); + uPhase = Cut_TruthPhase( pCut, pCut0 ); + if ( pCut->nVarsMax == 4 ) + { + assert( pCut0->nLeaves < 4 ); + assert( uPhase < 16 ); + uTruth0 = p->pPerms43[pCut0->uTruth & 0xFF][uPhase]; + } + else + { + assert( pCut->nVarsMax == 5 ); + assert( pCut0->nLeaves < 5 ); + assert( uPhase < 32 ); + if ( pCut0->nLeaves == 4 ) + { +// Count4++; +/* + if ( uPhase == 31-16 ) // 01111 + uTruth0 = pCut0->uTruth; + else if ( uPhase == 31-8 ) // 10111 + uTruth0 = p->pPerms54[pCut0->uTruth & 0xFFFF][0]; + else if ( uPhase == 31-4 ) // 11011 + uTruth0 = p->pPerms54[pCut0->uTruth & 0xFFFF][1]; + else if ( uPhase == 31-2 ) // 11101 + uTruth0 = p->pPerms54[pCut0->uTruth & 0xFFFF][2]; + else if ( uPhase == 31-1 ) // 11110 + uTruth0 = p->pPerms54[pCut0->uTruth & 0xFFFF][3]; + else + assert( 0 ); +*/ + uTruth0 = Extra_TruthPerm5One( *Cut_CutReadTruth(pCut0), uPhase ); + } + else + { +// Count5++; +// uTruth0 = p->pPerms53[pCut0->uTruth & 0xFF][uPhase]; + uTruth0 = Extra_TruthPerm5One( *Cut_CutReadTruth(pCut0), uPhase ); + } + } + } + uTruth0 = p->fCompl0? ~uTruth0: uTruth0; + + // assign the truth table + if ( pCut1->nLeaves == pCut->nLeaves ) + uTruth0 = *Cut_CutReadTruth(pCut1); + else + { + assert( pCut1->nLeaves < pCut->nLeaves ); + uPhase = Cut_TruthPhase( pCut, pCut1 ); + if ( pCut->nVarsMax == 4 ) + { + assert( pCut1->nLeaves < 4 ); + assert( uPhase < 16 ); + uTruth1 = p->pPerms43[pCut1->uTruth & 0xFF][uPhase]; + } + else + { + assert( pCut->nVarsMax == 5 ); + assert( pCut1->nLeaves < 5 ); + assert( uPhase < 32 ); + if ( pCut1->nLeaves == 4 ) + { +// Count4++; +/* + if ( uPhase == 31-16 ) // 01111 + uTruth1 = pCut1->uTruth; + else if ( uPhase == 31-8 ) // 10111 + uTruth1 = p->pPerms54[pCut1->uTruth & 0xFFFF][0]; + else if ( uPhase == 31-4 ) // 11011 + uTruth1 = p->pPerms54[pCut1->uTruth & 0xFFFF][1]; + else if ( uPhase == 31-2 ) // 11101 + uTruth1 = p->pPerms54[pCut1->uTruth & 0xFFFF][2]; + else if ( uPhase == 31-1 ) // 11110 + uTruth1 = p->pPerms54[pCut1->uTruth & 0xFFFF][3]; + else + assert( 0 ); +*/ + uTruth1 = Extra_TruthPerm5One( *Cut_CutReadTruth(pCut1), uPhase ); + } + else + { +// Count5++; +// uTruth1 = p->pPerms53[pCut1->uTruth & 0xFF][uPhase]; + uTruth1 = Extra_TruthPerm5One( *Cut_CutReadTruth(pCut1), uPhase ); + } + } + } + uTruth1 = p->fCompl1? ~uTruth1: uTruth1; + uTruth1 = uTruth0 & uTruth1; + if ( pCut->fCompl ) + uTruth1 = ~uTruth1; + if ( pCut->nVarsMax == 4 ) + uTruth1 &= 0xFFFF; + Cut_CutWriteTruth( pCut, &uTruth1 ); +p->timeTruth += clock() - clk; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/cut/module.make b/src/opt/cut/module.make index 132e730b..1175b3f2 100644 --- a/src/opt/cut/module.make +++ b/src/opt/cut/module.make @@ -1,9 +1,6 @@ -SRC += src/opt/cut/cutApi.c \ - src/opt/cut/cutCut.c \ - src/opt/cut/cutMan.c \ +SRC += src/opt/cut/cutMan.c \ src/opt/cut/cutMerge.c \ src/opt/cut/cutNode.c \ - src/opt/cut/cutOracle.c \ - src/opt/cut/cutPre22.c \ src/opt/cut/cutSeq.c \ + src/opt/cut/cutTable.c \ src/opt/cut/cutTruth.c diff --git a/src/opt/dec/dec.h b/src/opt/dec/dec.h index d0d9981d..6ecc9678 100644 --- a/src/opt/dec/dec.h +++ b/src/opt/dec/dec.h @@ -21,10 +21,6 @@ #ifndef __DEC_H__ #define __DEC_H__ -#ifdef __cplusplus -extern "C" { -#endif - //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -51,15 +47,11 @@ struct Dec_Node_t_ Dec_Edge_t eEdge1; // the right child of the node // other info void * pFunc; // the function of the node (BDD or AIG) - unsigned Level : 14; // the level of this node in the global AIG + unsigned Level : 16; // the level of this node in the global AIG // printing info unsigned fNodeOr : 1; // marks the original OR node unsigned fCompl0 : 1; // marks the original complemented edge unsigned fCompl1 : 1; // marks the original complemented edge - // latch info - unsigned nLat0 : 5; // the number of latches on the first edge - unsigned nLat1 : 5; // the number of latches on the second edge - unsigned nLat2 : 5; // the number of latches on the output edge }; typedef struct Dec_Graph_t_ Dec_Graph_t; @@ -103,6 +95,9 @@ struct Dec_Man_t_ //////////////////////////////////////////////////////////////////////// /*=== decAbc.c ========================================================*/ +extern Abc_Obj_t * Dec_GraphToNetwork( Abc_Aig_t * pMan, Dec_Graph_t * pGraph ); +extern int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ); +extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain ); /*=== decFactor.c ========================================================*/ extern Dec_Graph_t * Dec_Factor( char * pSop ); /*=== decMan.c ========================================================*/ @@ -111,10 +106,11 @@ extern void Dec_ManStop( Dec_Man_t * p ); /*=== decPrint.c ========================================================*/ extern void Dec_GraphPrint( FILE * pFile, Dec_Graph_t * pGraph, char * pNamesIn[], char * pNameOut ); /*=== decUtil.c ========================================================*/ +extern DdNode * Dec_GraphDeriveBdd( DdManager * dd, Dec_Graph_t * pGraph ); extern unsigned Dec_GraphDeriveTruth( Dec_Graph_t * pGraph ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -312,7 +308,7 @@ static inline void Dec_GraphFree( Dec_Graph_t * pGraph ) SeeAlso [] ***********************************************************************/ -static inline int Dec_GraphIsConst( Dec_Graph_t * pGraph ) +static inline bool Dec_GraphIsConst( Dec_Graph_t * pGraph ) { return pGraph->fConst; } @@ -328,7 +324,7 @@ static inline int Dec_GraphIsConst( Dec_Graph_t * pGraph ) SeeAlso [] ***********************************************************************/ -static inline int Dec_GraphIsConst0( Dec_Graph_t * pGraph ) +static inline bool Dec_GraphIsConst0( Dec_Graph_t * pGraph ) { return pGraph->fConst && pGraph->eRoot.fCompl; } @@ -344,7 +340,7 @@ static inline int Dec_GraphIsConst0( Dec_Graph_t * pGraph ) SeeAlso [] ***********************************************************************/ -static inline int Dec_GraphIsConst1( Dec_Graph_t * pGraph ) +static inline bool Dec_GraphIsConst1( Dec_Graph_t * pGraph ) { return pGraph->fConst && !pGraph->eRoot.fCompl; } @@ -360,7 +356,7 @@ static inline int Dec_GraphIsConst1( Dec_Graph_t * pGraph ) SeeAlso [] ***********************************************************************/ -static inline int Dec_GraphIsComplement( Dec_Graph_t * pGraph ) +static inline bool Dec_GraphIsComplement( Dec_Graph_t * pGraph ) { return pGraph->eRoot.fCompl; } @@ -473,7 +469,7 @@ static inline int Dec_GraphNodeInt( Dec_Graph_t * pGraph, Dec_Node_t * pNode ) SeeAlso [] ***********************************************************************/ -static inline int Dec_GraphIsVar( Dec_Graph_t * pGraph ) +static inline bool Dec_GraphIsVar( Dec_Graph_t * pGraph ) { return pGraph->eRoot.Node < (unsigned)pGraph->nLeaves; } @@ -489,7 +485,7 @@ static inline int Dec_GraphIsVar( Dec_Graph_t * pGraph ) SeeAlso [] ***********************************************************************/ -static inline int Dec_GraphNodeIsVar( Dec_Graph_t * pGraph, Dec_Node_t * pNode ) +static inline bool Dec_GraphNodeIsVar( Dec_Graph_t * pGraph, Dec_Node_t * pNode ) { return Dec_GraphNodeInt(pGraph,pNode) < pGraph->nLeaves; } @@ -631,84 +627,24 @@ static inline Dec_Edge_t Dec_GraphAddNodeOr( Dec_Graph_t * pGraph, Dec_Edge_t eE SeeAlso [] ***********************************************************************/ -static inline Dec_Edge_t Dec_GraphAddNodeXor( Dec_Graph_t * pGraph, Dec_Edge_t eEdge0, Dec_Edge_t eEdge1, int Type ) -{ - Dec_Edge_t eNode0, eNode1, eNode; - if ( Type == 0 ) - { - // derive the first AND - eEdge0.fCompl ^= 1; - eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 ); - eEdge0.fCompl ^= 1; - // derive the second AND - eEdge1.fCompl ^= 1; - eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 ); - // derive the final OR - eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); - } - else - { - // derive the first AND - eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 ); - // derive the second AND - eEdge0.fCompl ^= 1; - eEdge1.fCompl ^= 1; - eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 ); - // derive the final OR - eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); - eNode.fCompl ^= 1; - } - return eNode; -} - -/**Function************************************************************* - - Synopsis [Creates an XOR node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Edge_t Dec_GraphAddNodeMux( Dec_Graph_t * pGraph, Dec_Edge_t eEdgeC, Dec_Edge_t eEdgeT, Dec_Edge_t eEdgeE, int Type ) -{ - Dec_Edge_t eNode0, eNode1, eNode; - if ( Type == 0 ) - { - // derive the first AND - eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeT ); - // derive the second AND - eEdgeC.fCompl ^= 1; - eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeE ); - // derive the final OR - eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); - } - else - { - // complement the arguments - eEdgeT.fCompl ^= 1; - eEdgeE.fCompl ^= 1; - // derive the first AND - eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeT ); - // derive the second AND - eEdgeC.fCompl ^= 1; - eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeE ); - // derive the final OR - eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); - eNode.fCompl ^= 1; - } - return eNode; -} - -#ifdef __cplusplus +static inline Dec_Edge_t Dec_GraphAddNodeXor( Dec_Graph_t * pGraph, Dec_Edge_t eEdge0, Dec_Edge_t eEdge1 ) +{ + Dec_Edge_t eNode0, eNode1; + // derive the first AND + eEdge0.fCompl = !eEdge0.fCompl; + eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 ); + eEdge0.fCompl = !eEdge0.fCompl; + // derive the second AND + eEdge1.fCompl = !eEdge1.fCompl; + eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 ); + eEdge1.fCompl = !eEdge1.fCompl; + // derive the final OR + return Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); } -#endif - -#endif //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +#endif + diff --git a/src/opt/dec/decAbc.c b/src/opt/dec/decAbc.c index 6adb0f98..9931b136 100644 --- a/src/opt/dec/decAbc.c +++ b/src/opt/dec/decAbc.c @@ -18,14 +18,13 @@ #include "abc.h" #include "dec.h" -#include "ivy.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -40,14 +39,14 @@ SeeAlso [] ***********************************************************************/ -Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph ) +Abc_Obj_t * Dec_GraphToNetwork( Abc_Aig_t * pMan, Dec_Graph_t * pGraph ) { Abc_Obj_t * pAnd0, * pAnd1; Dec_Node_t * pNode; int i; // check for constant function if ( Dec_GraphIsConst(pGraph) ) - return Abc_ObjNotCond( Abc_AigConst1(pNtk), Dec_GraphIsComplement(pGraph) ); + return Abc_ObjNotCond( Abc_AigConst1(pMan), Dec_GraphIsComplement(pGraph) ); // check for a literal if ( Dec_GraphIsVar(pGraph) ) return Abc_ObjNotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); @@ -56,45 +55,7 @@ Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph ) { pAnd0 = Abc_ObjNotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); pAnd1 = Abc_ObjNotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); - pNode->pFunc = Abc_AigAnd( pNtk->pManFunc, pAnd0, pAnd1 ); - } - // complement the result if necessary - return Abc_ObjNotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); -} - -/**Function************************************************************* - - Synopsis [Transforms the decomposition graph into the AIG.] - - Description [AIG nodes for the fanins should be assigned to pNode->pFunc - of the leaves of the graph before calling this procedure.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Dec_GraphToNetworkNoStrash( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph ) -{ - Abc_Obj_t * pAnd, * pAnd0, * pAnd1; - Dec_Node_t * pNode; - int i; - // check for constant function - if ( Dec_GraphIsConst(pGraph) ) - return Abc_ObjNotCond( Abc_AigConst1(pNtk), Dec_GraphIsComplement(pGraph) ); - // check for a literal - if ( Dec_GraphIsVar(pGraph) ) - return Abc_ObjNotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); - // build the AIG nodes corresponding to the AND gates of the graph - Dec_GraphForEachNode( pGraph, pNode, i ) - { - pAnd0 = Abc_ObjNotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - pAnd1 = Abc_ObjNotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); -// pNode->pFunc = Abc_AigAnd( pNtk->pManFunc, pAnd0, pAnd1 ); - pAnd = Abc_NtkCreateNode( pNtk ); - Abc_ObjAddFanin( pAnd, pAnd0 ); - Abc_ObjAddFanin( pAnd, pAnd1 ); - pNode->pFunc = pAnd; + pNode->pFunc = Abc_AigAnd( pMan, pAnd0, pAnd1 ); } // complement the result if necessary return Abc_ObjNotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); @@ -158,14 +119,14 @@ int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa LevelNew = 1 + ABC_MAX( pNode0->Level, pNode1->Level ); if ( pAnd ) { - if ( Abc_ObjRegular(pAnd) == Abc_AigConst1(pRoot->pNtk) ) + if ( Abc_ObjRegular(pAnd) == Abc_AigConst1(pMan) ) LevelNew = 0; else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd0) ) LevelNew = (int)Abc_ObjRegular(pAnd0)->Level; else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd1) ) LevelNew = (int)Abc_ObjRegular(pAnd1)->Level; LevelOld = (int)Abc_ObjRegular(pAnd)->Level; -// assert( LevelNew == LevelOld ); + assert( LevelNew == LevelOld ); } if ( LevelNew > LevelMax ) return -1; @@ -187,118 +148,21 @@ int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa SeeAlso [] ***********************************************************************/ -void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, bool fUpdateLevel, int nGain ) +void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int nGain ) { - extern Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph ); Abc_Obj_t * pRootNew; Abc_Ntk_t * pNtk = pRoot->pNtk; int nNodesNew, nNodesOld; nNodesOld = Abc_NtkNodeNum(pNtk); // create the new structure of nodes - pRootNew = Dec_GraphToNetwork( pNtk, pGraph ); + pRootNew = Dec_GraphToNetwork( pNtk->pManFunc, pGraph ); // remove the old nodes - Abc_AigReplace( pNtk->pManFunc, pRoot, pRootNew, fUpdateLevel ); + Abc_AigReplace( pNtk->pManFunc, pRoot, pRootNew ); // compare the gains nNodesNew = Abc_NtkNodeNum(pNtk); assert( nGain <= nNodesOld - nNodesNew ); } - -/**Function************************************************************* - - Synopsis [Transforms the decomposition graph into the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Hop_Obj_t * Dec_GraphToNetworkAig( Hop_Man_t * pMan, Dec_Graph_t * pGraph ) -{ - Dec_Node_t * pNode; - Hop_Obj_t * pAnd0, * pAnd1; - int i; - // check for constant function - if ( Dec_GraphIsConst(pGraph) ) - return Hop_NotCond( Hop_ManConst1(pMan), Dec_GraphIsComplement(pGraph) ); - // check for a literal - if ( Dec_GraphIsVar(pGraph) ) - return Hop_NotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); - // build the AIG nodes corresponding to the AND gates of the graph - Dec_GraphForEachNode( pGraph, pNode, i ) - { - pAnd0 = Hop_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - pAnd1 = Hop_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); - pNode->pFunc = Hop_And( pMan, pAnd0, pAnd1 ); - } - // complement the result if necessary - return Hop_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Hop_Obj_t * Dec_GraphFactorSop( Hop_Man_t * pMan, char * pSop ) -{ - Hop_Obj_t * pFunc; - Dec_Graph_t * pFForm; - Dec_Node_t * pNode; - int i; - // perform factoring - pFForm = Dec_Factor( pSop ); - // collect the fanins - Dec_GraphForEachLeaf( pFForm, pNode, i ) - pNode->pFunc = Hop_IthVar( pMan, i ); - // perform strashing - pFunc = Dec_GraphToNetworkAig( pMan, pFForm ); - Dec_GraphFree( pFForm ); - return pFunc; -} - -/**Function************************************************************* - - Synopsis [Transforms the decomposition graph into the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Dec_GraphToNetworkIvy( Ivy_Man_t * pMan, Dec_Graph_t * pGraph ) -{ - Dec_Node_t * pNode; - Ivy_Obj_t * pAnd0, * pAnd1; - int i; - // check for constant function - if ( Dec_GraphIsConst(pGraph) ) - return Ivy_NotCond( Ivy_ManConst1(pMan), Dec_GraphIsComplement(pGraph) ); - // check for a literal - if ( Dec_GraphIsVar(pGraph) ) - return Ivy_NotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); - // build the AIG nodes corresponding to the AND gates of the graph - Dec_GraphForEachNode( pGraph, pNode, i ) - { - pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); - pNode->pFunc = Ivy_And( pMan, pAnd0, pAnd1 ); - } - // complement the result if necessary - return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); -} - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/dec/decFactor.c b/src/opt/dec/decFactor.c index 768dcd9b..f6654476 100644 --- a/src/opt/dec/decFactor.c +++ b/src/opt/dec/decFactor.c @@ -34,7 +34,7 @@ static int Dec_FactorVerify( char * pSop, Dec_Graph_t * pFForm ); static Mvc_Cover_t * Dec_ConvertSopToMvc( char * pSop ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -183,7 +183,7 @@ Dec_Edge_t Dec_Factor_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover ) ***********************************************************************/ Dec_Edge_t Dec_FactorLF_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cover_t * pSimple ) { - Dec_Man_t * pManDec = Abc_FrameReadManDec(); + Dec_Man_t * pManDec = Abc_FrameReadManDec(Abc_FrameGetGlobalFrame()); Vec_Int_t * vEdgeLits = pManDec->vLits; Mvc_Cover_t * pDiv, * pQuo, * pRem; Dec_Edge_t eNodeDiv, eNodeQuo, eNodeRem; @@ -228,7 +228,7 @@ Dec_Edge_t Dec_FactorLF_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cov ***********************************************************************/ Dec_Edge_t Dec_FactorTrivial( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover ) { - Dec_Man_t * pManDec = Abc_FrameReadManDec(); + Dec_Man_t * pManDec = Abc_FrameReadManDec(Abc_FrameGetGlobalFrame()); Vec_Int_t * vEdgeCubes = pManDec->vCubes; Vec_Int_t * vEdgeLits = pManDec->vLits; Mvc_Manager_t * pMem = pManDec->pMvcMem; @@ -258,15 +258,16 @@ Dec_Edge_t Dec_FactorTrivial( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover ) ***********************************************************************/ Dec_Edge_t Dec_FactorTrivialCube( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cube_t * pCube, Vec_Int_t * vEdgeLits ) { - Dec_Edge_t eNode; +// Dec_Edge_t eNode; int iBit, Value; // create the factored form for each literal Vec_IntClear( vEdgeLits ); Mvc_CubeForEachBit( pCover, pCube, iBit, Value ) if ( Value ) { - eNode = Dec_EdgeCreate( iBit/2, iBit%2 ); // CST - Vec_IntPush( vEdgeLits, Dec_EdgeToInt_(eNode) ); +// eNode = Dec_EdgeCreate( iBit/2, iBit%2 ); // CST +// Vec_IntPush( vEdgeLits, Dec_EdgeToInt_(eNode) ); + Vec_IntPush( vEdgeLits, iBit ); } // balance the factored forms return Dec_FactorTrivialTree_rec( pFForm, (Dec_Edge_t *)vEdgeLits->pArray, vEdgeLits->nSize, 0 ); @@ -322,7 +323,7 @@ Dec_Edge_t Dec_FactorTrivialTree_rec( Dec_Graph_t * pFForm, Dec_Edge_t * peNodes ***********************************************************************/ Mvc_Cover_t * Dec_ConvertSopToMvc( char * pSop ) { - Dec_Man_t * pManDec = Abc_FrameReadManDec(); + Dec_Man_t * pManDec = Abc_FrameReadManDec(Abc_FrameGetGlobalFrame()); Mvc_Manager_t * pMem = pManDec->pMvcMem; Mvc_Cover_t * pMvc; Mvc_Cube_t * pMvcCube; @@ -364,8 +365,7 @@ Mvc_Cover_t * Dec_ConvertSopToMvc( char * pSop ) ***********************************************************************/ int Dec_FactorVerify( char * pSop, Dec_Graph_t * pFForm ) { - extern DdNode * Dec_GraphDeriveBdd( DdManager * dd, Dec_Graph_t * pGraph ); - DdManager * dd = Abc_FrameReadManDd(); + DdManager * dd = Abc_FrameReadManDd( Abc_FrameGetGlobalFrame() ); DdNode * bFunc1, * bFunc2; int RetValue; bFunc1 = Abc_ConvertSopToBdd( dd, pSop ); Cudd_Ref( bFunc1 ); diff --git a/src/opt/dec/decMan.c b/src/opt/dec/decMan.c index 65857461..1d44d5cb 100644 --- a/src/opt/dec/decMan.c +++ b/src/opt/dec/decMan.c @@ -25,7 +25,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/dec/decPrint.c b/src/opt/dec/decPrint.c index 2d8f09b3..6fb20327 100644 --- a/src/opt/dec/decPrint.c +++ b/src/opt/dec/decPrint.c @@ -29,7 +29,7 @@ static void Dec_GraphPrintUpdatePos( FILE * pFile, int * pPos, int LitSizeMax static int Dec_GraphPrintOutputName( FILE * pFile, char * pNameOut, int fCompl ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -101,7 +101,7 @@ void Dec_GraphPrint( FILE * pFile, Dec_Graph_t * pGraph, char * pNamesIn[], char SeeAlso [] ***********************************************************************/ -void Dec_GraphPrint2_rec( FILE * pFile, Dec_Graph_t * pGraph, Dec_Node_t * pNode, int fCompl, char * pNamesIn[], int * pPos, int LitSizeMax ) +void Dec_GraphPrint_rec( FILE * pFile, Dec_Graph_t * pGraph, Dec_Node_t * pNode, int fCompl, char * pNamesIn[], int * pPos, int LitSizeMax ) { Dec_Node_t * pNode0, * pNode1; pNode0 = Dec_GraphNode(pGraph, pNode->eEdge0.Node); @@ -165,69 +165,6 @@ void Dec_GraphPrint2_rec( FILE * pFile, Dec_Graph_t * pGraph, Dec_Node_t * pNode SeeAlso [] ***********************************************************************/ -void Dec_GraphPrint_rec( FILE * pFile, Dec_Graph_t * pGraph, Dec_Node_t * pNode, int fCompl, char * pNamesIn[], int * pPos, int LitSizeMax ) -{ - Dec_Node_t * pNode0, * pNode1; - Dec_Node_t * pNode00, * pNode01, * pNode10, * pNode11; - pNode0 = Dec_GraphNode(pGraph, pNode->eEdge0.Node); - pNode1 = Dec_GraphNode(pGraph, pNode->eEdge1.Node); - if ( Dec_GraphNodeIsVar(pGraph, pNode) ) // FT_NODE_LEAF ) - { - (*pPos) += Dec_GraphPrintGetLeafName( pFile, Dec_GraphNodeInt(pGraph,pNode), fCompl, pNamesIn ); - return; - } - if ( !Dec_GraphNodeIsVar(pGraph, pNode0) && !Dec_GraphNodeIsVar(pGraph, pNode1) ) - { - pNode00 = Dec_GraphNode(pGraph, pNode0->eEdge0.Node); - pNode01 = Dec_GraphNode(pGraph, pNode0->eEdge1.Node); - pNode10 = Dec_GraphNode(pGraph, pNode1->eEdge0.Node); - pNode11 = Dec_GraphNode(pGraph, pNode1->eEdge1.Node); - if ( (pNode00 == pNode10 || pNode00 == pNode11) && (pNode01 == pNode10 || pNode01 == pNode11) ) - { - fprintf( pFile, "(" ); - (*pPos)++; - Dec_GraphPrint_rec( pFile, pGraph, pNode00, pNode00->fCompl0, pNamesIn, pPos, LitSizeMax ); - fprintf( pFile, " # " ); - (*pPos) += 3; - Dec_GraphPrint_rec( pFile, pGraph, pNode01, pNode01->fCompl1, pNamesIn, pPos, LitSizeMax ); - fprintf( pFile, ")" ); - (*pPos)++; - return; - } - } - if ( fCompl ) - { - fprintf( pFile, "(" ); - (*pPos)++; - Dec_GraphPrint_rec( pFile, pGraph, pNode0, !pNode->fCompl0, pNamesIn, pPos, LitSizeMax ); - fprintf( pFile, " + " ); - (*pPos) += 3; - Dec_GraphPrint_rec( pFile, pGraph, pNode1, !pNode->fCompl1, pNamesIn, pPos, LitSizeMax ); - fprintf( pFile, ")" ); - (*pPos)++; - } - else - { - fprintf( pFile, "(" ); - (*pPos)++; - Dec_GraphPrint_rec( pFile, pGraph, pNode0, pNode->fCompl0, pNamesIn, pPos, LitSizeMax ); - Dec_GraphPrint_rec( pFile, pGraph, pNode1, pNode->fCompl1, pNamesIn, pPos, LitSizeMax ); - fprintf( pFile, ")" ); - (*pPos)++; - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ int Dec_GraphPrintGetLeafName( FILE * pFile, int iLeaf, int fCompl, char * pNamesIn[] ) { static char Buffer[100]; diff --git a/src/opt/dec/decUtil.c b/src/opt/dec/decUtil.c index 463bc7e2..02c3346e 100644 --- a/src/opt/dec/decUtil.c +++ b/src/opt/dec/decUtil.c @@ -24,7 +24,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/fret/fretFlow.c b/src/opt/fret/fretFlow.c deleted file mode 100644 index a9cef327..00000000 --- a/src/opt/fret/fretFlow.c +++ /dev/null @@ -1,696 +0,0 @@ -/**CFile**************************************************************** - - FileName [fretFlow.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Flow-based retiming package.] - - Synopsis [Max-flow computation.] - - Author [Aaron Hurst] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 1, 2008.] - - Revision [$Id: fretFlow.c,v 1.00 2008/01/01 00:00:00 ahurst Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "vec.h" -#include "fretime.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void dfsfast_e_retreat( Abc_Obj_t *pObj ); -static void dfsfast_r_retreat( Abc_Obj_t *pObj ); - -#define FDIST(xn, xe, yn, ye) (FDATA(xn)->xe##_dist == (FDATA(yn)->ye##_dist + 1)) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Fast DFS.] - - Description [Uses sink-distance-histogram heuristic. May not find all - flow paths: this occurs in a small number of cases where - the flow predecessor points to a non-adjacent node and - the distance ordering is perturbed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -void dfsfast_preorder( Abc_Ntk_t *pNtk ) { - Abc_Obj_t *pObj, *pNext; - Vec_Ptr_t *vTimeIn, *qn = Vec_PtrAlloc(Abc_NtkObjNum(pNtk)); - Vec_Int_t *qe = Vec_IntAlloc(Abc_NtkObjNum(pNtk)); - int i, j, d = 0, end; - int qpos = 0; - - // create reverse timing edges for backward traversal -#if !defined(IGNORE_TIMING) - if (pManMR->maxDelay) { - Abc_NtkForEachObj( pNtk, pObj, i ) { - Vec_PtrForEachEntry( FTIMEEDGES(pObj), pNext, j ) { - vTimeIn = FDATA(pNext)->vNodes; - if (!vTimeIn) { - vTimeIn = FDATA(pNext)->vNodes = Vec_PtrAlloc(2); - } - Vec_PtrPush(vTimeIn, pObj); - } - } - } -#endif - - // clear histogram - memset(Vec_IntArray(pManMR->vSinkDistHist), 0, sizeof(int)*Vec_IntSize(pManMR->vSinkDistHist)); - - // seed queue : latches, PIOs, and blocks - Abc_NtkForEachObj( pNtk, pObj, i ) - if (Abc_ObjIsPo(pObj) || - Abc_ObjIsLatch(pObj) || - (pManMR->fIsForward && FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask)) { - Vec_PtrPush(qn, pObj); - Vec_IntPush(qe, 'r'); - FDATA(pObj)->r_dist = 1; - } else if (Abc_ObjIsPi(pObj) || - (!pManMR->fIsForward && FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask)) { - Vec_PtrPush(qn, pObj); - Vec_IntPush(qe, 'e'); - FDATA(pObj)->e_dist = 1; - } - - // until queue is empty... - while(qpos < Vec_PtrSize(qn)) { - pObj = (Abc_Obj_t *)Vec_PtrEntry(qn, qpos); - assert(pObj); - end = Vec_IntEntry(qe, qpos); - qpos++; - - if (end == 'r') { - d = FDATA(pObj)->r_dist; - - // 1. structural edges - if (pManMR->fIsForward) { - Abc_ObjForEachFanin( pObj, pNext, i ) - if (!FDATA(pNext)->e_dist) { - FDATA(pNext)->e_dist = d+1; - Vec_PtrPush(qn, pNext); - Vec_IntPush(qe, 'e'); - } - } else - Abc_ObjForEachFanout( pObj, pNext, i ) - if (!FDATA(pNext)->e_dist) { - FDATA(pNext)->e_dist = d+1; - Vec_PtrPush(qn, pNext); - Vec_IntPush(qe, 'e'); - } - - if (d == 1) continue; - - // 2. reverse edges (forward retiming only) - if (pManMR->fIsForward) { - Abc_ObjForEachFanout( pObj, pNext, i ) - if (!FDATA(pNext)->r_dist && !Abc_ObjIsLatch(pNext)) { - FDATA(pNext)->r_dist = d+1; - Vec_PtrPush(qn, pNext); - Vec_IntPush(qe, 'r'); - } - - // 3. timimg edges (forward retiming only) -#if !defined(IGNORE_TIMING) - if (pManMR->maxDelay && FDATA(pObj)->vNodes) - Vec_PtrForEachEntry( FDATA(pObj)->vNodes, pNext, i ) { - if (!FDATA(pNext)->r_dist) { - FDATA(pNext)->r_dist = d+1; - Vec_PtrPush(qn, pNext); - Vec_IntPush(qe, 'r'); - } - } -#endif - } - - } else { // if 'e' - if (Abc_ObjIsLatch(pObj)) continue; - - d = FDATA(pObj)->e_dist; - - // 1. through node - if (!FDATA(pObj)->r_dist) { - FDATA(pObj)->r_dist = d+1; - Vec_PtrPush(qn, pObj); - Vec_IntPush(qe, 'r'); - } - - // 2. reverse edges (backward retiming only) - if (!pManMR->fIsForward) { - Abc_ObjForEachFanin( pObj, pNext, i ) - if (!FDATA(pNext)->e_dist && !Abc_ObjIsLatch(pNext)) { - FDATA(pNext)->e_dist = d+1; - Vec_PtrPush(qn, pNext); - Vec_IntPush(qe, 'e'); - } - - // 3. timimg edges (backward retiming only) -#if !defined(IGNORE_TIMING) - if (pManMR->maxDelay && FDATA(pObj)->vNodes) - Vec_PtrForEachEntry( FDATA(pObj)->vNodes, pNext, i ) { - if (!FDATA(pNext)->e_dist) { - FDATA(pNext)->e_dist = d+1; - Vec_PtrPush(qn, pNext); - Vec_IntPush(qe, 'e'); - } - } -#endif - } - } - } - - // free time edges -#if !defined(IGNORE_TIMING) - if (pManMR->maxDelay) { - Abc_NtkForEachObj( pNtk, pObj, i ) { - vTimeIn = FDATA(pObj)->vNodes; - if (vTimeIn) { - Vec_PtrFree(vTimeIn); - FDATA(pObj)->vNodes = 0; - } - } - } -#endif - - Abc_NtkForEachObj( pNtk, pObj, i ) { - Vec_IntAddToEntry(pManMR->vSinkDistHist, FDATA(pObj)->r_dist, 1); - Vec_IntAddToEntry(pManMR->vSinkDistHist, FDATA(pObj)->e_dist, 1); - -#ifdef DEBUG_PREORDER - printf("node %d\t: r=%d\te=%d\n", Abc_ObjId(pObj), FDATA(pObj)->r_dist, FDATA(pObj)->e_dist); -#endif - } - - // printf("\t\tpre-ordered (max depth=%d)\n", d+1); - - // deallocate - Vec_PtrFree( qn ); - Vec_IntFree( qe ); -} - -int dfsfast_e( Abc_Obj_t *pObj, Abc_Obj_t *pPred ) { - int i; - Abc_Obj_t *pNext; - - if (pManMR->fSinkDistTerminate) return 0; - - // have we reached the sink? - if(FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask || - Abc_ObjIsPi(pObj)) { - assert(pPred); - assert(!pManMR->fIsForward); - return 1; - } - - FSET(pObj, VISITED_E); - -#ifdef DEBUG_VISITED - printf("(%de=%d) ", Abc_ObjId(pObj), FDATA(pObj)->e_dist); -#endif - - // 1. structural edges - if (pManMR->fIsForward) - Abc_ObjForEachFanout( pObj, pNext, i ) { - if (!FTEST(pNext, VISITED_R) && - FDIST(pObj, e, pNext, r) && - dfsfast_r(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("o"); -#endif - goto found; - } - } - else - Abc_ObjForEachFanin( pObj, pNext, i ) { - if (!FTEST(pNext, VISITED_R) && - FDIST(pObj, e, pNext, r) && - dfsfast_r(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("o"); -#endif - goto found; - } - } - - if (Abc_ObjIsLatch(pObj)) - goto not_found; - - // 2. reverse edges (backward retiming only) - if (!pManMR->fIsForward) { - Abc_ObjForEachFanout( pObj, pNext, i ) { - if (!FTEST(pNext, VISITED_E) && - FDIST(pObj, e, pNext, e) && - dfsfast_e(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("i"); -#endif - goto found; - } - } - - // 3. timing edges (backward retiming only) -#if !defined(IGNORE_TIMING) - if (pManMR->maxDelay) - Vec_PtrForEachEntry( FTIMEEDGES(pObj), pNext, i) { - if (!FTEST(pNext, VISITED_E) && - FDIST(pObj, e, pNext, e) && - dfsfast_e(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("o"); -#endif - goto found; - } - } -#endif - } - - // unwind - if (FTEST(pObj, FLOW) && - !FTEST(pObj, VISITED_R) && - FDIST(pObj, e, pObj, r) && - dfsfast_r(pObj, FGETPRED(pObj))) { - - FUNSET(pObj, FLOW); - FSETPRED(pObj, NULL); -#ifdef DEBUG_PRINT_FLOWS - printf("u"); -#endif - goto found; - } - - not_found: - FUNSET(pObj, VISITED_E); - dfsfast_e_retreat(pObj); - return 0; - - found: -#ifdef DEBUG_PRINT_FLOWS - printf("%d ", Abc_ObjId(pObj)); -#endif - FUNSET(pObj, VISITED_E); - return 1; -} - -int dfsfast_r( Abc_Obj_t *pObj, Abc_Obj_t *pPred ) { - int i; - Abc_Obj_t *pNext, *pOldPred; - - if (pManMR->fSinkDistTerminate) return 0; - -#ifdef DEBUG_VISITED - printf("(%dr=%d) ", Abc_ObjId(pObj), FDATA(pObj)->r_dist); -#endif - - // have we reached the sink? - if (Abc_ObjIsLatch(pObj) || - (pManMR->fIsForward && Abc_ObjIsPo(pObj)) || - (pManMR->fIsForward && FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask)) { - assert(pPred); - return 1; - } - - FSET(pObj, VISITED_R); - - if (FTEST(pObj, FLOW)) { - - pOldPred = FGETPRED(pObj); - if (pOldPred && - !FTEST(pOldPred, VISITED_E) && - FDIST(pObj, r, pOldPred, e) && - dfsfast_e(pOldPred, pOldPred)) { - - FSETPRED(pObj, pPred); - -#ifdef DEBUG_PRINT_FLOWS - printf("fr"); -#endif - goto found; - } - - } else { - - if (!FTEST(pObj, VISITED_E) && - FDIST(pObj, r, pObj, e) && - dfsfast_e(pObj, pObj)) { - - FSET(pObj, FLOW); - FSETPRED(pObj, pPred); - -#ifdef DEBUG_PRINT_FLOWS - printf("f"); -#endif - goto found; - } - } - - // 2. reverse edges (forward retiming only) - if (pManMR->fIsForward) { - Abc_ObjForEachFanin( pObj, pNext, i ) { - if (!FTEST(pNext, VISITED_R) && - FDIST(pObj, r, pNext, r) && - !Abc_ObjIsLatch(pNext) && - dfsfast_r(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("i"); -#endif - goto found; - } - } - - // 3. timing edges (forward retiming only) -#if !defined(IGNORE_TIMING) - if (pManMR->maxDelay) - Vec_PtrForEachEntry( FTIMEEDGES(pObj), pNext, i) { - if (!FTEST(pNext, VISITED_R) && - FDIST(pObj, r, pNext, r) && - dfsfast_r(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("o"); -#endif - goto found; - } - } -#endif - } - - FUNSET(pObj, VISITED_R); - dfsfast_r_retreat(pObj); - return 0; - - found: -#ifdef DEBUG_PRINT_FLOWS - printf("%d ", Abc_ObjId(pObj)); -#endif - FUNSET(pObj, VISITED_R); - return 1; -} - -void -dfsfast_e_retreat(Abc_Obj_t *pObj) { - Abc_Obj_t *pNext; - int i, *h; - int old_dist = FDATA(pObj)->e_dist; - int adj_dist, min_dist = MAX_DIST; - - // 1. structural edges - if (pManMR->fIsForward) - Abc_ObjForEachFanout( pObj, pNext, i ) { - adj_dist = FDATA(pNext)->r_dist; - if (adj_dist) min_dist = MIN(min_dist, adj_dist); - } - else - Abc_ObjForEachFanin( pObj, pNext, i ) { - adj_dist = FDATA(pNext)->r_dist; - if (adj_dist) min_dist = MIN(min_dist, adj_dist); - } - - if (Abc_ObjIsLatch(pObj)) goto update; - - // 2. through - if (FTEST(pObj, FLOW)) { - adj_dist = FDATA(pObj)->r_dist; - if (adj_dist) min_dist = MIN(min_dist, adj_dist); - } - - // 3. reverse edges (backward retiming only) - if (!pManMR->fIsForward) { - Abc_ObjForEachFanout( pObj, pNext, i ) { - adj_dist = FDATA(pNext)->e_dist; - if (adj_dist) min_dist = MIN(min_dist, adj_dist); - } - - // 4. timing edges (backward retiming only) -#if !defined(IGNORE_TIMING) - if (pManMR->maxDelay) - Vec_PtrForEachEntry( FTIMEEDGES(pObj), pNext, i) { - adj_dist = FDATA(pNext)->e_dist; - if (adj_dist) min_dist = MIN(min_dist, adj_dist); - } -#endif - } - - update: - ++min_dist; - if (min_dist >= MAX_DIST) min_dist = 0; - // printf("[%de=%d->%d] ", Abc_ObjId(pObj), old_dist, min_dist+1); - FDATA(pObj)->e_dist = min_dist; - - assert(min_dist < Vec_IntSize(pManMR->vSinkDistHist)); - h = Vec_IntArray(pManMR->vSinkDistHist); - h[old_dist]--; - h[min_dist]++; - if (!h[old_dist]) { - pManMR->fSinkDistTerminate = 1; - } -} - -void -dfsfast_r_retreat(Abc_Obj_t *pObj) { - Abc_Obj_t *pNext; - int i, *h; - int old_dist = FDATA(pObj)->r_dist; - int adj_dist, min_dist = MAX_DIST; - - // 1. through or pred - if (FTEST(pObj, FLOW)) { - if (FGETPRED(pObj)) { - adj_dist = FDATA(FGETPRED(pObj))->e_dist; - if (adj_dist) min_dist = MIN(min_dist, adj_dist); - } - } else { - adj_dist = FDATA(pObj)->e_dist; - if (adj_dist) min_dist = MIN(min_dist, adj_dist); - } - - // 2. reverse edges (forward retiming only) - if (pManMR->fIsForward) { - Abc_ObjForEachFanin( pObj, pNext, i ) - if (!Abc_ObjIsLatch(pNext)) { - adj_dist = FDATA(pNext)->r_dist; - if (adj_dist) min_dist = MIN(min_dist, adj_dist); - } - - // 3. timing edges (forward retiming only) -#if !defined(IGNORE_TIMING) - if (pManMR->maxDelay) - Vec_PtrForEachEntry( FTIMEEDGES(pObj), pNext, i) { - adj_dist = FDATA(pNext)->r_dist; - if (adj_dist) min_dist = MIN(min_dist, adj_dist); - } -#endif - } - - ++min_dist; - if (min_dist >= MAX_DIST) min_dist = 0; - //printf("[%dr=%d->%d] ", Abc_ObjId(pObj), old_dist, min_dist+1); - FDATA(pObj)->r_dist = min_dist; - - assert(min_dist < Vec_IntSize(pManMR->vSinkDistHist)); - h = Vec_IntArray(pManMR->vSinkDistHist); - h[old_dist]--; - h[min_dist]++; - if (!h[old_dist]) { - pManMR->fSinkDistTerminate = 1; - } -} - -/**Function************************************************************* - - Synopsis [Plain DFS.] - - Description [Does not use sink-distance-histogram heuristic.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -int dfsplain_e( Abc_Obj_t *pObj, Abc_Obj_t *pPred ) { - int i; - Abc_Obj_t *pNext; - - if (FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask || - Abc_ObjIsPi(pObj)) { - assert(pPred); - assert(!pManMR->fIsForward); - return 1; - } - - FSET(pObj, VISITED_E); - - // printf(" %de\n", Abc_ObjId(pObj)); - - // 1. structural edges - if (pManMR->fIsForward) - Abc_ObjForEachFanout( pObj, pNext, i ) { - if (!FTEST(pNext, VISITED_R) && - dfsplain_r(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("o"); -#endif - goto found; - } - } - else - Abc_ObjForEachFanin( pObj, pNext, i ) { - if (!FTEST(pNext, VISITED_R) && - dfsplain_r(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("o"); -#endif - goto found; - } - } - - if (Abc_ObjIsLatch(pObj)) - return 0; - - // 2. reverse edges (backward retiming only) - if (!pManMR->fIsForward) { - Abc_ObjForEachFanout( pObj, pNext, i ) { - if (!FTEST(pNext, VISITED_E) && - dfsplain_e(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("i"); -#endif - goto found; - } - } - - // 3. timing edges (backward retiming only) -#if !defined(IGNORE_TIMING) - if (pManMR->maxDelay) - Vec_PtrForEachEntry( FTIMEEDGES(pObj), pNext, i) { - if (!FTEST(pNext, VISITED_E) && - dfsplain_e(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("o"); -#endif - goto found; - } - } -#endif - } - - // unwind - if (FTEST(pObj, FLOW) && - !FTEST(pObj, VISITED_R) && - dfsplain_r(pObj, FGETPRED(pObj))) { - FUNSET(pObj, FLOW); - FSETPRED(pObj, NULL); -#ifdef DEBUG_PRINT_FLOWS - printf("u"); -#endif - goto found; - } - - return 0; - - found: -#ifdef DEBUG_PRINT_FLOWS - printf("%d ", Abc_ObjId(pObj)); -#endif - - return 1; -} - -int dfsplain_r( Abc_Obj_t *pObj, Abc_Obj_t *pPred ) { - int i; - Abc_Obj_t *pNext, *pOldPred; - - // have we reached the sink? - if (Abc_ObjIsLatch(pObj) || - (pManMR->fIsForward && Abc_ObjIsPo(pObj)) || - (pManMR->fIsForward && FTEST(pObj, BLOCK_OR_CONS) & pManMR->constraintMask)) { - assert(pPred); - return 1; - } - - FSET(pObj, VISITED_R); - - // printf(" %dr\n", Abc_ObjId(pObj)); - - if (FTEST(pObj, FLOW)) { - - pOldPred = FGETPRED(pObj); - if (pOldPred && - !FTEST(pOldPred, VISITED_E) && - dfsplain_e(pOldPred, pOldPred)) { - - FSETPRED(pObj, pPred); - -#ifdef DEBUG_PRINT_FLOWS - printf("fr"); -#endif - goto found; - } - - } else { - - if (!FTEST(pObj, VISITED_E) && - dfsplain_e(pObj, pObj)) { - - FSET(pObj, FLOW); - FSETPRED(pObj, pPred); - -#ifdef DEBUG_PRINT_FLOWS - printf("f"); -#endif - goto found; - } - } - - // 2. follow reverse edges - if (pManMR->fIsForward) { // forward retiming only - Abc_ObjForEachFanin( pObj, pNext, i ) { - if (!FTEST(pNext, VISITED_R) && - !Abc_ObjIsLatch(pNext) && - dfsplain_r(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("i"); -#endif - goto found; - } - } - - // 3. timing edges (forward only) -#if !defined(IGNORE_TIMING) - if (pManMR->maxDelay) - Vec_PtrForEachEntry( FTIMEEDGES(pObj), pNext, i) { - if (!FTEST(pNext, VISITED_R) && - dfsplain_r(pNext, pPred)) { -#ifdef DEBUG_PRINT_FLOWS - printf("o"); -#endif - goto found; - } - } -#endif - } - - return 0; - - found: -#ifdef DEBUG_PRINT_FLOWS - printf("%d ", Abc_ObjId(pObj)); -#endif - return 1; -} diff --git a/src/opt/fret/fretInit.c b/src/opt/fret/fretInit.c deleted file mode 100644 index 53df7386..00000000 --- a/src/opt/fret/fretInit.c +++ /dev/null @@ -1,762 +0,0 @@ -/**CFile**************************************************************** - - FileName [fretInit.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Flow-based retiming package.] - - Synopsis [Initialization for retiming package.] - - Author [Aaron Hurst] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 1, 2008.] - - Revision [$Id: fretInit.c,v 1.00 2008/01/01 00:00:00 ahurst Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "vec.h" -#include "io.h" -#include "fretime.h" -#include "mio.h" - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION PROTOTYPES /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_FlowRetime_UpdateForwardInit_rec( Abc_Obj_t * pObj ); -static void Abc_FlowRetime_VerifyBackwardInit( Abc_Ntk_t * pNtk ); -static void Abc_FlowRetime_VerifyBackwardInit_rec( Abc_Obj_t * pObj ); -static Abc_Obj_t* Abc_FlowRetime_UpdateBackwardInit_rec( Abc_Obj_t *pOrigObj, - Abc_Obj_t *pUseThisPi, Vec_Ptr_t *vOtherPis, - int recurse); -static void Abc_FlowRetime_SimulateNode( Abc_Obj_t * pObj ); -static void Abc_FlowRetime_SimulateSop( Abc_Obj_t * pObj, char *pSop ); - -extern void * Abc_FrameReadLibGen(); -extern Abc_Ntk_t * Abc_NtkRestrash( Abc_Ntk_t * pNtk, bool fCleanup ); - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Updates initial state information.] - - Description [Assumes latch boxes in original position, latches in - new positions.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void -Abc_FlowRetime_InitState( Abc_Ntk_t * pNtk ) { - - if (!pManMR->fComputeInitState) return; - - if (pManMR->fIsForward) - Abc_FlowRetime_UpdateForwardInit( pNtk ); - else { - Abc_FlowRetime_UpdateBackwardInit( pNtk ); - } -} - - -/**Function************************************************************* - - Synopsis [Prints initial state information.] - - Description [Prints distribution of 0,1,and X initial states.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void -Abc_FlowRetime_PrintInitStateInfo( Abc_Ntk_t * pNtk ) { - int i, n0=0, n1=0, nDC=0, nOther=0; - Abc_Obj_t *pLatch; - - Abc_NtkForEachLatch( pNtk, pLatch, i ) { - if (Abc_LatchIsInit0(pLatch)) n0++; - else if (Abc_LatchIsInit1(pLatch)) n1++; - else if (Abc_LatchIsInitDc(pLatch)) nDC++; - else nOther++; - } - - printf("\tinitial states {0,1,x} = {%d, %d, %d}", n0, n1, nDC); - if (nOther) - printf(" + %d UNKNOWN", nOther); - printf("\n"); -} - - -/**Function************************************************************* - - Synopsis [Computes initial state after forward retiming.] - - Description [Assumes box outputs in old positions stored w/ init values. - Uses three-value simulation to preserve don't cares.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_UpdateForwardInit( Abc_Ntk_t * pNtk ) { - Abc_Obj_t *pObj, *pFanin; - int i; - - vprintf("\t\tupdating init state\n"); - - Abc_NtkIncrementTravId( pNtk ); - - Abc_NtkForEachLatch( pNtk, pObj, i ) { - pFanin = Abc_ObjFanin0(pObj); - Abc_FlowRetime_UpdateForwardInit_rec( pFanin ); - - if (FTEST(pFanin, INIT_0)) - Abc_LatchSetInit0( pObj ); - else if (FTEST(pFanin, INIT_1)) - Abc_LatchSetInit1( pObj ); - else - Abc_LatchSetInitDc( pObj ); - } -} - -void Abc_FlowRetime_UpdateForwardInit_rec( Abc_Obj_t * pObj ) { - Abc_Obj_t *pNext; - int i; - - assert(!Abc_ObjIsPi(pObj)); // should never reach the inputs - - if (Abc_ObjIsBo(pObj)) return; - - // visited? - if (Abc_NodeIsTravIdCurrent(pObj)) return; - Abc_NodeSetTravIdCurrent(pObj); - - Abc_ObjForEachFanin( pObj, pNext, i ) { - Abc_FlowRetime_UpdateForwardInit_rec( pNext ); - } - - Abc_FlowRetime_SimulateNode( pObj ); -} - - -/**Function************************************************************* - - Synopsis [Sets initial value flags.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Abc_FlowRetime_SetInitValue( Abc_Obj_t * pObj, - int val, int dc ) { - - // store init value - FUNSET(pObj, INIT_CARE); - if (!dc){ - if (val) { - FSET(pObj, INIT_1); - } else { - FSET(pObj, INIT_0); - } - } -} - - -/**Function************************************************************* - - Synopsis [Propogates initial state through a logic node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_SimulateNode( Abc_Obj_t * pObj ) { - Abc_Ntk_t *pNtk = Abc_ObjNtk(pObj); - Abc_Obj_t * pFanin; - int i, rAnd, rVar, dcAnd, dcVar; - DdManager * dd = pNtk->pManFunc; - DdNode *pBdd = pObj->pData, *pVar; - - assert(!Abc_ObjIsLatch(pObj)); - - // (i) constant nodes - if (Abc_NtkHasAig(pNtk) && Abc_AigNodeIsConst(pObj)) { - Abc_FlowRetime_SetInitValue(pObj, 1, 0); - return; - } - if (!Abc_NtkIsStrash( pNtk ) && Abc_ObjIsNode(pObj)) { - if (Abc_NodeIsConst0(pObj)) { - Abc_FlowRetime_SetInitValue(pObj, 0, 0); - return; - } else if (Abc_NodeIsConst1(pObj)) { - Abc_FlowRetime_SetInitValue(pObj, 1, 0); - return; - } - } - - // (ii) terminal nodes - if (!Abc_ObjIsNode(pObj)) { - pFanin = Abc_ObjFanin0(pObj); - - Abc_FlowRetime_SetInitValue(pObj, - (FTEST(pFanin, INIT_1) ? 1 : 0) ^ pObj->fCompl0, - !FTEST(pFanin, INIT_CARE)); - return; - } - - // (iii) logic nodes - - // ------ SOP network - if ( Abc_NtkHasSop( pNtk )) { - Abc_FlowRetime_SimulateSop( pObj, (char *)Abc_ObjData(pObj) ); - return; - } - - // ------ BDD network - else if ( Abc_NtkHasBdd( pNtk )) { - assert(dd); - assert(pBdd); - - // cofactor for 0,1 inputs - // do nothing for X values - Abc_ObjForEachFanin(pObj, pFanin, i) { - pVar = Cudd_bddIthVar( dd, i ); - if (FTEST(pFanin, INIT_CARE)) { - if (FTEST(pFanin, INIT_0)) - pBdd = Cudd_Cofactor( dd, pBdd, Cudd_Not(pVar) ); - else - pBdd = Cudd_Cofactor( dd, pBdd, pVar ); - } - } - - // if function has not been reduced to - // a constant, propagate an X - rVar = (pBdd == Cudd_ReadOne(dd)); - dcVar = !Cudd_IsConstant(pBdd); - - Abc_FlowRetime_SetInitValue(pObj, rVar, dcVar); - return; - } - - // ------ AIG network - else if ( Abc_NtkHasAig( pNtk )) { - - assert(Abc_AigNodeIsAnd(pObj)); - dcAnd = 0, rAnd = 1; - - pFanin = Abc_ObjFanin0(pObj); - dcAnd |= FTEST(pFanin, INIT_CARE) ? 0 : 1; - rVar = FTEST(pFanin, INIT_0) ? 0 : 1; - if (pObj->fCompl0) rVar ^= 1; // complimented? - rAnd &= rVar; - - pFanin = Abc_ObjFanin1(pObj); - dcAnd |= FTEST(pFanin, INIT_CARE) ? 0 : 1; - rVar = FTEST(pFanin, INIT_0) ? 0 : 1; - if (pObj->fCompl1) rVar ^= 1; // complimented? - rAnd &= rVar; - - if (!rAnd) dcAnd = 0; /* controlling value */ - - Abc_FlowRetime_SetInitValue(pObj, rAnd, dcAnd); - return; - } - - // ------ MAPPED network - else if ( Abc_NtkHasMapping( pNtk )) { - Abc_FlowRetime_SimulateSop( pObj, (char *)Mio_GateReadSop(pObj->pData) ); - return; - } - - assert(0); -} - - -/**Function************************************************************* - - Synopsis [Propogates initial state through a SOP node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_SimulateSop( Abc_Obj_t * pObj, char *pSop ) { - Abc_Obj_t * pFanin; - char *pCube; - int i, j, rAnd, rOr, rVar, dcAnd, dcOr, v; - - assert( pSop && !Abc_SopIsExorType(pSop) ); - - rOr = 0, dcOr = 0; - - i = Abc_SopGetVarNum(pSop); - Abc_SopForEachCube( pSop, i, pCube ) { - rAnd = 1, dcAnd = 0; - Abc_CubeForEachVar( pCube, v, j ) { - pFanin = Abc_ObjFanin(pObj, j); - if ( v == '0' ) - rVar = FTEST(pFanin, INIT_0) ? 1 : 0; - else if ( v == '1' ) - rVar = FTEST(pFanin, INIT_1) ? 1 : 0; - else - continue; - - if (FTEST(pFanin, INIT_CARE)) - rAnd &= rVar; - else - dcAnd = 1; - } - if (!rAnd) dcAnd = 0; /* controlling value */ - if (dcAnd) - dcOr = 1; - else - rOr |= rAnd; - } - if (rOr) dcOr = 0; /* controlling value */ - - // complement the result if necessary - if ( !Abc_SopGetPhase(pSop) ) - rOr ^= 1; - - Abc_FlowRetime_SetInitValue(pObj, rOr, dcOr); -} - -/**Function************************************************************* - - Synopsis [Sets up backward initial state computation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_SetupBackwardInit( Abc_Ntk_t * pNtk ) { - Abc_Obj_t *pLatch, *pObj, *pPi; - int i; - Vec_Ptr_t *vObj = Vec_PtrAlloc(100); - - // create the network used for the initial state computation - if (Abc_NtkHasMapping(pNtk)) - pManMR->pInitNtk = Abc_NtkAlloc( pNtk->ntkType, ABC_FUNC_SOP, 1 ); - else - pManMR->pInitNtk = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 ); - - // mitre inputs - Abc_NtkForEachLatch( pNtk, pLatch, i ) { - // map latch to initial state network - pPi = Abc_NtkCreatePi( pManMR->pInitNtk ); - - // has initial state requirement? - if (Abc_LatchIsInit0(pLatch)) { - - if (Abc_NtkHasAig(pNtk)) - pObj = Abc_ObjNot( pPi ); - else - pObj = Abc_NtkCreateNodeInv( pManMR->pInitNtk, pPi ); - - Vec_PtrPush(vObj, pObj); - } - else if (Abc_LatchIsInit1(pLatch)) { - Vec_PtrPush(vObj, pPi); - } - - Abc_ObjSetData( pLatch, pPi ); // if not verifying init state - // FDATA(pLatch)->pInitObj = pPi; // if verifying init state - } - - // are there any nodes not DC? - if (!Vec_PtrSize(vObj)) { - pManMR->fSolutionIsDc = 1; - return; - } else - pManMR->fSolutionIsDc = 0; - - // mitre output - if (Abc_NtkHasAig(pNtk)) { - // create AND-by-AND - pObj = Vec_PtrPop( vObj ); - while( Vec_PtrSize(vObj) ) - pObj = Abc_AigAnd( pManMR->pInitNtk->pManFunc, pObj, Vec_PtrPop( vObj ) ); - } else - // create n-input AND gate - pObj = Abc_NtkCreateNodeAnd( pManMR->pInitNtk, vObj ); - - Abc_ObjAddFanin( Abc_NtkCreatePo( pManMR->pInitNtk ), pObj ); - - Vec_PtrFree( vObj ); -} - - -/**Function************************************************************* - - Synopsis [Solves backward initial state computation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_FlowRetime_SolveBackwardInit( Abc_Ntk_t * pNtk ) { - int i; - Abc_Obj_t *pObj, *pInitObj; - Vec_Ptr_t *vDelete = Vec_PtrAlloc(0); - int result; - - assert(pManMR->pInitNtk); - - // is the solution entirely DC's? - if (pManMR->fSolutionIsDc) { - Abc_NtkDelete(pManMR->pInitNtk); - Vec_PtrFree(vDelete); - Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_LatchSetInitDc( pObj ); - vprintf("\tno init state computation: all-don't-care solution\n"); - return 1; - } - - // check that network is combinational - // mark superfluous BI nodes for deletion - Abc_NtkForEachObj( pManMR->pInitNtk, pObj, i ) { - assert(!Abc_ObjIsLatch(pObj)); - assert(!Abc_ObjIsBo(pObj)); - - if (Abc_ObjIsBi(pObj)) { - Abc_ObjBetterTransferFanout( pObj, Abc_ObjFanin0(pObj), Abc_ObjFaninC0(pObj) ); - Vec_PtrPush( vDelete, pObj ); - } - } - - // delete superfluous nodes - while(Vec_PtrSize( vDelete )) { - pObj = (Abc_Obj_t *)Vec_PtrPop( vDelete ); - Abc_NtkDeleteObj( pObj ); - } - Vec_PtrFree(vDelete); - - // do some final cleanup on the network - Abc_NtkAddDummyPoNames(pManMR->pInitNtk); - Abc_NtkAddDummyPiNames(pManMR->pInitNtk); - if (Abc_NtkIsLogic(pManMR->pInitNtk)) - Abc_NtkCleanup(pManMR->pInitNtk, 0); - else if (Abc_NtkIsStrash(pManMR->pInitNtk)) { - Abc_NtkReassignIds(pManMR->pInitNtk); - } - - vprintf("\tsolving for init state (%d nodes)... ", Abc_NtkObjNum(pManMR->pInitNtk)); - fflush(stdout); - - // convert SOPs to BDD - if (Abc_NtkHasSop(pManMR->pInitNtk)) - Abc_NtkSopToBdd( pManMR->pInitNtk ); - - // solve - result = Abc_NtkMiterSat( pManMR->pInitNtk, (sint64)500000, (sint64)50000000, 0, NULL, NULL ); - - if (!result) { - vprintf("SUCCESS\n"); - } else { - vprintf("FAILURE\n"); - printf("WARNING: no equivalent init state. setting all initial states to don't-cares\n"); - Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_LatchSetInitDc( pObj ); - Abc_NtkDelete(pManMR->pInitNtk); - return 0; - } - - // clear initial values, associate PIs to latches - Abc_NtkForEachPi( pManMR->pInitNtk, pInitObj, i ) Abc_ObjSetCopy( pInitObj, NULL ); - Abc_NtkForEachLatch( pNtk, pObj, i ) { - pInitObj = Abc_ObjData( pObj ); - assert( Abc_ObjIsPi( pInitObj )); - Abc_ObjSetCopy( pInitObj, pObj ); - Abc_LatchSetInitNone( pObj ); - } - - // copy solution from PIs to latches - assert(pManMR->pInitNtk->pModel); - Abc_NtkForEachPi( pManMR->pInitNtk, pInitObj, i ) { - if ((pObj = Abc_ObjCopy( pInitObj ))) { - if ( pManMR->pInitNtk->pModel[i] ) - Abc_LatchSetInit1( pObj ); - else - Abc_LatchSetInit0( pObj ); - } - } - -#if defined(DEBUG_CHECK) - // check that all latches have initial state - Abc_NtkForEachLatch( pNtk, pObj, i ) assert( !Abc_LatchIsInitNone( pObj ) ); -#endif - - // deallocate - Abc_NtkDelete( pManMR->pInitNtk ); - - return 1; -} - - -/**Function************************************************************* - - Synopsis [Updates backward initial state computation problem.] - - Description [Assumes box outputs in old positions stored w/ init values.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_UpdateBackwardInit( Abc_Ntk_t * pNtk ) { - Abc_Obj_t *pOrigObj, *pInitObj; - Vec_Ptr_t *vBo = Vec_PtrAlloc(100); - Vec_Ptr_t *vOldPis = Vec_PtrAlloc(100); - int i; - - // remove PIs from network (from BOs) - Abc_NtkForEachObj( pNtk, pOrigObj, i ) - if (Abc_ObjIsBo(pOrigObj)) { - pInitObj = FDATA(pOrigObj)->pInitObj; - assert(Abc_ObjIsPi(pInitObj)); - Vec_PtrPush(vBo, pOrigObj); - - Abc_FlowRetime_UpdateBackwardInit_rec( Abc_ObjFanin0( pOrigObj ), pInitObj, vOldPis, 0 ); - } - - // add PIs to network (at latches) - Abc_NtkForEachLatch( pNtk, pOrigObj, i ) - Abc_FlowRetime_UpdateBackwardInit_rec( pOrigObj, NULL, vOldPis, 0 ); - - // connect nodes in init state network - Vec_PtrForEachEntry( vBo, pOrigObj, i ) - Abc_FlowRetime_UpdateBackwardInit_rec( Abc_ObjFanin0( pOrigObj ), NULL, NULL, 1 ); - - // clear flags - Abc_NtkForEachObj( pNtk, pOrigObj, i ) - pOrigObj->fMarkA = pOrigObj->fMarkB = 0; - - // deallocate - Vec_PtrFree( vBo ); - Vec_PtrFree( vOldPis ); -} - - -/**Function************************************************************* - - Synopsis [Updates backward initial state computation problem.] - - Description [Creates a duplicate node in the initial state network - corresponding to a node in the original circuit. If - fRecurse is set, the procedure recurses on and connects - the new node to its fan-ins. A latch in the original - circuit corresponds to a PI in the initial state network. - An existing PI may be supplied by pUseThisPi, and if the - node is a latch, it will be used; otherwise the PI is - saved in the list vOtherPis and subsequently used for - another latch.] - - SideEffects [Nodes that have a corresponding initial state node - are marked with fMarkA. Nodes that have been fully - connected in the initial state network are marked with - fMarkB.] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t* Abc_FlowRetime_UpdateBackwardInit_rec( Abc_Obj_t *pOrigObj, - Abc_Obj_t *pUseThisPi, Vec_Ptr_t *vOtherPis, - int fRecurse) { - Abc_Obj_t *pInitObj, *pOrigFanin, *pInitFanin; - void *pData; - int i; - Abc_Ntk_t *pNtk = Abc_ObjNtk( pOrigObj ); - - // should never reach primary IOs - assert(!Abc_ObjIsPi(pOrigObj)); - assert(!Abc_ObjIsPo(pOrigObj)); - - // if fanin is latch, it becomes a primary input - if (Abc_ObjIsLatch( pOrigObj )) { - if (pOrigObj->fMarkA) return FDATA(pOrigObj)->pInitObj; - - assert(vOtherPis); - - if (pUseThisPi) { - // reuse curent PI - pInitObj = pUseThisPi; } - else { - // reuse previous PI - pInitObj = (Abc_Obj_t*)Vec_PtrPop(vOtherPis); - } - - // remember link from original node to init ntk - Abc_ObjSetData( pOrigObj, pInitObj ); - - pOrigObj->fMarkA = 1; - return (FDATA(pOrigObj)->pInitObj = pInitObj); - } - - // does an init node already exist? - if(!pOrigObj->fMarkA) { - - if (Abc_NtkHasMapping( pNtk )) { - if (!pOrigObj->pData) { - // assume terminal... - assert(Abc_ObjFaninNum(pOrigObj) == 1); - pInitObj = Abc_NtkCreateNodeBuf( pManMR->pInitNtk, NULL ); - } else { - pInitObj = Abc_NtkCreateObj( pManMR->pInitNtk, Abc_ObjType(pOrigObj) ); - pData = Mio_GateReadSop(pOrigObj->pData); - assert( Abc_SopGetVarNum(pData) == Abc_ObjFaninNum(pOrigObj) ); - - pInitObj->pData = Abc_SopRegister( pManMR->pInitNtk->pManFunc, pData ); - } - } else { - pData = Abc_ObjCopy( pOrigObj ); // save ptr to flow data - if (Abc_NtkIsStrash( pNtk ) && Abc_AigNodeIsConst( pOrigObj )) - pInitObj = Abc_AigConst1( pManMR->pInitNtk ); - else - pInitObj = Abc_NtkDupObj( pManMR->pInitNtk, pOrigObj, 0 ); - Abc_ObjSetCopy( pOrigObj, pData ); // restore ptr to flow data - - // copy complementation - pInitObj->fCompl0 = pOrigObj->fCompl0; - pInitObj->fCompl1 = pOrigObj->fCompl1; - pInitObj->fPhase = pOrigObj->fPhase; - } - - // if we didn't use given PI, immediately transfer fanouts - // and add to list for later reuse - if (pUseThisPi) { - Abc_ObjBetterTransferFanout( pUseThisPi, pInitObj, 0 ); - Vec_PtrPush( vOtherPis, pUseThisPi ); - } - - pOrigObj->fMarkA = 1; - FDATA(pOrigObj)->pInitObj = pInitObj; - } else { - pInitObj = FDATA(pOrigObj)->pInitObj; - } - - // have we already connected this object? - if (fRecurse && !pOrigObj->fMarkB) { - - // create and/or connect fanins - Abc_ObjForEachFanin( pOrigObj, pOrigFanin, i ) { - pInitFanin = Abc_FlowRetime_UpdateBackwardInit_rec( pOrigFanin, NULL, NULL, fRecurse ); - Abc_ObjAddFanin( pInitObj, pInitFanin ); - } - - pOrigObj->fMarkB = 1; - } - - return pInitObj; -} - - -/**Function************************************************************* - - Synopsis [Verifies backward init state computation.] - - Description [This procedure requires the BOs to store the original - latch values and the latches to store the new values: - both in the INIT_0 and INIT_1 flags in the Flow_Data - structure. (This is not currently the case in the rest - of the code.) Also, can not verify backward state - computations that span multiple combinational frames.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_VerifyBackwardInit( Abc_Ntk_t * pNtk ) { - Abc_Obj_t *pObj, *pFanin; - int i; - - vprintf("\t\tupdating init state\n"); - - Abc_NtkIncrementTravId( pNtk ); - - Abc_NtkForEachObj( pNtk, pObj, i ) - if (Abc_ObjIsBo( pObj )) { - pFanin = Abc_ObjFanin0(pObj); - Abc_FlowRetime_VerifyBackwardInit_rec( pFanin ); - - if (FTEST(pObj, INIT_CARE)) { - if(FTEST(pObj, INIT_CARE) != FTEST(pFanin, INIT_CARE)) { - printf("ERROR: expected val=%d care=%d and got val=%d care=%d\n", - FTEST(pObj, INIT_1)?1:0, FTEST(pObj, INIT_CARE)?1:0, - FTEST(pFanin, INIT_1)?1:0, FTEST(pFanin, INIT_CARE)?1:0 ); - - } - } - } -} - -void Abc_FlowRetime_VerifyBackwardInit_rec( Abc_Obj_t * pObj ) { - Abc_Obj_t *pNext; - int i; - - assert(!Abc_ObjIsBo(pObj)); // should never reach the inputs - assert(!Abc_ObjIsPi(pObj)); // should never reach the inputs - - // visited? - if (Abc_NodeIsTravIdCurrent(pObj)) return; - Abc_NodeSetTravIdCurrent(pObj); - - if (Abc_ObjIsLatch(pObj)) { - FUNSET(pObj, INIT_CARE); - if (Abc_LatchIsInit0(pObj)) - FSET(pObj, INIT_0); - else if (Abc_LatchIsInit1(pObj)) - FSET(pObj, INIT_1); - return; - } - - Abc_ObjForEachFanin( pObj, pNext, i ) { - Abc_FlowRetime_VerifyBackwardInit_rec( pNext ); - } - - Abc_FlowRetime_SimulateNode( pObj ); -} - - -/**Function************************************************************* - - Synopsis [Constrains backward retiming for initializability.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_ConstrainInit( ) { - // unimplemented -} diff --git a/src/opt/fret/fretMain.c b/src/opt/fret/fretMain.c deleted file mode 100644 index 780c1f6f..00000000 --- a/src/opt/fret/fretMain.c +++ /dev/null @@ -1,1059 +0,0 @@ -/**CFile**************************************************************** - - FileName [fretMain.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Flow-based retiming package.] - - Synopsis [Main file for retiming package.] - - Author [Aaron Hurst] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 1, 2008.] - - Revision [$Id: fretMain.c,v 1.00 2008/01/01 00:00:00 ahurst Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "vec.h" -#include "fretime.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_FlowRetime_AddDummyFanin( Abc_Obj_t * pObj ); - -static void Abc_FlowRetime_MainLoop( ); - -static void Abc_FlowRetime_MarkBlocks( Abc_Ntk_t * pNtk ); -static void Abc_FlowRetime_MarkReachable_rec( Abc_Obj_t * pObj, char end ); -static int Abc_FlowRetime_ImplementCut( Abc_Ntk_t * pNtk ); -static void Abc_FlowRetime_RemoveLatchBubbles( Abc_Obj_t * pLatch ); - -static void Abc_FlowRetime_VerifyPathLatencies( Abc_Ntk_t * pNtk ); -static int Abc_FlowRetime_VerifyPathLatencies_rec( Abc_Obj_t * pObj, int markD ); - -extern void Abc_NtkMarkCone_rec( Abc_Obj_t * pObj, int fForward ); -extern Abc_Ntk_t * Abc_NtkRestrash( Abc_Ntk_t * pNtk, bool fCleanup ); - -void -print_node3(Abc_Obj_t *pObj); - -MinRegMan_t *pManMR; - -int fPathError = 0; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs minimum-register retiming.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * -Abc_FlowRetime_MinReg( Abc_Ntk_t * pNtk, int fVerbose, int fComputeInitState, - int fForwardOnly, int fBackwardOnly, int nMaxIters, - int maxDelay, int fFastButConservative ) { - - int i; - Abc_Obj_t *pObj, *pNext; - - // create manager - pManMR = ALLOC( MinRegMan_t, 1 ); - - pManMR->pNtk = pNtk; - pManMR->fVerbose = fVerbose; - pManMR->fComputeInitState = fComputeInitState; - pManMR->fGuaranteeInitState = 0; - pManMR->fForwardOnly = fForwardOnly; - pManMR->fBackwardOnly = fBackwardOnly; - pManMR->nMaxIters = nMaxIters; - pManMR->maxDelay = maxDelay; - pManMR->fComputeInitState = fComputeInitState; - pManMR->fConservTimingOnly = fFastButConservative; - pManMR->vNodes = Vec_PtrAlloc(100); - - vprintf("Flow-based minimum-register retiming...\n"); - - if (!Abc_NtkHasOnlyLatchBoxes(pNtk)) { - printf("\tERROR: Can not retime with black/white boxes\n"); - return pNtk; - } - - if (maxDelay) { - vprintf("\tmax delay constraint = %d\n", maxDelay); - if (maxDelay < (i = Abc_NtkLevel(pNtk))) { - printf("ERROR: max delay constraint must be > current max delay (%d)\n", i); - return pNtk; - } - } - - // print info about type of network - vprintf("\tnetlist type = "); - if (Abc_NtkIsNetlist( pNtk )) { vprintf("netlist/"); } - else if (Abc_NtkIsLogic( pNtk )) { vprintf("logic/"); } - else if (Abc_NtkIsStrash( pNtk )) { vprintf("strash/"); } - else { vprintf("***unknown***/"); } - if (Abc_NtkHasSop( pNtk )) { vprintf("sop\n"); } - else if (Abc_NtkHasBdd( pNtk )) { vprintf("bdd\n"); } - else if (Abc_NtkHasAig( pNtk )) { vprintf("aig\n"); } - else if (Abc_NtkHasMapping( pNtk )) { vprintf("mapped\n"); } - else { vprintf("***unknown***\n"); } - - vprintf("\tinitial reg count = %d\n", Abc_NtkLatchNum(pNtk)); - vprintf("\tinitial levels = %d\n", Abc_NtkLevel(pNtk)); - - // remove bubbles from latch boxes - if (pManMR->fVerbose) Abc_FlowRetime_PrintInitStateInfo(pNtk); - vprintf("\tpushing bubbles out of latch boxes\n"); - Abc_NtkForEachLatch( pNtk, pObj, i ) - Abc_FlowRetime_RemoveLatchBubbles(pObj); - if (pManMR->fVerbose) Abc_FlowRetime_PrintInitStateInfo(pNtk); - - // check for box inputs/outputs - Abc_NtkForEachLatch( pNtk, pObj, i ) { - assert(Abc_ObjFaninNum(pObj) == 1); - assert(Abc_ObjFanoutNum(pObj) == 1); - assert(!Abc_ObjFaninC0(pObj)); - - pNext = Abc_ObjFanin0(pObj); - assert(Abc_ObjIsBi(pNext)); - assert(Abc_ObjFaninNum(pNext) <= 1); - if(Abc_ObjFaninNum(pNext) == 0) // every Bi should have a fanin - Abc_FlowRetime_AddDummyFanin( pNext ); - - pNext = Abc_ObjFanout0(pObj); - assert(Abc_ObjIsBo(pNext)); - assert(Abc_ObjFaninNum(pNext) == 1); - assert(!Abc_ObjFaninC0(pNext)); - } - - pManMR->nLatches = Abc_NtkLatchNum( pNtk ); - pManMR->nNodes = Abc_NtkObjNumMax( pNtk )+1; - - // build histogram - pManMR->vSinkDistHist = Vec_IntStart( pManMR->nNodes*2+10 ); - - // initialize timing - if (maxDelay) - Abc_FlowRetime_InitTiming( pNtk ); - - // create Flow_Data structure - pManMR->pDataArray = ALLOC( Flow_Data_t, pManMR->nNodes ); - Abc_FlowRetime_ClearFlows( 1 ); - Abc_NtkForEachObj( pNtk, pObj, i ) - Abc_ObjSetCopy( pObj, (void *)(&pManMR->pDataArray[i]) ); - - // main loop! - Abc_FlowRetime_MainLoop(); - - // clear pCopy field - Abc_NtkForEachObj( pNtk, pObj, i ) { - Abc_ObjSetCopy( pObj, NULL ); - - // if not computing init state, set all latches to DC - if (!fComputeInitState && Abc_ObjIsLatch(pObj)) - Abc_LatchSetInitDc(pObj); - } - - // deallocate space - FREE( pManMR->pDataArray ); - if (pManMR->vNodes) Vec_PtrFree(pManMR->vNodes); - if (pManMR->vSinkDistHist) Vec_IntFree(pManMR->vSinkDistHist); - if (pManMR->maxDelay) Abc_FlowRetime_FreeTiming( pNtk ); - - // restrash if necessary - if (Abc_NtkIsStrash(pNtk)) { - Abc_NtkReassignIds( pNtk ); - pNtk = Abc_NtkRestrash( pNtk, 1 ); - } - - vprintf("\tfinal reg count = %d\n", Abc_NtkLatchNum(pNtk)); - vprintf("\tfinal levels = %d\n", Abc_NtkLevel(pNtk)); - -#if defined(DEBUG_CHECK) - Abc_NtkDoCheck( pNtk ); -#endif - - // free manager - FREE( pManMR ); - - return pNtk; -} - -/**Function************************************************************* - - Synopsis [Main loop.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void -Abc_FlowRetime_MainLoop( ) { - Abc_Ntk_t *pNtk = pManMR->pNtk; - // Abc_Obj_t *pObj; int i; - int last, flow = 0, cut; - - // (i) forward retiming loop - pManMR->fIsForward = 1; - pManMR->iteration = 0; - - if (!pManMR->fBackwardOnly) do { - if (pManMR->iteration == pManMR->nMaxIters) break; - pManMR->subIteration = 0; - - vprintf("\tforward iteration %d\n", pManMR->iteration); - last = Abc_NtkLatchNum( pNtk ); - - Abc_FlowRetime_MarkBlocks( pNtk ); - - if (pManMR->maxDelay) { - // timing-constrained loop - Abc_FlowRetime_ConstrainConserv( pNtk ); - while(Abc_FlowRetime_RefineConstraints( )) { - pManMR->subIteration++; - Abc_FlowRetime_ClearFlows( 0 ); - } - } else { - flow = Abc_FlowRetime_PushFlows( pNtk, 1 ); - } - - cut = Abc_FlowRetime_ImplementCut( pNtk ); - - vprintf("\t\tlevels = %d\n", Abc_NtkLevel(pNtk)); - -#if 0 - Abc_NtkForEachObj( pNtk, pObj, i ) pObj->Level = 0; - - Abc_NtkLevel(pNtk); - Abc_NtkForEachObj( pNtk, pObj, i ) - if (pObj->Level > pManMR->maxDelay) { - print_node( pObj ); - Vec_PtrForEachEntry( FTIMEEDGES(pObj), p2,j ) { - printf(":%d ", p2->Id); - } - } - Abc_NtkLevelReverse(pNtk); - Abc_NtkForEachObj( pNtk, pObj, i ) - if (pObj->Level > pManMR->maxDelay) { - print_node( pObj ); - } -#endif - - Abc_FlowRetime_ClearFlows( 1 ); - - pManMR->iteration++; - } while( cut != last ); - - // print info about initial states - if (pManMR->fComputeInitState && pManMR->fVerbose) - Abc_FlowRetime_PrintInitStateInfo( pNtk ); - - // (ii) backward retiming loop - pManMR->fIsForward = 0; - pManMR->iteration = 0; - - if (!pManMR->fForwardOnly) do { - // initializability loop - - if (pManMR->fComputeInitState) { - Abc_FlowRetime_SetupBackwardInit( pNtk ); - } - - do { - if (pManMR->iteration == pManMR->nMaxIters) break; - pManMR->subIteration = 0; - - vprintf("\tbackward iteration %d\n", pManMR->iteration); - last = Abc_NtkLatchNum( pNtk ); - - Abc_FlowRetime_MarkBlocks( pNtk ); - - if (pManMR->maxDelay) { - // timing-constrained loop - Abc_FlowRetime_ConstrainConserv( pNtk ); - while(Abc_FlowRetime_RefineConstraints( )) { - pManMR->subIteration++; - Abc_FlowRetime_ClearFlows( 0 ); - } - } else { - flow = Abc_FlowRetime_PushFlows( pNtk, 1 ); - } - - cut = Abc_FlowRetime_ImplementCut( pNtk ); - - vprintf("\t\tlevels = %d\n", Abc_NtkLevelReverse(pNtk)); - -#if 0 - Abc_NtkForEachObj( pNtk, pObj, i ) pObj->Level = 0; - - Abc_NtkLevel(pNtk); - Abc_NtkForEachObj( pNtk, pObj, i ) - if (pObj->Level > pManMR->maxDelay) { - print_node( pObj ); - } - Abc_NtkLevelReverse(pNtk); - Abc_NtkForEachObj( pNtk, pObj, i ) - if (pObj->Level > pManMR->maxDelay) { - print_node( pObj ); - } -#endif - - Abc_FlowRetime_ClearFlows( 1 ); - - pManMR->iteration++; - } while( cut != last ); - - // compute initial states - if (!pManMR->fComputeInitState) break; - - if (Abc_FlowRetime_SolveBackwardInit( pNtk )) { - if (pManMR->fVerbose) Abc_FlowRetime_PrintInitStateInfo( pNtk ); - break; - } else { - if (!pManMR->fGuaranteeInitState) break; - Abc_FlowRetime_ConstrainInit( ); - } - } while(1); -} - - -/**Function************************************************************* - - Synopsis [Pushes latch bubbles outside of box.] - - Description [If network is an AIG, a fCompl0 is allowed to remain on - the BI node.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void -Abc_FlowRetime_RemoveLatchBubbles( Abc_Obj_t * pLatch ) { - int bubble = 0; - Abc_Ntk_t *pNtk = pManMR->pNtk; - Abc_Obj_t *pBi, *pBo, *pInv; - - pBi = Abc_ObjFanin0(pLatch); - pBo = Abc_ObjFanout0(pLatch); - assert(!Abc_ObjIsComplement(pBi)); - assert(!Abc_ObjIsComplement(pBo)); - - // push bubbles on BO into latch box - if (Abc_ObjFaninC0(pBo) && Abc_ObjFanoutNum(pBo) > 0) { - bubble = 1; - if (Abc_LatchIsInit0(pLatch)) Abc_LatchSetInit1(pLatch); - else if (Abc_LatchIsInit1(pLatch)) Abc_LatchSetInit0(pLatch); - } - - // absorb bubbles on BI - pBi->fCompl0 ^= bubble ^ Abc_ObjFaninC0(pLatch); - - // convert bubble to INV if not AIG - if (!Abc_NtkHasAig( pNtk ) && Abc_ObjFaninC0(pBi)) { - pBi->fCompl0 = 0; - pInv = Abc_NtkCreateNodeInv( pNtk, Abc_ObjFanin0(pBi) ); - Abc_ObjPatchFanin( pBi, Abc_ObjFanin0(pBi), pInv ); - } - - pBo->fCompl0 = 0; - pLatch->fCompl0 = 0; -} - - -/**Function************************************************************* - - Synopsis [Marks nodes in TFO/TFI of PI/PO.] - - Description [Sets flow data flag BLOCK appropriately.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void -Abc_FlowRetime_MarkBlocks( Abc_Ntk_t * pNtk ) { - int i; - Abc_Obj_t *pObj; - - if (pManMR->fIsForward){ - // mark the frontier - Abc_NtkForEachPo( pNtk, pObj, i ) - pObj->fMarkA = 1; - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pObj->fMarkA = 1; - } - // mark the nodes reachable from the PIs - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkMarkCone_rec( pObj, pManMR->fIsForward ); - } else { - // mark the frontier - Abc_NtkForEachPi( pNtk, pObj, i ) - pObj->fMarkA = 1; - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pObj->fMarkA = 1; - } - // mark the nodes reachable from the POs - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkMarkCone_rec( pObj, pManMR->fIsForward ); - } - - // copy marks - Abc_NtkForEachObj( pNtk, pObj, i ) { - if (pObj->fMarkA) { - pObj->fMarkA = 0; - if (!Abc_ObjIsLatch(pObj) /* && !Abc_ObjIsPi(pObj) */ ) - FSET(pObj, BLOCK); - } - } -} - - -/**Function************************************************************* - - Synopsis [Computes maximum flow.] - - Description [] - - SideEffects [Leaves VISITED flags on source-reachable nodes.] - - SeeAlso [] - -***********************************************************************/ -int -Abc_FlowRetime_PushFlows( Abc_Ntk_t * pNtk, bool fVerbose ) { - int i, j, flow = 0, last, srcDist = 0; - Abc_Obj_t *pObj, *pObj2; - - pManMR->constraintMask |= BLOCK; - - pManMR->fSinkDistTerminate = 0; - dfsfast_preorder( pNtk ); - - // (i) fast max-flow computation - while(!pManMR->fSinkDistTerminate && srcDist < MAX_DIST) { - srcDist = MAX_DIST; - Abc_NtkForEachLatch( pNtk, pObj, i ) - if (FDATA(pObj)->e_dist) - srcDist = MIN(srcDist, FDATA(pObj)->e_dist); - - Abc_NtkForEachLatch( pNtk, pObj, i ) { - if (srcDist == FDATA(pObj)->e_dist && - dfsfast_e( pObj, NULL )) { -#ifdef DEBUG_PRINT_FLOWS - printf("\n\n"); -#endif - flow++; - } - } - } - - if (fVerbose) vprintf("\t\tmax-flow1 = %d \t", flow); - - // (ii) complete max-flow computation - // also, marks source-reachable nodes - do { - last = flow; - Abc_NtkForEachLatch( pNtk, pObj, i ) { - if (dfsplain_e( pObj, NULL )) { -#ifdef DEBUG_PRINT_FLOWS - printf("\n\n"); -#endif - flow++; - Abc_NtkForEachObj( pNtk, pObj2, j ) - FUNSET( pObj2, VISITED ); - } - } - } while (flow > last); - - if (fVerbose) vprintf("max-flow2 = %d\n", flow); - - return flow; -} - - -/**Function************************************************************* - - Synopsis [Restores latch boxes.] - - Description [Latchless BI/BO nodes are removed. Latch boxes are - restored around remaining latches.] - - SideEffects [Deletes nodes as appropriate.] - - SeeAlso [] - -***********************************************************************/ -void -Abc_FlowRetime_FixLatchBoxes( Abc_Ntk_t *pNtk, Vec_Ptr_t *vBoxIns ) { - int i; - Abc_Obj_t *pObj, *pBo = NULL, *pBi = NULL; - Vec_Ptr_t *vFreeBi = Vec_PtrAlloc( 100 ); - Vec_Ptr_t *vFreeBo = Vec_PtrAlloc( 100 ); - - // 1. remove empty bi/bo pairs - while(Vec_PtrSize( vBoxIns )) { - pBi = (Abc_Obj_t *)Vec_PtrPop( vBoxIns ); - assert(Abc_ObjIsBi(pBi)); - assert(Abc_ObjFanoutNum(pBi) == 1); - assert(Abc_ObjFaninNum(pBi) == 1); - pBo = Abc_ObjFanout0(pBi); - assert(!Abc_ObjFaninC0(pBo)); - - if (Abc_ObjIsBo(pBo)) { - // an empty bi/bo pair - - Abc_ObjRemoveFanins( pBo ); - // transfer complement from BI, if present - assert(!Abc_ObjIsComplement(Abc_ObjFanin0(pBi))); - Abc_ObjBetterTransferFanout( pBo, Abc_ObjFanin0(pBi), Abc_ObjFaninC0(pBi) ); - - Abc_ObjRemoveFanins( pBi ); - pBi->fCompl0 = 0; - Vec_PtrPush( vFreeBi, pBi ); - Vec_PtrPush( vFreeBo, pBo ); - - // free names - if (Nm_ManFindNameById(pNtk->pManName, Abc_ObjId(pBi))) - Nm_ManDeleteIdName( pNtk->pManName, Abc_ObjId(pBi)); - if (Nm_ManFindNameById(pNtk->pManName, Abc_ObjId(pBo))) - Nm_ManDeleteIdName( pNtk->pManName, Abc_ObjId(pBo)); - - // check for complete detachment - assert(Abc_ObjFaninNum(pBi) == 0); - assert(Abc_ObjFanoutNum(pBi) == 0); - assert(Abc_ObjFaninNum(pBo) == 0); - assert(Abc_ObjFanoutNum(pBo) == 0); - } else assert(Abc_ObjIsLatch(pBo)); - } - - // 2. add bi/bos as necessary for latches - Abc_NtkForEachLatch( pNtk, pObj, i ) { - assert(Abc_ObjFaninNum(pObj) == 1); - if (Abc_ObjFanoutNum(pObj)) - pBo = Abc_ObjFanout0(pObj); - else pBo = NULL; - pBi = Abc_ObjFanin0(pObj); - - // add BO - if (!pBo || !Abc_ObjIsBo(pBo)) { - pBo = (Abc_Obj_t *)Vec_PtrPop( vFreeBo ); - if (Abc_ObjFanoutNum(pObj)) Abc_ObjTransferFanout( pObj, pBo ); - Abc_ObjAddFanin( pBo, pObj ); - } - // add BI - if (!Abc_ObjIsBi(pBi)) { - pBi = (Abc_Obj_t *)Vec_PtrPop( vFreeBi ); - assert(Abc_ObjFaninNum(pBi) == 0); - Abc_ObjAddFanin( pBi, Abc_ObjFanin0(pObj) ); - pBi->fCompl0 = pObj->fCompl0; - Abc_ObjRemoveFanins( pObj ); - Abc_ObjAddFanin( pObj, pBi ); - } - } - - // delete remaining BIs and BOs - while(Vec_PtrSize( vFreeBi )) { - pObj = (Abc_Obj_t *)Vec_PtrPop( vFreeBi ); - Abc_NtkDeleteObj( pObj ); - } - while(Vec_PtrSize( vFreeBo )) { - pObj = (Abc_Obj_t *)Vec_PtrPop( vFreeBo ); - Abc_NtkDeleteObj( pObj ); - } - -#if defined(DEBUG_CHECK) - Abc_NtkForEachObj( pNtk, pObj, i ) { - if (Abc_ObjIsBo(pObj)) { - assert(Abc_ObjFaninNum(pObj) == 1); - assert(Abc_ObjIsLatch(Abc_ObjFanin0(pObj))); - } - if (Abc_ObjIsBi(pObj)) { - assert(Abc_ObjFaninNum(pObj) == 1); - assert(Abc_ObjFanoutNum(pObj) == 1); - assert(Abc_ObjIsLatch(Abc_ObjFanout0(pObj))); - } - if (Abc_ObjIsLatch(pObj)) { - assert(Abc_ObjFanoutNum(pObj) == 1); - assert(Abc_ObjFaninNum(pObj) == 1); - } - } -#endif - - Vec_PtrFree( vFreeBi ); - Vec_PtrFree( vFreeBo ); -} - - -/**Function************************************************************* - - Synopsis [Checks register count along all combinational paths.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void -Abc_FlowRetime_VerifyPathLatencies( Abc_Ntk_t * pNtk ) { - int i; - Abc_Obj_t *pObj; - fPathError = 0; - - vprintf("\t\tVerifying latency along all paths..."); - - Abc_NtkForEachObj( pNtk, pObj, i ) { - if (Abc_ObjIsBo(pObj)) { - Abc_FlowRetime_VerifyPathLatencies_rec( pObj, 0 ); - } else if (!pManMR->fIsForward && Abc_ObjIsPi(pObj)) { - Abc_FlowRetime_VerifyPathLatencies_rec( pObj, 0 ); - } - - if (fPathError) { - if (Abc_ObjFaninNum(pObj) > 0) { - printf("fanin "); - print_node(Abc_ObjFanin0(pObj)); - } - printf("\n"); - exit(0); - } - } - - vprintf(" ok\n"); - - Abc_NtkForEachObj( pNtk, pObj, i ) { - pObj->fMarkA = 0; - pObj->fMarkB = 0; - pObj->fMarkC = 0; - } -} - - -int -Abc_FlowRetime_VerifyPathLatencies_rec( Abc_Obj_t * pObj, int markD ) { - int i, j; - Abc_Obj_t *pNext; - int fCare = 0; - int markC = pObj->fMarkC; - - if (!pObj->fMarkB) { - pObj->fMarkB = 1; // visited - - if (Abc_ObjIsLatch(pObj)) - markC = 1; // latch in output - - if (!pManMR->fIsForward && !Abc_ObjIsPo(pObj) && !Abc_ObjFanoutNum(pObj)) - return -1; // dangling non-PO outputs : don't care what happens - - Abc_ObjForEachFanout( pObj, pNext, i ) { - // reached end of cycle? - if ( Abc_ObjIsBo(pNext) || - (pManMR->fIsForward && Abc_ObjIsPo(pNext)) ) { - if (!markD && !Abc_ObjIsLatch(pObj)) { - printf("\nERROR: no-latch path (end)\n"); - print_node(pNext); - printf("\n"); - fPathError = 1; - } - } else if (!pManMR->fIsForward && Abc_ObjIsPo(pNext)) { - if (markD || Abc_ObjIsLatch(pObj)) { - printf("\nERROR: extra-latch path to outputs\n"); - print_node(pNext); - printf("\n"); - fPathError = 1; - } - } else { - j = Abc_FlowRetime_VerifyPathLatencies_rec( pNext, markD || Abc_ObjIsLatch(pObj) ); - if (j >= 0) { - markC |= j; - fCare = 1; - } - } - - if (fPathError) { - print_node(pObj); - printf("\n"); - return 0; - } - } - } - - if (!fCare) return -1; - - if (markC && markD) { - printf("\nERROR: mult-latch path\n"); - print_node(pObj); - printf("\n"); - fPathError = 1; - } - if (!markC && !markD) { - printf("\nERROR: no-latch path (inter)\n"); - print_node(pObj); - printf("\n"); - fPathError = 1; - } - - return (pObj->fMarkC = markC); -} - - -/**Function************************************************************* - - Synopsis [Copies initial state from latches to BO nodes.] - - Description [Initial states are marked on BO nodes with INIT_0 and - INIT_1 flags in their Flow_Data structures.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void -Abc_FlowRetime_CopyInitState( Abc_Obj_t * pSrc, Abc_Obj_t * pDest ) { - Abc_Obj_t *pObj; - - if (!pManMR->fComputeInitState) return; - - assert(Abc_ObjIsLatch(pSrc)); - assert(Abc_ObjFanin0(pDest) == pSrc); - assert(!Abc_ObjFaninC0(pDest)); - - FUNSET(pDest, INIT_CARE); - if (Abc_LatchIsInit0(pSrc)) { - FSET(pDest, INIT_0); - } else if (Abc_LatchIsInit1(pSrc)) { - FSET(pDest, INIT_1); - } - - if (!pManMR->fIsForward) { - pObj = Abc_ObjData(pSrc); - assert(Abc_ObjIsPi(pObj)); - FDATA(pDest)->pInitObj = pObj; - } -} - - -/**Function************************************************************* - - Synopsis [Implements min-cut.] - - Description [Requires source-reachable nodes to be marked VISITED.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int -Abc_FlowRetime_ImplementCut( Abc_Ntk_t * pNtk ) { - int i, j, cut = 0, unmoved = 0; - Abc_Obj_t *pObj, *pReg, *pNext, *pBo = NULL, *pBi = NULL; - Vec_Ptr_t *vFreeRegs = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) ); - Vec_Ptr_t *vBoxIns = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) ); - Vec_Ptr_t *vMove = Vec_PtrAlloc( 100 ); - - // remove latches from netlist - Abc_NtkForEachLatch( pNtk, pObj, i ) { - pBo = Abc_ObjFanout0(pObj); - pBi = Abc_ObjFanin0(pObj); - assert(Abc_ObjIsBo(pBo) && Abc_ObjIsBi(pBi)); - Vec_PtrPush( vBoxIns, pBi ); - - // copy initial state values to BO - Abc_FlowRetime_CopyInitState( pObj, pBo ); - - // re-use latch elsewhere - Vec_PtrPush( vFreeRegs, pObj ); - FSET(pBo, CROSS_BOUNDARY); - - // cut out of netlist - Abc_ObjPatchFanin( pBo, pObj, pBi ); - Abc_ObjRemoveFanins( pObj ); - - // free name - if (Nm_ManFindNameById(pNtk->pManName, Abc_ObjId(pObj))) - Nm_ManDeleteIdName( pNtk->pManName, Abc_ObjId(pObj)); - } - - // insert latches into netlist - Abc_NtkForEachObj( pNtk, pObj, i ) { - if (Abc_ObjIsLatch( pObj )) continue; - - // a latch is required on every node that lies across the min-cit - assert(!pManMR->fIsForward || !FTEST(pObj, VISITED_E) || FTEST(pObj, VISITED_R)); - if (FTEST(pObj, VISITED_R) && !FTEST(pObj, VISITED_E)) { - assert(FTEST(pObj, FLOW)); - - // count size of cut - cut++; - if ((pManMR->fIsForward && Abc_ObjIsBo(pObj)) || - (!pManMR->fIsForward && Abc_ObjIsBi(pObj))) - unmoved++; - - // only insert latch between fanouts that lie across min-cut - // some fanout paths may be cut at deeper points - Abc_ObjForEachFanout( pObj, pNext, j ) - if (Abc_FlowRetime_IsAcrossCut( pObj, pNext )) - Vec_PtrPush(vMove, pNext); - - // check that move-set is non-zero - if (Vec_PtrSize(vMove) == 0) - print_node(pObj); - assert(Vec_PtrSize(vMove) > 0); - - // insert one of re-useable registers - assert(Vec_PtrSize( vFreeRegs )); - pReg = (Abc_Obj_t *)Vec_PtrPop( vFreeRegs ); - - Abc_ObjAddFanin(pReg, pObj); - while(Vec_PtrSize( vMove )) { - pNext = (Abc_Obj_t *)Vec_PtrPop( vMove ); - Abc_ObjPatchFanin( pNext, pObj, pReg ); - if (Abc_ObjIsBi(pNext)) assert(Abc_ObjFaninNum(pNext) == 1); - - } - if (Abc_ObjIsBi(pObj)) assert(Abc_ObjFaninNum(pObj) == 1); - } - } - -#if defined(DEBUG_CHECK) - Abc_FlowRetime_VerifyPathLatencies( pNtk ); -#endif - - // delete remaining latches - while(Vec_PtrSize( vFreeRegs )) { - pReg = (Abc_Obj_t *)Vec_PtrPop( vFreeRegs ); - Abc_NtkDeleteObj( pReg ); - } - - // update initial states - Abc_FlowRetime_InitState( pNtk ); - - // restore latch boxes - Abc_FlowRetime_FixLatchBoxes( pNtk, vBoxIns ); - - Vec_PtrFree( vFreeRegs ); - Vec_PtrFree( vMove ); - Vec_PtrFree( vBoxIns ); - - vprintf("\t\tmin-cut = %d (unmoved = %d)\n", cut, unmoved); - return cut; -} - - -/**Function************************************************************* - - Synopsis [Adds dummy fanin.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void -Abc_FlowRetime_AddDummyFanin( Abc_Obj_t * pObj ) { - Abc_Ntk_t *pNtk = Abc_ObjNtk( pObj ); - - if (Abc_NtkHasAig(pNtk)) - Abc_ObjAddFanin(pObj, Abc_AigConst1( pNtk )); - else - Abc_ObjAddFanin(pObj, Abc_NtkCreateNodeConst0( pNtk )); -} - - -/**Function************************************************************* - - Synopsis [Prints information about a node.] - - Description [Debuging.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void -print_node(Abc_Obj_t *pObj) { - int i; - Abc_Obj_t * pNext; - char m[6]; - - m[0] = 0; - if (pObj->fMarkA) - strcat(m, "A"); - if (pObj->fMarkB) - strcat(m, "B"); - if (pObj->fMarkC) - strcat(m, "C"); - - printf("node %d type=%d lev=%d tedge=%d (%x%s) fanouts {", Abc_ObjId(pObj), Abc_ObjType(pObj), - pObj->Level, Vec_PtrSize(FTIMEEDGES(pObj)), FDATA(pObj)->mark, m); - Abc_ObjForEachFanout( pObj, pNext, i ) - printf("%d[%d](%d),", Abc_ObjId(pNext), Abc_ObjType(pNext), FDATA(pNext)->mark); - printf("} fanins {"); - Abc_ObjForEachFanin( pObj, pNext, i ) - printf("%d[%d](%d),", Abc_ObjId(pNext), Abc_ObjType(pNext), FDATA(pNext)->mark); - printf("}\n"); -} - -void -print_node2(Abc_Obj_t *pObj) { - int i; - Abc_Obj_t * pNext; - char m[6]; - - m[0] = 0; - if (pObj->fMarkA) - strcat(m, "A"); - if (pObj->fMarkB) - strcat(m, "B"); - if (pObj->fMarkC) - strcat(m, "C"); - - printf("node %d type=%d %s fanouts {", Abc_ObjId(pObj), Abc_ObjType(pObj), m); - Abc_ObjForEachFanout( pObj, pNext, i ) - printf("%d ,", Abc_ObjId(pNext)); - printf("} fanins {"); - Abc_ObjForEachFanin( pObj, pNext, i ) - printf("%d ,", Abc_ObjId(pNext)); - printf("} "); -} - -void -print_node3(Abc_Obj_t *pObj) { - int i; - Abc_Obj_t * pNext; - char m[6]; - - m[0] = 0; - if (pObj->fMarkA) - strcat(m, "A"); - if (pObj->fMarkB) - strcat(m, "B"); - if (pObj->fMarkC) - strcat(m, "C"); - - printf("\nnode %d type=%d mark=%d %s\n", Abc_ObjId(pObj), Abc_ObjType(pObj), FDATA(pObj)->mark, m); - printf("fanouts\n"); - Abc_ObjForEachFanout( pObj, pNext, i ) { - print_node(pNext); - printf("\n"); - } - printf("fanins\n"); - Abc_ObjForEachFanin( pObj, pNext, i ) { - print_node(pNext); - printf("\n"); - } -} - - -/**Function************************************************************* - - Synopsis [Transfers fanout.] - - Description [Does not produce an error if there is no fanout. - Complements as necessary.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void -Abc_ObjBetterTransferFanout( Abc_Obj_t * pFrom, Abc_Obj_t * pTo, int compl ) { - Abc_Obj_t *pNext; - - while(Abc_ObjFanoutNum(pFrom) > 0) { - pNext = Abc_ObjFanout0(pFrom); - Abc_ObjPatchFanin( pNext, pFrom, Abc_ObjNotCond(pTo, compl) ); - } -} - - -/**Function************************************************************* - - Synopsis [Returns true is a connection spans the min-cut.] - - Description [pNext is a direct fanout of pObj.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool -Abc_FlowRetime_IsAcrossCut( Abc_Obj_t *pObj, Abc_Obj_t *pNext ) { - - if (FTEST(pObj, VISITED_R) && !FTEST(pObj, VISITED_E)) { - if (pManMR->fIsForward) { - if (!FTEST(pNext, VISITED_R) || - (FTEST(pNext, BLOCK_OR_CONS) & pManMR->constraintMask)|| - FTEST(pNext, CROSS_BOUNDARY) || - Abc_ObjIsLatch(pNext)) - return 1; - } else { - if (FTEST(pNext, VISITED_E) || - FTEST(pNext, CROSS_BOUNDARY)) - return 1; - } - } - - return 0; -} - - -/**Function************************************************************* - - Synopsis [Resets flow problem] - - Description [If fClearAll is true, all marks will be cleared; this is - typically appropriate after the circuit structure has - been modified.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_ClearFlows( bool fClearAll ) { - int i; - - if (fClearAll) - memset(pManMR->pDataArray, 0, sizeof(Flow_Data_t)*pManMR->nNodes); - else { - // clear only data related to flow problem - for(i=0; i<pManMR->nNodes; i++) { - pManMR->pDataArray[i].mark &= ~(VISITED | FLOW ); - pManMR->pDataArray[i].e_dist = 0; - pManMR->pDataArray[i].r_dist = 0; - pManMR->pDataArray[i].pred = NULL; - } - } -} diff --git a/src/opt/fret/fretTime.c b/src/opt/fret/fretTime.c deleted file mode 100644 index f497df60..00000000 --- a/src/opt/fret/fretTime.c +++ /dev/null @@ -1,763 +0,0 @@ -/**CFile**************************************************************** - - FileName [fretTime.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Flow-based retiming package.] - - Synopsis [Delay-constrained retiming code.] - - Author [Aaron Hurst] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 1, 2008.] - - Revision [$Id: fretTime.c,v 1.00 2008/01/01 00:00:00 ahurst Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "vec.h" -#include "fretime.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Abc_FlowRetime_Dfs_forw( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes ); -static void Abc_FlowRetime_Dfs_back( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes ); - -static void Abc_FlowRetime_ConstrainExact_forw( Abc_Obj_t * pObj ); -static void Abc_FlowRetime_ConstrainExact_back( Abc_Obj_t * pObj ); -static void Abc_FlowRetime_ConstrainConserv_forw( Abc_Ntk_t * pNtk ); -static void Abc_FlowRetime_ConstrainConserv_back( Abc_Ntk_t * pNtk ); - - -void trace2(Abc_Obj_t *pObj) { - Abc_Obj_t *pNext; - int i; - - print_node(pObj); - Abc_ObjForEachFanin(pObj, pNext, i) - if (pNext->Level >= pObj->Level - 1) { - trace2(pNext); - break; - } -} - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - - -/**Function************************************************************* - - Synopsis [Initializes timing] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_InitTiming( Abc_Ntk_t *pNtk ) { - - pManMR->nConservConstraints = pManMR->nExactConstraints = 0; - - pManMR->vExactNodes = Vec_PtrAlloc(1000); - - pManMR->vTimeEdges = ALLOC( Vec_Ptr_t, Abc_NtkObjNumMax(pNtk)+1 ); - assert(pManMR->vTimeEdges); - memset(pManMR->vTimeEdges, 0, (Abc_NtkObjNumMax(pNtk)+1) * sizeof(Vec_Ptr_t) ); -} - - -/**Function************************************************************* - - Synopsis [Marks nodes with conservative constraints.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_ConstrainConserv( Abc_Ntk_t * pNtk ) { - Abc_Obj_t *pObj; - int i; - void *pArray; - - // clear all exact constraints - pManMR->nExactConstraints = 0; - while( Vec_PtrSize( pManMR->vExactNodes )) { - pObj = Vec_PtrPop( pManMR->vExactNodes ); - - if ( Vec_PtrSize( FTIMEEDGES(pObj) )) { - pArray = Vec_PtrReleaseArray( FTIMEEDGES(pObj) ); - FREE( pArray ); - } - } - -#if !defined(IGNORE_TIMING) - if (pManMR->fIsForward) { - Abc_FlowRetime_ConstrainConserv_forw(pNtk); - } else { - Abc_FlowRetime_ConstrainConserv_back(pNtk); - } -#endif - - Abc_NtkForEachObj( pNtk, pObj, i) - assert( !Vec_PtrSize(FTIMEEDGES(pObj)) ); -} - - -void Abc_FlowRetime_ConstrainConserv_forw( Abc_Ntk_t * pNtk ) { - Vec_Ptr_t *vNodes = pManMR->vNodes; - Abc_Obj_t *pObj, *pNext, *pBi, *pBo; - int i, j; - - assert(!Vec_PtrSize( vNodes )); - pManMR->nConservConstraints = 0; - - // 1. hard constraints - - // (i) collect TFO of PIs - Abc_NtkIncrementTravId(pNtk); - Abc_NtkForEachPi(pNtk, pObj, i) - Abc_FlowRetime_Dfs_forw( pObj, vNodes ); - - // ... propagate values - Vec_PtrForEachEntryReverse(vNodes, pObj, i) { - pObj->Level = 0; - Abc_ObjForEachFanin( pObj, pNext, j ) - { - if ( Abc_NodeIsTravIdCurrent(pNext) && - pObj->Level < pNext->Level ) - pObj->Level = pNext->Level; - } - pObj->Level += Abc_ObjIsNode(pObj) ? 1 : 0; - - if ( Abc_ObjIsBi(pObj) ) - pObj->fMarkA = 1; - - assert(pObj->Level <= pManMR->maxDelay); - } - - // collect TFO of latches - // seed arrival times from BIs - Vec_PtrClear(vNodes); - Abc_NtkIncrementTravId(pNtk); - Abc_NtkForEachLatch(pNtk, pObj, i) { - pBo = Abc_ObjFanout0( pObj ); - pBi = Abc_ObjFanin0( pObj ); - - Abc_NodeSetTravIdCurrent( pObj ); - Abc_FlowRetime_Dfs_forw( pBo, vNodes ); - - if (pBi->fMarkA) { - pBi->fMarkA = 0; - pObj->Level = pBi->Level; - assert(pObj->Level <= pManMR->maxDelay); - } else - pObj->Level = 0; - } - -#if defined(DEBUG_CHECK) - // DEBUG: check DFS ordering - Vec_PtrForEachEntryReverse(vNodes, pObj, i) { - pObj->fMarkB = 1; - - Abc_ObjForEachFanin( pObj, pNext, j ) - if ( Abc_NodeIsTravIdCurrent(pNext) && !Abc_ObjIsLatch(pNext)) - assert(pNext->fMarkB); - } - Vec_PtrForEachEntryReverse(vNodes, pObj, i) - pObj->fMarkB = 0; -#endif - - // ... propagate values - Vec_PtrForEachEntryReverse(vNodes, pObj, i) { - pObj->Level = 0; - Abc_ObjForEachFanin( pObj, pNext, j ) - { - if ( Abc_NodeIsTravIdCurrent(pNext) && - pObj->Level < pNext->Level ) - pObj->Level = pNext->Level; - } - pObj->Level += Abc_ObjIsNode(pObj) ? 1 : 0; - - if (pObj->Level > pManMR->maxDelay) { - FSET(pObj, BLOCK); - } - } - - // 2. conservative constraints - - // first pass: seed latches with T=0 - Abc_NtkForEachLatch(pNtk, pObj, i) { - pObj->Level = 0; - } - - // ... propagate values - Vec_PtrForEachEntryReverse(vNodes, pObj, i) { - pObj->Level = 0; - Abc_ObjForEachFanin( pObj, pNext, j ) { - if ( Abc_NodeIsTravIdCurrent(pNext) && - pObj->Level < pNext->Level ) - pObj->Level = pNext->Level; - } - pObj->Level += Abc_ObjIsNode(pObj) ? 1 : 0; - - if ( Abc_ObjIsBi(pObj) ) - pObj->fMarkA = 1; - - assert(pObj->Level <= pManMR->maxDelay); - } - - Abc_NtkForEachLatch(pNtk, pObj, i) { - pBo = Abc_ObjFanout0( pObj ); - pBi = Abc_ObjFanin0( pObj ); - - if (pBi->fMarkA) { - pBi->fMarkA = 0; - pObj->Level = pBi->Level; - assert(pObj->Level <= pManMR->maxDelay); - } else - pObj->Level = 0; - } - - // ... propagate values - Vec_PtrForEachEntryReverse(vNodes, pObj, i) { - pObj->Level = 0; - Abc_ObjForEachFanin( pObj, pNext, j ) { - if ( Abc_NodeIsTravIdCurrent(pNext) && - pObj->Level < pNext->Level ) - pObj->Level = pNext->Level; - } - pObj->Level += Abc_ObjIsNode(pObj) ? 1 : 0; - - // constrained? - if (pObj->Level > pManMR->maxDelay) { - FSET( pObj, CONSERVATIVE ); - pManMR->nConservConstraints++; - } else - FUNSET( pObj, CONSERVATIVE ); - } - - Vec_PtrClear( vNodes ); -} - - -void Abc_FlowRetime_ConstrainConserv_back( Abc_Ntk_t * pNtk ) { - Vec_Ptr_t *vNodes = pManMR->vNodes; - Abc_Obj_t *pObj, *pNext, *pBi, *pBo; - int i, j, l; - - assert(!Vec_PtrSize(vNodes)); - - pManMR->nConservConstraints = 0; - - // 1. hard constraints - - // (i) collect TFO of POs - Abc_NtkIncrementTravId(pNtk); - Abc_NtkForEachPo(pNtk, pObj, i) - Abc_FlowRetime_Dfs_back( pObj, vNodes ); - - // ... propagate values - Vec_PtrForEachEntryReverse(vNodes, pObj, i) { - pObj->Level = 0; - Abc_ObjForEachFanout( pObj, pNext, j ) - { - l = pNext->Level + (Abc_ObjIsNode(pObj) ? 1 : 0); - if ( Abc_NodeIsTravIdCurrent(pNext) && - pObj->Level < l ) - pObj->Level = l; - } - - if ( Abc_ObjIsBo(pObj) ) - pObj->fMarkA = 1; - - assert(pObj->Level <= pManMR->maxDelay); - } - - // collect TFO of latches - // seed arrival times from BIs - Vec_PtrClear(vNodes); - Abc_NtkIncrementTravId(pNtk); - Abc_NtkForEachLatch(pNtk, pObj, i) { - pBo = Abc_ObjFanout0( pObj ); - pBi = Abc_ObjFanin0( pObj ); - - Abc_NodeSetTravIdCurrent( pObj ); - Abc_FlowRetime_Dfs_back( pBi, vNodes ); - - if (pBo->fMarkA) { - pBo->fMarkA = 0; - pObj->Level = pBo->Level; - assert(pObj->Level <= pManMR->maxDelay); - } else - pObj->Level = 0; - } - -#if defined(DEBUG_CHECK) - // DEBUG: check DFS ordering - Vec_PtrForEachEntryReverse(vNodes, pObj, i) { - pObj->fMarkB = 1; - - Abc_ObjForEachFanout( pObj, pNext, j ) - if ( Abc_NodeIsTravIdCurrent(pNext) && !Abc_ObjIsLatch(pNext)) - assert(pNext->fMarkB); - } - Vec_PtrForEachEntryReverse(vNodes, pObj, i) - pObj->fMarkB = 0; -#endif - - // ... propagate values - Vec_PtrForEachEntryReverse(vNodes, pObj, i) { - pObj->Level = 0; - Abc_ObjForEachFanout( pObj, pNext, j ) - { - l = pNext->Level + (Abc_ObjIsNode(pObj) ? 1 : 0); - if ( Abc_NodeIsTravIdCurrent(pNext) && - pObj->Level < l ) - pObj->Level = l; - } - - if (pObj->Level + (Abc_ObjIsNode(pObj)?1:0) > pManMR->maxDelay) { - FSET(pObj, BLOCK); - } - } - - // 2. conservative constraints - - // first pass: seed latches with T=0 - Abc_NtkForEachLatch(pNtk, pObj, i) { - pObj->Level = 0; - } - - // ... propagate values - Vec_PtrForEachEntryReverse(vNodes, pObj, i) { - pObj->Level = 0; - Abc_ObjForEachFanout( pObj, pNext, j ) { - l = pNext->Level + (Abc_ObjIsNode(pObj) ? 1 : 0); - if ( Abc_NodeIsTravIdCurrent(pNext) && - pObj->Level < l ) - pObj->Level = l; - } - - if ( Abc_ObjIsBo(pObj) ) { - pObj->fMarkA = 1; - } - - assert(pObj->Level <= pManMR->maxDelay); - } - - Abc_NtkForEachLatch(pNtk, pObj, i) { - pBo = Abc_ObjFanout0( pObj ); - assert(Abc_ObjIsBo(pBo)); - pBi = Abc_ObjFanin0( pObj ); - assert(Abc_ObjIsBi(pBi)); - - if (pBo->fMarkA) { - pBo->fMarkA = 0; - pObj->Level = pBo->Level; - } else - pObj->Level = 0; - } - - // ... propagate values - Vec_PtrForEachEntryReverse(vNodes, pObj, i) { - pObj->Level = 0; - Abc_ObjForEachFanout( pObj, pNext, j ) { - l = pNext->Level + (Abc_ObjIsNode(pObj) ? 1 : 0); - if ( Abc_NodeIsTravIdCurrent(pNext) && - pObj->Level < l ) - pObj->Level = l; - } - - // constrained? - if (pObj->Level > pManMR->maxDelay) { - FSET( pObj, CONSERVATIVE ); - pManMR->nConservConstraints++; - } else - FUNSET( pObj, CONSERVATIVE ); - } - - Vec_PtrClear( vNodes ); -} - - -/**Function************************************************************* - - Synopsis [Introduces exact timing constraints for a node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_ConstrainExact( Abc_Obj_t * pObj ) { - - if (FTEST( pObj, CONSERVATIVE )) { - pManMR->nConservConstraints--; - FUNSET( pObj, CONSERVATIVE ); - } - -#if !defined(IGNORE_TIMING) - if (pManMR->fIsForward) { - Abc_FlowRetime_ConstrainExact_forw(pObj); - } else { - Abc_FlowRetime_ConstrainExact_back(pObj); - } -#endif -} - -void Abc_FlowRetime_ConstrainExact_forw_rec( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes, int latch ) { - Abc_Obj_t *pNext; - int i; - - // terminate? - if (Abc_ObjIsLatch(pObj)) { - if (latch) return; - latch = 1; - } - - // already visited? - if (!latch) { - if (pObj->fMarkA) return; - pObj->fMarkA = 1; - } else { - if (pObj->fMarkB) return; - pObj->fMarkB = 1; - } - - // recurse - Abc_ObjForEachFanin(pObj, pNext, i) { - Abc_FlowRetime_ConstrainExact_forw_rec( pNext, vNodes, latch ); - } - - // add - pObj->Level = 0; - Vec_PtrPush(vNodes, Abc_ObjNotCond(pObj, latch)); -} - -void Abc_FlowRetime_ConstrainExact_forw( Abc_Obj_t * pObj ) { - Vec_Ptr_t *vNodes = pManMR->vNodes; - Abc_Obj_t *pNext, *pCur, *pReg; - // Abc_Ntk_t *pNtk = pManMR->pNtk; - int i, j; - - assert( !Vec_PtrSize(vNodes) ); - assert( !Abc_ObjIsLatch(pObj) ); - assert( !Vec_PtrSize( FTIMEEDGES(pObj) )); - Vec_PtrPush( pManMR->vExactNodes, pObj ); - - // rev topo order - Abc_FlowRetime_ConstrainExact_forw_rec( pObj, vNodes, 0 ); - - Vec_PtrForEachEntryReverse( vNodes, pCur, i) { - pReg = Abc_ObjRegular( pCur ); - - if (pReg == pCur) { - assert(!Abc_ObjIsLatch(pReg)); - Abc_ObjForEachFanin(pReg, pNext, j) - pNext->Level = MAX( pNext->Level, pReg->Level + (Abc_ObjIsNode(pReg)?1:0)); - assert(pReg->Level <= pManMR->maxDelay); - pReg->Level = 0; - pReg->fMarkA = pReg->fMarkB = 0; - } - } - Vec_PtrForEachEntryReverse( vNodes, pCur, i) { - pReg = Abc_ObjRegular( pCur ); - if (pReg != pCur) { - Abc_ObjForEachFanin(pReg, pNext, j) - if (!Abc_ObjIsLatch(pNext)) - pNext->Level = MAX( pNext->Level, pReg->Level + (Abc_ObjIsNode(pReg)?1:0)); - - if (pReg->Level == pManMR->maxDelay) { - Vec_PtrPush( FTIMEEDGES(pObj), pReg); - pManMR->nExactConstraints++; - } - pReg->Level = 0; - pReg->fMarkA = pReg->fMarkB = 0; - } - } - - Vec_PtrClear( vNodes ); -} - -void Abc_FlowRetime_ConstrainExact_back_rec( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes, int latch ) { - Abc_Obj_t *pNext; - int i; - - // terminate? - if (Abc_ObjIsLatch(pObj)) { - if (latch) return; - latch = 1; - } - - // already visited? - if (!latch) { - if (pObj->fMarkA) return; - pObj->fMarkA = 1; - } else { - if (pObj->fMarkB) return; - pObj->fMarkB = 1; - } - - // recurse - Abc_ObjForEachFanout(pObj, pNext, i) { - Abc_FlowRetime_ConstrainExact_back_rec( pNext, vNodes, latch ); - } - - // add - pObj->Level = 0; - Vec_PtrPush(vNodes, Abc_ObjNotCond(pObj, latch)); -} - - -void Abc_FlowRetime_ConstrainExact_back( Abc_Obj_t * pObj ) { - Vec_Ptr_t *vNodes = pManMR->vNodes; - Abc_Obj_t *pNext, *pCur, *pReg; - // Abc_Ntk_t *pNtk = pManMR->pNtk; - int i, j; - - assert( !Vec_PtrSize( vNodes )); - assert( !Abc_ObjIsLatch(pObj) ); - assert( !Vec_PtrSize( FTIMEEDGES(pObj) )); - Vec_PtrPush( pManMR->vExactNodes, pObj ); - - // rev topo order - Abc_FlowRetime_ConstrainExact_back_rec( pObj, vNodes, 0 ); - - Vec_PtrForEachEntryReverse( vNodes, pCur, i) { - pReg = Abc_ObjRegular( pCur ); - - if (pReg == pCur) { - assert(!Abc_ObjIsLatch(pReg)); - Abc_ObjForEachFanout(pReg, pNext, j) - pNext->Level = MAX( pNext->Level, pReg->Level + (Abc_ObjIsNode(pReg)?1:0)); - assert(pReg->Level <= pManMR->maxDelay); - pReg->Level = 0; - pReg->fMarkA = pReg->fMarkB = 0; - } - } - Vec_PtrForEachEntryReverse( vNodes, pCur, i) { - pReg = Abc_ObjRegular( pCur ); - if (pReg != pCur) { - Abc_ObjForEachFanout(pReg, pNext, j) - if (!Abc_ObjIsLatch(pNext)) - pNext->Level = MAX( pNext->Level, pReg->Level + (Abc_ObjIsNode(pReg)?1:0)); - - if (pReg->Level == pManMR->maxDelay) { - Vec_PtrPush( FTIMEEDGES(pObj), pReg); - pManMR->nExactConstraints++; - } - pReg->Level = 0; - pReg->fMarkA = pReg->fMarkB = 0; - } - } - - Vec_PtrClear( vNodes ); -} - - -/**Function************************************************************* - - Synopsis [Introduces all exact timing constraints in a network] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_ConstrainExactAll( Abc_Ntk_t * pNtk ) { - int i; - Abc_Obj_t *pObj; - void *pArray; - - // free existing constraints - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( Vec_PtrSize( FTIMEEDGES(pObj) )) { - pArray = Vec_PtrReleaseArray( FTIMEEDGES(pObj) ); - FREE( pArray ); - } - pManMR->nExactConstraints = 0; - - // generate all constraints - Abc_NtkForEachObj(pNtk, pObj, i) - if (!Abc_ObjIsLatch(pObj) && FTEST( pObj, CONSERVATIVE ) && !FTEST( pObj, BLOCK )) - if (!Vec_PtrSize( FTIMEEDGES( pObj ) )) - Abc_FlowRetime_ConstrainExact( pObj ); -} - - - -/**Function************************************************************* - - Synopsis [Deallocates exact constraints.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_FreeTiming( Abc_Ntk_t *pNtk ) { - Abc_Obj_t *pObj; - void *pArray; - - while( Vec_PtrSize( pManMR->vExactNodes )) { - pObj = Vec_PtrPop( pManMR->vExactNodes ); - - if ( Vec_PtrSize( FTIMEEDGES(pObj) )) { - pArray = Vec_PtrReleaseArray( FTIMEEDGES(pObj) ); - FREE( pArray ); - } - } - - Vec_PtrFree(pManMR->vExactNodes); - FREE( pManMR->vTimeEdges ); -} - - -/**Function************************************************************* - - Synopsis [DFS order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_FlowRetime_Dfs_forw( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes ) { - Abc_Obj_t *pNext; - int i; - - if (Abc_ObjIsLatch(pObj)) return; - - Abc_NodeSetTravIdCurrent( pObj ); - - Abc_ObjForEachFanout( pObj, pNext, i ) - if (!Abc_NodeIsTravIdCurrent( pNext )) - Abc_FlowRetime_Dfs_forw( pNext, vNodes ); - - Vec_PtrPush( vNodes, pObj ); -} - - -void Abc_FlowRetime_Dfs_back( Abc_Obj_t * pObj, Vec_Ptr_t *vNodes ) { - Abc_Obj_t *pNext; - int i; - - if (Abc_ObjIsLatch(pObj)) return; - - Abc_NodeSetTravIdCurrent( pObj ); - - Abc_ObjForEachFanin( pObj, pNext, i ) - if (!Abc_NodeIsTravIdCurrent( pNext )) - Abc_FlowRetime_Dfs_back( pNext, vNodes ); - - Vec_PtrPush( vNodes, pObj ); -} - - -/**Function************************************************************* - - Synopsis [Main timing-constrained routine.] - - Description [Refines constraints that are limiting area improvement. - These are identified by computing - the min-cuts both with and without the conservative - constraints: these two situation represent an - over- and under-constrained version of the timing.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Abc_FlowRetime_RefineConstraints( ) { - Abc_Ntk_t *pNtk = pManMR->pNtk; - int i, flow, count = 0; - Abc_Obj_t *pObj; - int maxTighten = 99999; - - vprintf("\t\tsubiter %d : constraints = {cons, exact} = %d, %d\n", - pManMR->subIteration, pManMR->nConservConstraints, pManMR->nExactConstraints); - - // 1. overconstrained - pManMR->constraintMask = BLOCK | CONSERVATIVE; - vprintf("\t\trefinement: over "); - fflush(stdout); - flow = Abc_FlowRetime_PushFlows( pNtk, 0 ); - vprintf("= %d ", flow); - - // remember nodes - if (pManMR->fIsForward) { - Abc_NtkForEachObj( pNtk, pObj, i ) - if (!FTEST(pObj, VISITED_R)) - pObj->fMarkC = 1; - } else { - Abc_NtkForEachObj( pNtk, pObj, i ) - if (!FTEST(pObj, VISITED_E)) - pObj->fMarkC = 1; - } - - if (pManMR->fConservTimingOnly) { - vprintf(" done\n"); - return 0; - } - - // 2. underconstrained - pManMR->constraintMask = BLOCK; - Abc_FlowRetime_ClearFlows( 0 ); - vprintf("under = "); - fflush(stdout); - flow = Abc_FlowRetime_PushFlows( pNtk, 0 ); - vprintf("%d refined nodes = ", flow); - fflush(stdout); - - // find area-limiting constraints - if (pManMR->fIsForward) { - Abc_NtkForEachObj( pNtk, pObj, i ) { - if (pObj->fMarkC && - FTEST(pObj, VISITED_R) && - FTEST(pObj, CONSERVATIVE) && - count < maxTighten) { - count++; - Abc_FlowRetime_ConstrainExact( pObj ); - } - pObj->fMarkC = 0; - } - } else { - Abc_NtkForEachObj( pNtk, pObj, i ) { - if (pObj->fMarkC && - FTEST(pObj, VISITED_E) && - FTEST(pObj, CONSERVATIVE) && - count < maxTighten) { - count++; - Abc_FlowRetime_ConstrainExact( pObj ); - } - pObj->fMarkC = 0; - } - } - - vprintf("%d\n", count); - - return (count > 0); -} - - diff --git a/src/opt/fret/fretime.h b/src/opt/fret/fretime.h deleted file mode 100644 index 167543ce..00000000 --- a/src/opt/fret/fretime.h +++ /dev/null @@ -1,165 +0,0 @@ -/**CFile**************************************************************** - - FileName [fretime.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Flow-based retiming package.] - - Synopsis [Header file for retiming package.] - - Author [Aaron Hurst] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 1, 2008.] - - Revision [$Id: fretime.h,v 1.00 2008/01/01 00:00:00 ahurst Exp $] - -***********************************************************************/ - -#if !defined(RETIME_H_) -#define RETIME_H_ - -#include "abc.h" - -// #define IGNORE_TIMING -// #define DEBUG_PRINT_FLOWS -// #define DEBUG_VISITED -// #define DEBUG_PREORDER -// #define DEBUG_CHECK - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define MAX_DIST 30000 - -// flags in Flow_Data structure... -#define VISITED_E 0x01 -#define VISITED_R 0x02 -#define VISITED (VISITED_E | VISITED_R) -#define FLOW 0x04 -#define CROSS_BOUNDARY 0x08 -#define BLOCK 0x10 -#define INIT_0 0x20 -#define INIT_1 0x40 -#define INIT_CARE (INIT_0 | INIT_1) -#define CONSERVATIVE 0x80 -#define BLOCK_OR_CONS (BLOCK | CONSERVATIVE) - -typedef struct Flow_Data_t_ { - unsigned int mark : 16; - - union { - Abc_Obj_t *pred; - /* unsigned int var; */ - Abc_Obj_t *pInitObj; - Vec_Ptr_t *vNodes; - }; - - unsigned int e_dist : 16; - unsigned int r_dist : 16; -} Flow_Data_t; - -// useful macros for manipulating Flow_Data structure... -#define FDATA( x ) ((Flow_Data_t *)Abc_ObjCopy(x)) -#define FSET( x, y ) ((Flow_Data_t *)Abc_ObjCopy(x))->mark |= y -#define FUNSET( x, y ) ((Flow_Data_t *)Abc_ObjCopy(x))->mark &= ~y -#define FTEST( x, y ) (((Flow_Data_t *)Abc_ObjCopy(x))->mark & y) -#define FTIMEEDGES( x ) &(pManMR->vTimeEdges[Abc_ObjId( x )]) - -static inline void FSETPRED(Abc_Obj_t *pObj, Abc_Obj_t *pPred) { - assert(!Abc_ObjIsLatch(pObj)); // must preserve field to maintain init state linkage - FDATA(pObj)->pred = pPred; -} -static inline Abc_Obj_t * FGETPRED(Abc_Obj_t *pObj) { - return FDATA(pObj)->pred; -} - - -typedef struct MinRegMan_t_ { - - // problem description: - int maxDelay; - bool fComputeInitState, fGuaranteeInitState; - int nNodes, nLatches; - bool fForwardOnly, fBackwardOnly; - bool fConservTimingOnly; - int nMaxIters; - bool fVerbose; - Abc_Ntk_t *pNtk; - - int nPreRefine; - - // problem state - bool fIsForward; - bool fSinkDistTerminate; - int nExactConstraints, nConservConstraints; - int fSolutionIsDc; - int constraintMask; - int iteration, subIteration; - - // problem data - Vec_Int_t *vSinkDistHist; - Flow_Data_t *pDataArray; - Vec_Ptr_t *vTimeEdges; - Vec_Ptr_t *vExactNodes; - Abc_Ntk_t *pInitNtk; - Vec_Ptr_t *vNodes; // re-useable struct - -} MinRegMan_t ; - -#define vprintf if (pManMR->fVerbose) printf - -/*=== fretMain.c ==========================================================*/ - -extern MinRegMan_t *pManMR; - -Abc_Ntk_t * Abc_FlowRetime_MinReg( Abc_Ntk_t * pNtk, int fVerbose, int fComputeInitState, - int fForward, int fBackward, int nMaxIters, - int maxDelay, int fFastButConservative); - -void print_node(Abc_Obj_t *pObj); - -void Abc_ObjBetterTransferFanout( Abc_Obj_t * pFrom, Abc_Obj_t * pTo, int compl ); - -int Abc_FlowRetime_PushFlows( Abc_Ntk_t * pNtk, bool fVerbose ); -bool Abc_FlowRetime_IsAcrossCut( Abc_Obj_t *pCur, Abc_Obj_t *pNext ); -void Abc_FlowRetime_ClearFlows( bool fClearAll ); - -/*=== fretFlow.c ==========================================================*/ - -int dfsplain_e( Abc_Obj_t *pObj, Abc_Obj_t *pPred ); -int dfsplain_r( Abc_Obj_t *pObj, Abc_Obj_t *pPred ); - -void dfsfast_preorder( Abc_Ntk_t *pNtk ); -int dfsfast_e( Abc_Obj_t *pObj, Abc_Obj_t *pPred ); -int dfsfast_r( Abc_Obj_t *pObj, Abc_Obj_t *pPred ); - -/*=== fretInit.c ==========================================================*/ - -void Abc_FlowRetime_PrintInitStateInfo( Abc_Ntk_t * pNtk ); - -void Abc_FlowRetime_InitState( Abc_Ntk_t * pNtk ); - -void Abc_FlowRetime_UpdateForwardInit( Abc_Ntk_t * pNtk ); -void Abc_FlowRetime_UpdateBackwardInit( Abc_Ntk_t * pNtk ); - -void Abc_FlowRetime_SetupBackwardInit( Abc_Ntk_t * pNtk ); -int Abc_FlowRetime_SolveBackwardInit( Abc_Ntk_t * pNtk ); - -void Abc_FlowRetime_ConstrainInit( ); - -/*=== fretTime.c ==========================================================*/ - -void Abc_FlowRetime_InitTiming( Abc_Ntk_t *pNtk ); -void Abc_FlowRetime_FreeTiming( Abc_Ntk_t *pNtk ); - -bool Abc_FlowRetime_RefineConstraints( ); - -void Abc_FlowRetime_ConstrainConserv( Abc_Ntk_t * pNtk ); -void Abc_FlowRetime_ConstrainExact( Abc_Obj_t * pObj ); -void Abc_FlowRetime_ConstrainExactAll( Abc_Ntk_t * pNtk ); - -#endif diff --git a/src/opt/fret/module.make b/src/opt/fret/module.make deleted file mode 100644 index fda6a73d..00000000 --- a/src/opt/fret/module.make +++ /dev/null @@ -1,5 +0,0 @@ -SRC += src/opt/fret/fretMain.c \ - src/opt/fret/fretFlow.c \ - src/opt/fret/fretInit.c \ - src/opt/fret/fretTime.c - diff --git a/src/opt/fxu/fxu.c b/src/opt/fxu/fxu.c index d11fd793..46f7ca1a 100644 --- a/src/opt/fxu/fxu.c +++ b/src/opt/fxu/fxu.c @@ -17,6 +17,7 @@ ***********************************************************************/ #include "fxuInt.h" +//#include "mvc.h" #include "fxu.h" //////////////////////////////////////////////////////////////////////// @@ -31,7 +32,7 @@ static int s_MemoryTotal; static int s_MemoryPeak; //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -58,7 +59,6 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) Fxu_Single * pSingle; Fxu_Double * pDouble; int Weight1, Weight2, Weight3; - int Counter = 0; s_MemoryTotal = 0; s_MemoryPeak = 0; @@ -78,7 +78,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) { Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); if ( pData->fVerbose ) - printf( "Div %5d : Best single = %5d.\r", Counter++, Weight1 ); + printf( "Best single = %3d.\n", Weight1 ); if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 ) Fxu_UpdateSingle( p ); else @@ -93,7 +93,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) { Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); if ( pData->fVerbose ) - printf( "Div %5d : Best double = %5d.\r", Counter++, Weight2 ); + printf( "Best double = %3d.\n", Weight2 ); if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 ) Fxu_UpdateDouble( p ); else @@ -110,7 +110,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); if ( pData->fVerbose ) - printf( "Div %5d : Best double = %5d. Best single = %5d.\r", Counter++, Weight2, Weight1 ); + printf( "Best double = %3d. Best single = %3d.\n", Weight2, Weight1 ); //Fxu_Select( p, &pSingle, &pDouble ); if ( Weight1 >= Weight2 ) @@ -141,8 +141,8 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) // select the best single and double Weight3 = Fxu_Select( p, &pSingle, &pDouble ); if ( pData->fVerbose ) - printf( "Div %5d : Best double = %5d. Best single = %5d. Best complement = %5d.\r", - Counter++, Weight2, Weight1, Weight3 ); + printf( "Best double = %3d. Best single = %3d. Best complement = %3d.\n", + Weight2, Weight1, Weight3 ); if ( Weight3 > 0 || Weight3 == 0 && pData->fUse0 ) Fxu_Update( p, pSingle, pDouble ); @@ -153,14 +153,13 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) } if ( pData->fVerbose ) - printf( "Total single = %3d. Total double = %3d. Total compl = %3d. \n", - p->nDivs1, p->nDivs2, p->nDivs3 ); + printf( "Total single = %3d. Total double = %3d. Total compl = %3d.\n", p->nDivs1, p->nDivs2, p->nDivs3 ); // create the new covers if ( pData->nNodesNew ) Fxu_CreateCovers( p, pData ); Fxu_MatrixDelete( p ); -// printf( "Memory usage after deallocation: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak ); +// printf( "Memory usage after delocation: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak ); if ( pData->nNodesNew == pData->nNodesExt ) printf( "Warning: The limit on the number of extracted divisors has been reached.\n" ); return pData->nNodesNew; diff --git a/src/opt/fxu/fxu.h b/src/opt/fxu/fxu.h index e6d0b69e..e9f63ea3 100644 --- a/src/opt/fxu/fxu.h +++ b/src/opt/fxu/fxu.h @@ -19,10 +19,6 @@ #ifndef __FXU_H__ #define __FXU_H__ -#ifdef __cplusplus -extern "C" { -#endif - //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -37,11 +33,9 @@ extern "C" { /// STRUCTURE DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -#ifndef __cplusplus #ifndef bool #define bool int #endif -#endif typedef struct FxuDataStruct Fxu_Data_t; @@ -55,8 +49,7 @@ struct FxuDataStruct bool fUseCompl; // set to 1 to have complement taken into account bool fVerbose; // set to 1 to have verbose output int nNodesExt; // the number of divisors to extract - int nSingleMax; // the max number of single-cube divisors to consider - int nPairsMax; // the max number of double-cube divisors to consider + int nPairsMax; // the maximum number of cube pairs to consider // the input information Vec_Ptr_t * vSops; // the SOPs for each node in the network Vec_Ptr_t * vFanins; // the fanins of each node in the network @@ -71,23 +64,19 @@ struct FxuDataStruct }; //////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// +/// MACRO DEFITIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /*===== fxu.c ==========================================================*/ extern int Fxu_FastExtract( Fxu_Data_t * pData ); -#ifdef __cplusplus -} -#endif - -#endif - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +#endif + diff --git a/src/opt/fxu/fxuCreate.c b/src/opt/fxu/fxuCreate.c index 55026b27..b061f53d 100644 --- a/src/opt/fxu/fxuCreate.c +++ b/src/opt/fxu/fxuCreate.c @@ -24,16 +24,16 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Int_t * vFanins, int * pOrder ); +static void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Fan_t * vFanins, int * pOrder ); static int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY ); static void Fxu_CreateCoversNode( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode, Fxu_Cube * pCubeFirst, Fxu_Cube * pCubeNext ); static Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode ); -static int * s_pLits; +static Abc_Fan_t * s_pLits; extern int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -53,7 +53,7 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) Fxu_Var * pVar; Fxu_Cube * pCubeFirst, * pCubeNew; Fxu_Cube * pCube1, * pCube2; - Vec_Int_t * vFanins; + Vec_Fan_t * vFanins; char * pSopCover; char * pSopCube; int * pOrder, nBitsMax; @@ -69,7 +69,7 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) nCubesTotal = 0; nPairsTotal = 0; nPairsStore = 0; - nBitsMax = -1; + nBitsMax = -1; for ( i = 0; i < pData->nNodesOld; i++ ) if ( pSopCover = pData->vSops->pArray[i] ) { @@ -89,7 +89,7 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) return NULL; } - if ( nPairsStore > 50000000 ) + if ( nPairsStore > 10000000 ) { printf( "The problem is too large to be solved by \"fxu\" (%d cubes and %d cube pairs)\n", nCubesTotal, nPairsStore ); return NULL; @@ -151,7 +151,7 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) pOrder[v] = v; // reorder the fanins qsort( (void *)pOrder, nFanins, sizeof(int),(int (*)(const void *, const void *))Fxu_CreateMatrixLitCompare); - assert( s_pLits[ pOrder[0] ] < s_pLits[ pOrder[nFanins-1] ] ); + assert( s_pLits[ pOrder[0] ].iFan < s_pLits[ pOrder[nFanins-1] ].iFan ); // create the corresponding cubes in the matrix pCubeFirst = NULL; c = 0; @@ -178,26 +178,11 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) // consider the case when cube pairs should be preprocessed // before adding them to the set of divisors -// if ( pData->fVerbose ) -// printf( "The total number of cube pairs is %d.\n", nPairsTotal ); - if ( nPairsTotal > 10000000 ) - { - printf( "The total number of cube pairs of the network is more than 10,000,000.\n" ); - printf( "Command \"fx\" takes a long time to run in such cases. It is suggested\n" ); - printf( "that the user changes the network by reducing the size of logic node and\n" ); - printf( "consequently the number of cube pairs to be processed by this command.\n" ); - printf( "One way to achieve this is to run the commands \"st; multi -m -F <num>\"\n" ); - printf( "as a proprocessing step, while selecting <num> as approapriate.\n" ); - return NULL; - } if ( nPairsTotal > pData->nPairsMax ) - if ( !Fxu_PreprocessCubePairs( p, pData->vSops, nPairsTotal, pData->nPairsMax ) ) - return NULL; -// if ( pData->fVerbose ) -// printf( "Only %d best cube pairs will be used by the fast extract command.\n", pData->nPairsMax ); + Fxu_PreprocessCubePairs( p, pData->vSops, nPairsTotal, pData->nPairsMax ); // add the var pairs to the heap - Fxu_MatrixComputeSingles( p, pData->fUse0, pData->nSingleMax ); + Fxu_MatrixComputeSingles( p ); // print stats if ( pData->fVerbose ) @@ -208,8 +193,9 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) p->lVars.nItems, p->lCubes.nItems ); fprintf( stdout, "Lits = %d Density = %.5f%%\n", p->nEntries, Density ); - fprintf( stdout, "1-cube divs = %6d. (Total = %6d) ", p->lSingles.nItems, p->nSingleTotal ); - fprintf( stdout, "2-cube divs = %6d. (Total = %6d)", p->nDivsTotal, nPairsTotal ); + fprintf( stdout, "1-cube divisors = %6d. ", p->lSingles.nItems ); + fprintf( stdout, "2-cube divisors = %6d. ", p->nDivsTotal ); + fprintf( stdout, "Cube pairs = %6d.", nPairsTotal ); fprintf( stdout, "\n" ); } // Fxu_MatrixPrint( stdout, p ); @@ -228,7 +214,7 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) SeeAlso [] ***********************************************************************/ -void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Int_t * vFanins, int * pOrder ) +void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Fan_t * vFanins, int * pOrder ) { Fxu_Var * pVar; int Value, i; @@ -238,12 +224,12 @@ void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Value = pSopCube[pOrder[i]]; if ( Value == '0' ) { - pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]] + 1 ]; // CST + pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]].iFan + 1 ]; // CST Fxu_MatrixAddLiteral( p, pCube, pVar ); } else if ( Value == '1' ) { - pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]] ]; // CST + pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]].iFan ]; // CST Fxu_MatrixAddLiteral( p, pCube, pVar ); } } @@ -423,7 +409,7 @@ Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iV ***********************************************************************/ int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY ) { - return s_pLits[*ptrX] - s_pLits[*ptrY]; + return s_pLits[*ptrX].iFan - s_pLits[*ptrY].iFan; } //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/fxu/fxuHeapD.c b/src/opt/fxu/fxuHeapD.c index c81ad818..7c123249 100644 --- a/src/opt/fxu/fxuHeapD.c +++ b/src/opt/fxu/fxuHeapD.c @@ -38,7 +38,7 @@ static void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv ); static void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/fxu/fxuHeapS.c b/src/opt/fxu/fxuHeapS.c index eaca8363..dbd66055 100644 --- a/src/opt/fxu/fxuHeapS.c +++ b/src/opt/fxu/fxuHeapS.c @@ -38,7 +38,7 @@ static void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle ); static void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/fxu/fxuInt.h b/src/opt/fxu/fxuInt.h index ea85cb79..59b2df6d 100644 --- a/src/opt/fxu/fxuInt.h +++ b/src/opt/fxu/fxuInt.h @@ -23,6 +23,7 @@ /// INCLUDES /// //////////////////////////////////////////////////////////////////////// +#include "util.h" #include "extra.h" #include "vec.h" @@ -172,8 +173,6 @@ struct FxuMatrix // ~ 30 words // the single cube divisors Fxu_ListSingle lSingles; // the linked list of single cube divisors Fxu_HeapSingle * pHeapSingle; // the heap of variables by the number of literals in the matrix - int nWeightLimit;// the limit on weight of single cube divisors collected - int nSingleTotal;// the total number of single cube divisors // storage for cube pairs Fxu_Pair *** pppPairs; Fxu_Pair ** ppPairs; @@ -273,7 +272,7 @@ struct FxuSingle // 7 words }; //////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// +/// MACRO DEFITIONS /// //////////////////////////////////////////////////////////////////////// // minimum/maximum @@ -431,7 +430,7 @@ extern void Fxu_MatrixRingVarsUnmark( Fxu_Matrix * p ); #endif //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /*===== fxu.c ====================================================*/ @@ -461,7 +460,7 @@ extern void Fxu_PairClearStorage( Fxu_Cube * pCube ); extern Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 ); extern void Fxu_PairAdd( Fxu_Pair * pPair ); /*===== fxuSingle.c ====================================================*/ -extern void Fxu_MatrixComputeSingles( Fxu_Matrix * p, int fUse0, int nSingleMax ); +extern void Fxu_MatrixComputeSingles( Fxu_Matrix * p ); extern void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ); extern int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 ); /*===== fxuMatrix.c ====================================================*/ @@ -531,9 +530,8 @@ extern int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p ); extern Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p ); extern Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p ); -#endif - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +#endif diff --git a/src/opt/fxu/fxuList.c b/src/opt/fxu/fxuList.c index 52995804..bb081d80 100644 --- a/src/opt/fxu/fxuList.c +++ b/src/opt/fxu/fxuList.c @@ -23,7 +23,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// // matrix -> var diff --git a/src/opt/fxu/fxuMatrix.c b/src/opt/fxu/fxuMatrix.c index 93ec7b90..503ba2f1 100644 --- a/src/opt/fxu/fxuMatrix.c +++ b/src/opt/fxu/fxuMatrix.c @@ -25,7 +25,7 @@ extern unsigned int Cudd_Prime( unsigned int p ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -130,7 +130,7 @@ void Fxu_MatrixDelete( Fxu_Matrix * p ) MEM_FREE_FXU( p, Fxu_Var, 1, pVar ); } #else - Extra_MmFixedStop( p->pMemMan ); + Extra_MmFixedStop( p->pMemMan, 0 ); #endif Vec_PtrFree( p->vPairs ); diff --git a/src/opt/fxu/fxuPair.c b/src/opt/fxu/fxuPair.c index 3c031ce8..be6be5e9 100644 --- a/src/opt/fxu/fxuPair.c +++ b/src/opt/fxu/fxuPair.c @@ -55,7 +55,7 @@ static s_Primes[MAX_PRIMES] = }; //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/fxu/fxuPrint.c b/src/opt/fxu/fxuPrint.c index 232b109a..2d25c0e9 100644 --- a/src/opt/fxu/fxuPrint.c +++ b/src/opt/fxu/fxuPrint.c @@ -23,7 +23,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/fxu/fxuReduce.c b/src/opt/fxu/fxuReduce.c index 0ab8a157..652d807b 100644 --- a/src/opt/fxu/fxuReduce.c +++ b/src/opt/fxu/fxuReduce.c @@ -27,7 +27,7 @@ static int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -90,16 +90,6 @@ int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTota pnPairCounters[ pnLitsDiff[k] ]++; // determine what pairs to take starting from the lower // so that there would be exactly pPairsMax pairs - if ( pnPairCounters[0] != 0 ) - { - printf( "The SOPs of the nodes are not cube-free. Run \"bdd; sop\" before \"fx\".\n" ); - return 0; - } - if ( pnPairCounters[1] != 0 ) - { - printf( "The SOPs of the nodes are not SCC-free. Run \"bdd; sop\" before \"fx\".\n" ); - return 0; - } assert( pnPairCounters[0] == 0 ); // otherwise, covers are not dup-free assert( pnPairCounters[1] == 0 ); // otherwise, covers are not SCC-free nSum = 0; diff --git a/src/opt/fxu/fxuSelect.c b/src/opt/fxu/fxuSelect.c index b9265487..b56407a9 100644 --- a/src/opt/fxu/fxuSelect.c +++ b/src/opt/fxu/fxuSelect.c @@ -37,7 +37,7 @@ void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble, //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/fxu/fxuSingle.c b/src/opt/fxu/fxuSingle.c index 73d9a76c..5af5c341 100644 --- a/src/opt/fxu/fxuSingle.c +++ b/src/opt/fxu/fxuSingle.c @@ -17,16 +17,13 @@ ***********************************************************************/ #include "fxuInt.h" -#include "vec.h" //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static void Fxu_MatrixComputeSinglesOneCollect( Fxu_Matrix * p, Fxu_Var * pVar, Vec_Ptr_t * vSingles ); - //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -41,130 +38,12 @@ static void Fxu_MatrixComputeSinglesOneCollect( Fxu_Matrix * p, Fxu_Var * pVar, SeeAlso [] ***********************************************************************/ -void Fxu_MatrixComputeSingles( Fxu_Matrix * p, int fUse0, int nSingleMax ) +void Fxu_MatrixComputeSingles( Fxu_Matrix * p ) { Fxu_Var * pVar; - Vec_Ptr_t * vSingles; - int i, k; - // set the weight limit - p->nWeightLimit = 1 - fUse0; - // iterate through columns in the matrix and collect single-cube divisors - vSingles = Vec_PtrAlloc( 10000 ); + // iterate through the columns in the matrix Fxu_MatrixForEachVariable( p, pVar ) - Fxu_MatrixComputeSinglesOneCollect( p, pVar, vSingles ); - p->nSingleTotal = Vec_PtrSize(vSingles) / 3; - // check if divisors should be filtered - if ( Vec_PtrSize(vSingles) > nSingleMax ) - { - int * pWeigtCounts, nDivCount, Weight, i, c;; - assert( Vec_PtrSize(vSingles) % 3 == 0 ); - // count how many divisors have the given weight - pWeigtCounts = ALLOC( int, 1000 ); - memset( pWeigtCounts, 0, sizeof(int) * 1000 ); - for ( i = 2; i < Vec_PtrSize(vSingles); i += 3 ) - { - Weight = (int)Vec_PtrEntry(vSingles, i); - if ( Weight >= 999 ) - pWeigtCounts[999]++; - else - pWeigtCounts[Weight]++; - } - // select the bound on the weight (above this bound, singles will be included) - nDivCount = 0; - for ( c = 999; c >= 0; c-- ) - { - nDivCount += pWeigtCounts[c]; - if ( nDivCount >= nSingleMax ) - break; - } - free( pWeigtCounts ); - // collect singles with the given costs - k = 0; - for ( i = 2; i < Vec_PtrSize(vSingles); i += 3 ) - { - Weight = (int)Vec_PtrEntry(vSingles, i); - if ( Weight < c ) - continue; - Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i-2) ); - Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i-1) ); - Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i) ); - if ( k/3 == nSingleMax ) - break; - } - Vec_PtrShrink( vSingles, k ); - // adjust the weight limit - p->nWeightLimit = c; - } - // collect the selected divisors - assert( Vec_PtrSize(vSingles) % 3 == 0 ); - for ( i = 0; i < Vec_PtrSize(vSingles); i += 3 ) - { - Fxu_MatrixAddSingle( p, - Vec_PtrEntry(vSingles,i), - Vec_PtrEntry(vSingles,i+1), - (int)Vec_PtrEntry(vSingles,i+2) ); - } - Vec_PtrFree( vSingles ); -} - -/**Function************************************************************* - - Synopsis [Adds the single-cube divisors associated with a new column.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixComputeSinglesOneCollect( Fxu_Matrix * p, Fxu_Var * pVar, Vec_Ptr_t * vSingles ) -{ - Fxu_Lit * pLitV, * pLitH; - Fxu_Var * pVar2; - int Coin; - int WeightCur; - - // start collecting the affected vars - Fxu_MatrixRingVarsStart( p ); - // go through all the literals of this variable - for ( pLitV = pVar->lLits.pHead; pLitV; pLitV = pLitV->pVNext ) - // for this literal, go through all the horizontal literals - for ( pLitH = pLitV->pHPrev; pLitH; pLitH = pLitH->pHPrev ) - { - // get another variable - pVar2 = pLitH->pVar; - // skip the var if it is already used - if ( pVar2->pOrder ) - continue; - // skip the var if it belongs to the same node -// if ( pValue2Node[pVar->iVar] == pValue2Node[pVar2->iVar] ) -// continue; - // collect the var - Fxu_MatrixRingVarsAdd( p, pVar2 ); - } - // stop collecting the selected vars - Fxu_MatrixRingVarsStop( p ); - - // iterate through the selected vars - Fxu_MatrixForEachVarInRing( p, pVar2 ) - { - // count the coincidence - Coin = Fxu_SingleCountCoincidence( p, pVar2, pVar ); - assert( Coin > 0 ); - // get the new weight - WeightCur = Coin - 2; - // peformance fix (August 24, 2007) - if ( WeightCur >= p->nWeightLimit ) - { - Vec_PtrPush( vSingles, pVar2 ); - Vec_PtrPush( vSingles, pVar ); - Vec_PtrPush( vSingles, (void *)WeightCur ); - } - } - - // unmark the vars - Fxu_MatrixRingVarsUnmark( p ); + Fxu_MatrixComputeSinglesOne( p, pVar ); } /**Function************************************************************* @@ -180,9 +59,12 @@ void Fxu_MatrixComputeSinglesOneCollect( Fxu_Matrix * p, Fxu_Var * pVar, Vec_Ptr ***********************************************************************/ void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ) { +// int * pValue2Node = p->pValue2Node; Fxu_Lit * pLitV, * pLitH; Fxu_Var * pVar2; int Coin; +// int CounterAll; +// int CounterTest; int WeightCur; // start collecting the affected vars @@ -194,6 +76,7 @@ void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ) { // get another variable pVar2 = pLitH->pVar; +// CounterAll++; // skip the var if it is already used if ( pVar2->pOrder ) continue; @@ -209,17 +92,16 @@ void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ) // iterate through the selected vars Fxu_MatrixForEachVarInRing( p, pVar2 ) { +// CounterTest++; // count the coincidence Coin = Fxu_SingleCountCoincidence( p, pVar2, pVar ); assert( Coin > 0 ); // get the new weight WeightCur = Coin - 2; - // peformance fix (August 24, 2007) -// if ( WeightCur >= 0 ) -// Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur ); - if ( WeightCur >= p->nWeightLimit ) + if ( WeightCur >= 0 ) Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur ); } + // unmark the vars Fxu_MatrixRingVarsUnmark( p ); } diff --git a/src/opt/fxu/fxuUpdate.c b/src/opt/fxu/fxuUpdate.c index 274f79f6..4006bc76 100644 --- a/src/opt/fxu/fxuUpdate.c +++ b/src/opt/fxu/fxuUpdate.c @@ -37,7 +37,7 @@ static void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p ); static void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -757,14 +757,12 @@ void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p ) { Fxu_Single * pSingle, * pSingle2; int WeightNew; - int Counter = 0; Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 ) { // if at least one of the variables is marked, recalculate if ( pSingle->pVar1->pOrder || pSingle->pVar2->pOrder ) { - Counter++; // get the new weight WeightNew = -2 + Fxu_SingleCountCoincidence( p, pSingle->pVar1, pSingle->pVar2 ); if ( WeightNew >= 0 ) @@ -780,7 +778,6 @@ void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p ) } } } -// printf( "Called procedure %d times.\n", Counter ); } /**Function************************************************************* diff --git a/src/opt/lpk/lpk.h b/src/opt/lpk/lpk.h deleted file mode 100644 index 2a642db2..00000000 --- a/src/opt/lpk/lpk.h +++ /dev/null @@ -1,84 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpk.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpk.h,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __LPK_H__ -#define __LPK_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Lpk_Par_t_ Lpk_Par_t; -struct Lpk_Par_t_ -{ - // user-controlled parameters - int nLutsMax; // (N) the maximum number of LUTs in the structure - int nLutsOver; // (Q) the maximum number of LUTs not in the MFFC - int nVarsShared; // (S) the maximum number of shared variables (crossbars) - int nGrowthLevel; // (L) the maximum increase in the node level after resynthesis - int fSatur; // iterate till saturation - int fZeroCost; // accept zero-cost replacements - int fFirst; // use root node and first cut only - int fOldAlgo; // use old algorithm - int fVerbose; // the verbosiness flag - int fVeryVerbose; // additional verbose info printout - // internal parameters - int nLutSize; // (K) the LUT size (determined by the input network) - int nVarsMax; // (V) the largest number of variables: V = N * (K-1) + 1 -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// ITERATORS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== lpkCore.c ========================================================*/ -extern int Lpk_Resynthesize( Abc_Ntk_t * pNtk, Lpk_Par_t * pPars ); - - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/lpk/lpkAbcDec.c b/src/opt/lpk/lpkAbcDec.c deleted file mode 100644 index aa2d4bc0..00000000 --- a/src/opt/lpk/lpkAbcDec.c +++ /dev/null @@ -1,290 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkAbcDec.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [The new core procedure.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkAbcDec.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Implements the function.] - - Description [Returns the node implementing this function.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -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, 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 ) - { - pObjNew->pData = Hop_NotCond( Hop_ManConst1(pNtk->pManFunc), !(pTruth[0] & 1) ); - return pObjNew; - } - if ( p->nVars == 1 ) - { - pObjNew->pData = Hop_NotCond( Hop_ManPi(pNtk->pManFunc, 0), (pTruth[0] & 1) ); - return pObjNew; - } - // create the logic function - pObjNew->pData = Kit_TruthToHop( pNtk->pManFunc, pTruth, p->nVars, NULL ); - return pObjNew; -} - -/**Function************************************************************* - - Synopsis [Implements the function.] - - Description [Returns the node implementing this function.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Lpk_Implement_rec( Lpk_Man_t * pMan, Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, Lpk_Fun_t * pFun ) -{ - Abc_Obj_t * pFanin, * pRes; - int i; - // prepare the leaves of the function - for ( i = 0; i < (int)pFun->nVars; i++ ) - { - 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; -} - -/**Function************************************************************* - - Synopsis [Decomposes the function using recursive MUX decomposition.] - - Description [Returns the ID of the top-most decomposition node - implementing this function, or 0 if there is no decomposition satisfying - the constraints on area and delay.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -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 ); - // skip if area bound is exceeded - if ( Lpk_LutNumLuts(p->nVars, p->nLutK) > (int)p->nAreaLim ) - return 0; - // 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 -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 if ( pResMux && pResDsd ) - { - // compare two decompositions - if ( pResMux->AreaEst < pResDsd->AreaEst || - (pResMux->AreaEst == pResDsd->AreaEst && pResMux->nSuppSizeL < pResDsd->nSuppSizeL) || - (pResMux->AreaEst == pResDsd->AreaEst && pResMux->nSuppSizeL == pResDsd->nSuppSizeL && pResMux->DelayEst < pResDsd->DelayEst) ) - pResDsd = NULL; - else - pResMux = NULL; - } - assert( pResMux == NULL || pResDsd == NULL ); - if ( pResMux ) - { -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( pMan, p ) ) - return 0; - return 1; - } - if ( pResDsd ) - { -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; - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Removes decomposed nodes from the array of fanins.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_DecomposeClean( Vec_Ptr_t * vLeaves, int nLeavesOld ) -{ - Lpk_Fun_t * pFunc; - int i; - Vec_PtrForEachEntryStart( vLeaves, pFunc, i, nLeavesOld ) - Lpk_FunFree( pFunc ); - Vec_PtrShrink( vLeaves, nLeavesOld ); -} - -/**Function************************************************************* - - Synopsis [Decomposes the function using recursive MUX decomposition.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -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( p, pNtk, vLeaves, pFun ); - else if ( Lpk_Decompose_rec(p, pFun) ) - pObjNew = Lpk_Implement( p, pNtk, vLeaves, nLeaves ); - Lpk_DecomposeClean( vLeaves, nLeaves ); - return pObjNew; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpkAbcDsd.c b/src/opt/lpk/lpkAbcDsd.c deleted file mode 100644 index f4095914..00000000 --- a/src/opt/lpk/lpkAbcDsd.c +++ /dev/null @@ -1,603 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkAbcDsd.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [LUT-decomposition based on recursive DSD.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkAbcDsd.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Cofactors TTs w.r.t. all vars and finds the best var.] - - Description [The best variable is the variable with the minimum - sum total of the support sizes of all truth tables. This procedure - computes and returns cofactors w.r.t. the best variable.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_FunComputeMinSuppSizeVar( Lpk_Fun_t * p, unsigned ** ppTruths, int nTruths, unsigned ** ppCofs, unsigned uNonDecSupp ) -{ - int i, Var, VarBest, nSuppSize0, nSuppSize1, nSuppTotalMin, nSuppTotalCur, nSuppMaxMin, nSuppMaxCur; - assert( nTruths > 0 ); - VarBest = -1; - Lpk_SuppForEachVar( p->uSupp, Var ) - { - if ( (uNonDecSupp & (1 << Var)) == 0 ) - continue; - nSuppMaxCur = 0; - nSuppTotalCur = 0; - for ( i = 0; i < nTruths; i++ ) - { - if ( nTruths == 1 ) - { - nSuppSize0 = Kit_WordCountOnes( p->puSupps[2*Var+0] ); - nSuppSize1 = Kit_WordCountOnes( p->puSupps[2*Var+1] ); - } - else - { - Kit_TruthCofactor0New( ppCofs[2*i+0], ppTruths[i], p->nVars, Var ); - Kit_TruthCofactor1New( ppCofs[2*i+1], ppTruths[i], p->nVars, Var ); - nSuppSize0 = Kit_TruthSupportSize( ppCofs[2*i+0], p->nVars ); - nSuppSize1 = Kit_TruthSupportSize( ppCofs[2*i+1], p->nVars ); - } - nSuppMaxCur = ABC_MAX( nSuppMaxCur, nSuppSize0 ); - nSuppMaxCur = ABC_MAX( nSuppMaxCur, nSuppSize1 ); - nSuppTotalCur += nSuppSize0 + nSuppSize1; - } - if ( VarBest == -1 || nSuppMaxMin > nSuppMaxCur || - (nSuppMaxMin == nSuppMaxCur && nSuppTotalMin > nSuppTotalCur) ) - { - VarBest = Var; - nSuppMaxMin = nSuppMaxCur; - nSuppTotalMin = nSuppTotalCur; - } - } - // recompute cofactors for the best var - for ( i = 0; i < nTruths; i++ ) - { - Kit_TruthCofactor0New( ppCofs[2*i+0], ppTruths[i], p->nVars, VarBest ); - Kit_TruthCofactor1New( ppCofs[2*i+1], ppTruths[i], p->nVars, VarBest ); - } - return VarBest; -} - -/**Function************************************************************* - - Synopsis [Recursively computes decomposable subsets.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Lpk_ComputeBoundSets_rec( Kit_DsdNtk_t * p, int iLit, Vec_Int_t * vSets, int nSizeMax ) -{ - unsigned i, iLitFanin, uSupport, uSuppCur; - Kit_DsdObj_t * pObj; - // consider the case of simple gate - pObj = Kit_DsdNtkObj( p, Kit_DsdLit2Var(iLit) ); - if ( pObj == NULL ) - return (1 << Kit_DsdLit2Var(iLit)); - if ( pObj->Type == KIT_DSD_AND || pObj->Type == KIT_DSD_XOR ) - { - unsigned uSupps[16], Limit, s; - uSupport = 0; - Kit_DsdObjForEachFanin( p, pObj, iLitFanin, i ) - { - uSupps[i] = Lpk_ComputeBoundSets_rec( p, iLitFanin, vSets, nSizeMax ); - uSupport |= uSupps[i]; - } - // create all subsets, except empty and full - Limit = (1 << pObj->nFans) - 1; - for ( s = 1; s < Limit; s++ ) - { - uSuppCur = 0; - for ( i = 0; i < pObj->nFans; i++ ) - if ( s & (1 << i) ) - uSuppCur |= uSupps[i]; - if ( Kit_WordCountOnes(uSuppCur) <= nSizeMax ) - Vec_IntPush( vSets, uSuppCur ); - } - return uSupport; - } - assert( pObj->Type == KIT_DSD_PRIME ); - // get the cumulative support of all fanins - uSupport = 0; - Kit_DsdObjForEachFanin( p, pObj, iLitFanin, i ) - { - uSuppCur = Lpk_ComputeBoundSets_rec( p, iLitFanin, vSets, nSizeMax ); - uSupport |= uSuppCur; - if ( Kit_WordCountOnes(uSuppCur) <= nSizeMax ) - Vec_IntPush( vSets, uSuppCur ); - } - return uSupport; -} - -/**Function************************************************************* - - Synopsis [Computes the set of subsets of decomposable variables.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Lpk_ComputeBoundSets( Kit_DsdNtk_t * p, int nSizeMax ) -{ - Vec_Int_t * vSets; - unsigned uSupport, Entry; - int Number, i; - assert( p->nVars <= 16 ); - vSets = Vec_IntAlloc( 100 ); - Vec_IntPush( vSets, 0 ); - if ( Kit_DsdNtkRoot(p)->Type == KIT_DSD_CONST1 ) - return vSets; - if ( Kit_DsdNtkRoot(p)->Type == KIT_DSD_VAR ) - { - uSupport = ( 1 << Kit_DsdLit2Var(Kit_DsdNtkRoot(p)->pFans[0]) ); - if ( Kit_WordCountOnes(uSupport) <= nSizeMax ) - Vec_IntPush( vSets, uSupport ); - return vSets; - } - uSupport = Lpk_ComputeBoundSets_rec( p, p->Root, vSets, nSizeMax ); - assert( (uSupport & 0xFFFF0000) == 0 ); - // add the total support of the network - if ( Kit_WordCountOnes(uSupport) <= nSizeMax ) - Vec_IntPush( vSets, uSupport ); - // set the remaining variables - Vec_IntForEachEntry( vSets, Number, i ) - { - Entry = Number; - Vec_IntWriteEntry( vSets, i, Entry | ((uSupport & ~Entry) << 16) ); - } - return vSets; -} - -/**Function************************************************************* - - Synopsis [Prints the sets of subsets.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static void Lpk_PrintSetOne( int uSupport ) -{ - unsigned k; - for ( k = 0; k < 16; k++ ) - if ( uSupport & (1<<k) ) - printf( "%c", 'a'+k ); - printf( " " ); -} -/**Function************************************************************* - - Synopsis [Prints the sets of subsets.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static void Lpk_PrintSets( Vec_Int_t * vSets ) -{ - unsigned uSupport; - int Number, i; - printf( "Subsets(%d): ", Vec_IntSize(vSets) ); - Vec_IntForEachEntry( vSets, Number, i ) - { - uSupport = Number; - Lpk_PrintSetOne( uSupport ); - } - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Merges two bound sets.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Lpk_MergeBoundSets( Vec_Int_t * vSets0, Vec_Int_t * vSets1, int nSizeMax ) -{ - Vec_Int_t * vSets; - int Entry0, Entry1, Entry; - int i, k; - vSets = Vec_IntAlloc( 100 ); - Vec_IntForEachEntry( vSets0, Entry0, i ) - Vec_IntForEachEntry( vSets1, Entry1, k ) - { - Entry = Entry0 | Entry1; - if ( (Entry & (Entry >> 16)) ) - continue; - if ( Kit_WordCountOnes(Entry & 0xffff) <= nSizeMax ) - Vec_IntPush( vSets, Entry ); - } - return vSets; -} - -/**Function************************************************************* - - Synopsis [Performs DSD-based decomposition of the function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_FunCompareBoundSets( Lpk_Fun_t * p, Vec_Int_t * vBSets, int nCofDepth, unsigned uNonDecSupp, unsigned uLateArrSupp, Lpk_Res_t * pRes ) -{ - int fVerbose = 0; - unsigned uBoundSet; - int i, nVarsBS, nVarsRem, Delay, Area; - - // compare the resulting boundsets - memset( pRes, 0, sizeof(Lpk_Res_t) ); - Vec_IntForEachEntry( vBSets, uBoundSet, i ) - { - if ( (uBoundSet & 0xFFFF) == 0 ) // skip empty boundset - continue; - if ( (uBoundSet & uNonDecSupp) == 0 ) // skip those boundsets that are not in the domain of interest - continue; - if ( (uBoundSet & uLateArrSupp) ) // skip those boundsets that are late arriving - continue; -if ( fVerbose ) -Lpk_PrintSetOne( uBoundSet ); - assert( (uBoundSet & (uBoundSet >> 16)) == 0 ); - nVarsBS = Kit_WordCountOnes( uBoundSet & 0xFFFF ); - if ( nVarsBS == 1 ) - continue; - assert( nVarsBS <= (int)p->nLutK - nCofDepth ); - nVarsRem = p->nVars - nVarsBS + 1; - Area = 1 + Lpk_LutNumLuts( nVarsRem, p->nLutK ); - Delay = 1 + Lpk_SuppDelay( uBoundSet & 0xFFFF, p->pDelays ); -if ( fVerbose ) -printf( "area = %d limit = %d delay = %d limit = %d\n", Area, (int)p->nAreaLim, Delay, (int)p->nDelayLim ); - if ( Area > (int)p->nAreaLim || Delay > (int)p->nDelayLim ) - continue; - if ( pRes->BSVars == 0 || pRes->nSuppSizeL > nVarsRem || (pRes->nSuppSizeL == nVarsRem && pRes->DelayEst > Delay) ) - { - pRes->nBSVars = nVarsBS; - pRes->BSVars = (uBoundSet & 0xFFFF); - pRes->nSuppSizeS = nVarsBS + nCofDepth; - pRes->nSuppSizeL = nVarsRem; - pRes->DelayEst = Delay; - pRes->AreaEst = Area; - } - } -if ( fVerbose ) -{ -if ( pRes->BSVars ) -{ -printf( "Found bound set " ); -Lpk_PrintSetOne( pRes->BSVars ); -printf( "\n" ); -} -else -printf( "Did not find boundsets.\n" ); -printf( "\n" ); -} - if ( pRes->BSVars ) - { - assert( pRes->DelayEst <= (int)p->nDelayLim ); - assert( pRes->AreaEst <= (int)p->nAreaLim ); - } -} - - -/**Function************************************************************* - - Synopsis [Finds late arriving inputs, which cannot be in the bound set.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Lpk_DsdLateArriving( Lpk_Fun_t * p ) -{ - unsigned i, uLateArrSupp = 0; - Lpk_SuppForEachVar( p->uSupp, i ) - if ( p->pDelays[i] > (int)p->nDelayLim - 2 ) - uLateArrSupp |= (1 << i); - return uLateArrSupp; -} - -/**Function************************************************************* - - Synopsis [Performs DSD-based decomposition of the function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_DsdAnalizeOne( Lpk_Fun_t * p, unsigned * ppTruths[5][16], Kit_DsdNtk_t * pNtks[], char pCofVars[], int nCofDepth, Lpk_Res_t * pRes ) -{ - int fVerbose = 0; - Vec_Int_t * pvBSets[4][8]; - unsigned uNonDecSupp, uLateArrSupp; - int i, k, nNonDecSize, nNonDecSizeMax; - assert( nCofDepth >= 1 && nCofDepth <= 3 ); - assert( nCofDepth < (int)p->nLutK - 1 ); - assert( p->fSupports ); - - // find the support of the largest non-DSD block - nNonDecSizeMax = 0; - uNonDecSupp = p->uSupp; - for ( i = 0; i < (1<<(nCofDepth-1)); i++ ) - { - nNonDecSize = Kit_DsdNonDsdSizeMax( pNtks[i] ); - if ( nNonDecSizeMax < nNonDecSize ) - { - nNonDecSizeMax = nNonDecSize; - uNonDecSupp = Kit_DsdNonDsdSupports( pNtks[i] ); - } - else if ( nNonDecSizeMax == nNonDecSize ) - uNonDecSupp |= Kit_DsdNonDsdSupports( pNtks[i] ); - } - - // remove those variables that cannot be used because of delay constraints - // if variables arrival time is more than p->DelayLim - 2, it cannot be used - uLateArrSupp = Lpk_DsdLateArriving( p ); - if ( (uNonDecSupp & ~uLateArrSupp) == 0 ) - { - memset( pRes, 0, sizeof(Lpk_Res_t) ); - return 0; - } - - // find the next cofactoring variable - pCofVars[nCofDepth-1] = Lpk_FunComputeMinSuppSizeVar( p, ppTruths[nCofDepth-1], 1<<(nCofDepth-1), ppTruths[nCofDepth], uNonDecSupp & ~uLateArrSupp ); - - // derive decomposed networks - for ( i = 0; i < (1<<nCofDepth); i++ ) - { - if ( pNtks[i] ) - Kit_DsdNtkFree( pNtks[i] ); - pNtks[i] = Kit_DsdDecomposeExpand( ppTruths[nCofDepth][i], p->nVars ); -if ( fVerbose ) -Kit_DsdPrint( stdout, pNtks[i] ); - pvBSets[nCofDepth][i] = Lpk_ComputeBoundSets( pNtks[i], p->nLutK - nCofDepth ); // try restricting to those in uNonDecSupp!!! - } - - // derive the set of feasible boundsets - for ( i = nCofDepth - 1; i >= 0; i-- ) - for ( k = 0; k < (1<<i); k++ ) - pvBSets[i][k] = Lpk_MergeBoundSets( pvBSets[i+1][2*k+0], pvBSets[i+1][2*k+1], p->nLutK - nCofDepth ); - // compare bound-sets - Lpk_FunCompareBoundSets( p, pvBSets[0][0], nCofDepth, uNonDecSupp, uLateArrSupp, pRes ); - // free the bound sets - for ( i = nCofDepth; i >= 0; i-- ) - for ( k = 0; k < (1<<i); k++ ) - Vec_IntFree( pvBSets[i][k] ); - - // copy the cofactoring variables - if ( pRes->BSVars ) - { - pRes->nCofVars = nCofDepth; - for ( i = 0; i < nCofDepth; i++ ) - pRes->pCofVars[i] = pCofVars[i]; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Performs DSD-based decomposition of the function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Lpk_Res_t * Lpk_DsdAnalize( Lpk_Man_t * pMan, Lpk_Fun_t * p, int nShared ) -{ - static Lpk_Res_t Res0, * pRes0 = &Res0; - static Lpk_Res_t Res1, * pRes1 = &Res1; - static Lpk_Res_t Res2, * pRes2 = &Res2; - static Lpk_Res_t Res3, * pRes3 = &Res3; - int fUseBackLooking = 1; - Lpk_Res_t * pRes = NULL; - Vec_Int_t * vBSets; - Kit_DsdNtk_t * pNtks[8] = {NULL}; - char pCofVars[5]; - int i; - - assert( p->nLutK >= 3 ); - assert( nShared >= 0 && nShared <= 3 ); - assert( p->uSupp == Kit_BitMask(p->nVars) ); - - // try decomposition without cofactoring - pNtks[0] = Kit_DsdDecomposeExpand( Lpk_FunTruth( p, 0 ), p->nVars ); - if ( pMan->pPars->fVerbose ) - pMan->nBlocks[ Kit_DsdNonDsdSizeMax(pNtks[0]) ]++; - vBSets = Lpk_ComputeBoundSets( pNtks[0], p->nLutK ); - Lpk_FunCompareBoundSets( p, vBSets, 0, 0xFFFF, Lpk_DsdLateArriving(p), pRes0 ); - Vec_IntFree( vBSets ); - - // check the result - if ( pRes0->nBSVars == (int)p->nLutK ) - { pRes = pRes0; goto finish; } - if ( pRes0->nBSVars == (int)p->nLutK - 1 ) - { pRes = pRes0; goto finish; } - if ( nShared == 0 ) - goto finish; - - // prepare storage - Kit_TruthCopy( pMan->ppTruths[0][0], Lpk_FunTruth( p, 0 ), p->nVars ); - - // cofactor 1 time - if ( !Lpk_DsdAnalizeOne( p, pMan->ppTruths, pNtks, pCofVars, 1, pRes1 ) ) - goto finish; - assert( pRes1->nBSVars <= (int)p->nLutK - 1 ); - if ( pRes1->nBSVars == (int)p->nLutK - 1 ) - { pRes = pRes1; goto finish; } - if ( pRes0->nBSVars == (int)p->nLutK - 2 ) - { pRes = pRes0; goto finish; } - if ( pRes1->nBSVars == (int)p->nLutK - 2 ) - { pRes = pRes1; goto finish; } - if ( nShared == 1 ) - goto finish; - - // cofactor 2 times - if ( p->nLutK >= 4 ) - { - if ( !Lpk_DsdAnalizeOne( p, pMan->ppTruths, pNtks, pCofVars, 2, pRes2 ) ) - goto finish; - assert( pRes2->nBSVars <= (int)p->nLutK - 2 ); - if ( pRes2->nBSVars == (int)p->nLutK - 2 ) - { pRes = pRes2; goto finish; } - if ( fUseBackLooking ) - { - if ( pRes0->nBSVars == (int)p->nLutK - 3 ) - { pRes = pRes0; goto finish; } - if ( pRes1->nBSVars == (int)p->nLutK - 3 ) - { pRes = pRes1; goto finish; } - } - if ( pRes2->nBSVars == (int)p->nLutK - 3 ) - { pRes = pRes2; goto finish; } - if ( nShared == 2 ) - goto finish; - assert( nShared == 3 ); - } - - // cofactor 3 times - if ( p->nLutK >= 5 ) - { - if ( !Lpk_DsdAnalizeOne( p, pMan->ppTruths, pNtks, pCofVars, 3, pRes3 ) ) - goto finish; - assert( pRes3->nBSVars <= (int)p->nLutK - 3 ); - if ( pRes3->nBSVars == (int)p->nLutK - 3 ) - { pRes = pRes3; goto finish; } - if ( fUseBackLooking ) - { - if ( pRes0->nBSVars == (int)p->nLutK - 4 ) - { pRes = pRes0; goto finish; } - if ( pRes1->nBSVars == (int)p->nLutK - 4 ) - { pRes = pRes1; goto finish; } - if ( pRes2->nBSVars == (int)p->nLutK - 4 ) - { pRes = pRes2; goto finish; } - } - if ( pRes3->nBSVars == (int)p->nLutK - 4 ) - { pRes = pRes3; goto finish; } - } - -finish: - // free the networks - for ( i = 0; i < (1<<nShared); i++ ) - if ( pNtks[i] ) - Kit_DsdNtkFree( pNtks[i] ); - // choose the best under these conditions - return pRes; -} - -/**Function************************************************************* - - Synopsis [Splits the function into two subfunctions using DSD.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Lpk_Fun_t * Lpk_DsdSplit( Lpk_Man_t * pMan, Lpk_Fun_t * p, char * pCofVars, int nCofVars, unsigned uBoundSet ) -{ - Lpk_Fun_t * pNew; - Kit_DsdNtk_t * pNtkDec; - int i, k, iVacVar, nCofs; - // prepare storage - Kit_TruthCopy( pMan->ppTruths[0][0], Lpk_FunTruth(p, 0), p->nVars ); - // get the vacuous variable - iVacVar = Kit_WordFindFirstBit( uBoundSet ); - // compute the cofactors - for ( i = 0; i < nCofVars; i++ ) - for ( k = 0; k < (1<<i); k++ ) - { - Kit_TruthCofactor0New( pMan->ppTruths[i+1][2*k+0], pMan->ppTruths[i][k], p->nVars, pCofVars[i] ); - Kit_TruthCofactor1New( pMan->ppTruths[i+1][2*k+1], pMan->ppTruths[i][k], p->nVars, pCofVars[i] ); - } - // decompose each cofactor w.r.t. the bound set - nCofs = (1<<nCofVars); - for ( k = 0; k < nCofs; k++ ) - { - pNtkDec = Kit_DsdDecomposeExpand( pMan->ppTruths[nCofVars][k], p->nVars ); - Kit_DsdTruthPartialTwo( pMan->pDsdMan, pNtkDec, uBoundSet, iVacVar, pMan->ppTruths[nCofVars+1][k], pMan->ppTruths[nCofVars+1][nCofs+k] ); - Kit_DsdNtkFree( pNtkDec ); - } - // compute the composition/decomposition functions (they will be in pMan->ppTruths[1][0]/pMan->ppTruths[1][1]) - for ( i = nCofVars; i >= 1; i-- ) - for ( k = 0; k < (1<<i); k++ ) - Kit_TruthMuxVar( pMan->ppTruths[i][k], pMan->ppTruths[i+1][2*k+0], pMan->ppTruths[i+1][2*k+1], p->nVars, pCofVars[i-1] ); - - // derive the new component (decomposition function) - pNew = Lpk_FunDup( p, pMan->ppTruths[1][1] ); - // update the old component (composition function) - Kit_TruthCopy( Lpk_FunTruth(p, 0), pMan->ppTruths[1][0], p->nVars ); - p->uSupp = Kit_TruthSupport( Lpk_FunTruth(p, 0), p->nVars ); - p->pFanins[iVacVar] = pNew->Id; - p->pDelays[iVacVar] = Lpk_SuppDelay( pNew->uSupp, pNew->pDelays ); - // support minimize both - p->fSupports = 0; - Lpk_FunSuppMinimize( p ); - Lpk_FunSuppMinimize( pNew ); - // update delay and area requirements - pNew->nDelayLim = p->pDelays[iVacVar]; - pNew->nAreaLim = 1; - p->nAreaLim = p->nAreaLim - 1; - return pNew; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpkAbcMux.c b/src/opt/lpk/lpkAbcMux.c deleted file mode 100644 index d6f579ee..00000000 --- a/src/opt/lpk/lpkAbcMux.c +++ /dev/null @@ -1,235 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkAbcMux.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [LUT-decomposition based on recursive MUX decomposition.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkAbcMux.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Checks the possibility of MUX decomposition.] - - Description [Returns the best variable to use for MUX decomposition.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Lpk_Res_t * Lpk_MuxAnalize( Lpk_Man_t * pMan, Lpk_Fun_t * p ) -{ - static Lpk_Res_t Res, * pRes = &Res; - int nSuppSize0, nSuppSize1, nSuppSizeS, nSuppSizeL; - int Var, Area, Polarity, Delay, Delay0, Delay1, DelayA, DelayB; - memset( pRes, 0, sizeof(Lpk_Res_t) ); - assert( p->uSupp == Kit_BitMask(p->nVars) ); - assert( p->fSupports ); - // derive the delay and area after MUX-decomp with each var - and find the best var - pRes->Variable = -1; - Lpk_SuppForEachVar( p->uSupp, Var ) - { - nSuppSize0 = Kit_WordCountOnes(p->puSupps[2*Var+0]); - nSuppSize1 = Kit_WordCountOnes(p->puSupps[2*Var+1]); - assert( nSuppSize0 < (int)p->nVars ); - assert( nSuppSize1 < (int)p->nVars ); - if ( nSuppSize0 < 1 || nSuppSize1 < 1 ) - continue; -//printf( "%d %d ", nSuppSize0, nSuppSize1 ); - if ( nSuppSize0 <= (int)p->nLutK - 2 && nSuppSize1 <= (int)p->nLutK - 2 ) - { - // include cof var into 0-block - DelayA = Lpk_SuppDelay( p->puSupps[2*Var+0] | (1<<Var), p->pDelays ); - DelayB = Lpk_SuppDelay( p->puSupps[2*Var+1] , p->pDelays ); - Delay0 = ABC_MAX( DelayA, DelayB + 1 ); - // include cof var into 1-block - DelayA = Lpk_SuppDelay( p->puSupps[2*Var+1] | (1<<Var), p->pDelays ); - DelayB = Lpk_SuppDelay( p->puSupps[2*Var+0] , p->pDelays ); - Delay1 = ABC_MAX( DelayA, DelayB + 1 ); - // get the best delay - Delay = ABC_MIN( Delay0, Delay1 ); - Area = 2; - Polarity = (int)(Delay == Delay1); - } - else if ( nSuppSize0 <= (int)p->nLutK - 2 ) - { - DelayA = Lpk_SuppDelay( p->puSupps[2*Var+0] | (1<<Var), p->pDelays ); - DelayB = Lpk_SuppDelay( p->puSupps[2*Var+1] , p->pDelays ); - Delay = ABC_MAX( DelayA, DelayB + 1 ); - Area = 1 + Lpk_LutNumLuts( nSuppSize1, p->nLutK ); - Polarity = 0; - } - else if ( nSuppSize1 <= (int)p->nLutK - 2 ) - { - DelayA = Lpk_SuppDelay( p->puSupps[2*Var+1] | (1<<Var), p->pDelays ); - DelayB = Lpk_SuppDelay( p->puSupps[2*Var+0] , p->pDelays ); - Delay = ABC_MAX( DelayA, DelayB + 1 ); - Area = 1 + Lpk_LutNumLuts( nSuppSize0, p->nLutK ); - Polarity = 1; - } - else if ( nSuppSize0 <= (int)p->nLutK ) - { - DelayA = Lpk_SuppDelay( p->puSupps[2*Var+1] | (1<<Var), p->pDelays ); - DelayB = Lpk_SuppDelay( p->puSupps[2*Var+0] , p->pDelays ); - Delay = ABC_MAX( DelayA, DelayB + 1 ); - Area = 1 + Lpk_LutNumLuts( nSuppSize1+2, p->nLutK ); - Polarity = 1; - } - else if ( nSuppSize1 <= (int)p->nLutK ) - { - DelayA = Lpk_SuppDelay( p->puSupps[2*Var+0] | (1<<Var), p->pDelays ); - DelayB = Lpk_SuppDelay( p->puSupps[2*Var+1] , p->pDelays ); - Delay = ABC_MAX( DelayA, DelayB + 1 ); - Area = 1 + Lpk_LutNumLuts( nSuppSize0+2, p->nLutK ); - Polarity = 0; - } - else - { - // include cof var into 0-block - DelayA = Lpk_SuppDelay( p->puSupps[2*Var+0] | (1<<Var), p->pDelays ); - DelayB = Lpk_SuppDelay( p->puSupps[2*Var+1] , p->pDelays ); - Delay0 = ABC_MAX( DelayA, DelayB + 1 ); - // include cof var into 1-block - DelayA = Lpk_SuppDelay( p->puSupps[2*Var+1] | (1<<Var), p->pDelays ); - DelayB = Lpk_SuppDelay( p->puSupps[2*Var+0] , p->pDelays ); - Delay1 = ABC_MAX( DelayA, DelayB + 1 ); - // get the best delay - Delay = ABC_MIN( Delay0, Delay1 ); - if ( Delay == Delay0 ) - Area = Lpk_LutNumLuts( nSuppSize0+2, p->nLutK ) + Lpk_LutNumLuts( nSuppSize1, p->nLutK ); - else - Area = Lpk_LutNumLuts( nSuppSize1+2, p->nLutK ) + Lpk_LutNumLuts( nSuppSize0, p->nLutK ); - Polarity = (int)(Delay == Delay1); - } - // find the best variable - if ( Delay > (int)p->nDelayLim ) - continue; - if ( Area > (int)p->nAreaLim ) - continue; - nSuppSizeS = ABC_MIN( nSuppSize0 + 2 *!Polarity, nSuppSize1 + 2 * Polarity ); - nSuppSizeL = ABC_MAX( nSuppSize0 + 2 *!Polarity, nSuppSize1 + 2 * Polarity ); - if ( nSuppSizeL > (int)p->nVars ) - continue; - if ( pRes->Variable == -1 || pRes->AreaEst > Area || - (pRes->AreaEst == Area && pRes->nSuppSizeS + pRes->nSuppSizeL > nSuppSizeS + nSuppSizeL) || - (pRes->AreaEst == Area && pRes->nSuppSizeS + pRes->nSuppSizeL == nSuppSizeS + nSuppSizeL && pRes->DelayEst > Delay) ) - { - pRes->Variable = Var; - pRes->Polarity = Polarity; - pRes->AreaEst = Area; - pRes->DelayEst = Delay; - pRes->nSuppSizeS = nSuppSizeS; - pRes->nSuppSizeL = nSuppSizeL; - } - } - return pRes->Variable == -1 ? NULL : pRes; -} - -/**Function************************************************************* - - Synopsis [Transforms the function decomposed by the MUX decomposition.] - - Description [Returns the best variable to use for MUX decomposition.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Lpk_Fun_t * Lpk_MuxSplit( Lpk_Man_t * pMan, Lpk_Fun_t * p, int Var, int Pol ) -{ - Lpk_Fun_t * pNew; - unsigned * pTruth = Lpk_FunTruth( p, 0 ); - unsigned * pTruth0 = Lpk_FunTruth( p, 1 ); - unsigned * pTruth1 = Lpk_FunTruth( p, 2 ); -// unsigned uSupp; - int iVarVac; - assert( Var >= 0 && Var < (int)p->nVars ); - assert( p->nAreaLim >= 2 ); - assert( p->uSupp == Kit_BitMask(p->nVars) ); - Kit_TruthCofactor0New( pTruth0, pTruth, p->nVars, Var ); - Kit_TruthCofactor1New( pTruth1, pTruth, p->nVars, Var ); -/* -uSupp = Kit_TruthSupport( pTruth, p->nVars ); -Extra_PrintBinary( stdout, &uSupp, 16 ); printf( "\n" ); -uSupp = Kit_TruthSupport( pTruth0, p->nVars ); -Extra_PrintBinary( stdout, &uSupp, 16 ); printf( "\n" ); -uSupp = Kit_TruthSupport( pTruth1, p->nVars ); -Extra_PrintBinary( stdout, &uSupp, 16 ); printf( "\n\n" ); -*/ - // derive the new component - pNew = Lpk_FunDup( p, Pol ? pTruth0 : pTruth1 ); - // update the support of the old component - p->uSupp = Kit_TruthSupport( Pol ? pTruth1 : pTruth0, p->nVars ); - p->uSupp |= (1 << Var); - // update the truth table of the old component - iVarVac = Kit_WordFindFirstBit( ~p->uSupp ); - assert( iVarVac < (int)p->nVars ); - p->uSupp |= (1 << iVarVac); - Kit_TruthIthVar( pTruth, p->nVars, iVarVac ); - if ( Pol ) - Kit_TruthMuxVar( pTruth, pTruth, pTruth1, p->nVars, Var ); - else - Kit_TruthMuxVar( pTruth, pTruth0, pTruth, p->nVars, Var ); - assert( p->uSupp == Kit_TruthSupport(pTruth, p->nVars) ); - // set the decomposed variable - p->pFanins[iVarVac] = pNew->Id; - p->pDelays[iVarVac] = p->nDelayLim - 1; - // support minimize both - p->fSupports = 0; - Lpk_FunSuppMinimize( p ); - Lpk_FunSuppMinimize( pNew ); - // update delay and area requirements - pNew->nDelayLim = p->nDelayLim - 1; - if ( pNew->nVars <= pNew->nLutK ) - { - pNew->nAreaLim = 1; - p->nAreaLim = p->nAreaLim - 1; - } - else if ( p->nVars <= p->nLutK ) - { - pNew->nAreaLim = p->nAreaLim - 1; - p->nAreaLim = 1; - } - else if ( p->nVars < pNew->nVars ) - { - pNew->nAreaLim = p->nAreaLim / 2 + p->nAreaLim % 2; - p->nAreaLim = p->nAreaLim / 2 - p->nAreaLim % 2; - } - else // if ( pNew->nVars < p->nVars ) - { - pNew->nAreaLim = p->nAreaLim / 2 - p->nAreaLim % 2; - p->nAreaLim = p->nAreaLim / 2 + p->nAreaLim % 2; - } - pNew->fMark = 1; - return pNew; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpkAbcUtil.c b/src/opt/lpk/lpkAbcUtil.c deleted file mode 100644 index 3f917ce2..00000000 --- a/src/opt/lpk/lpkAbcUtil.c +++ /dev/null @@ -1,244 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkAbcUtil.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [Procedures working on decomposed functions.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkAbcUtil.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates the function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Lpk_Fun_t * Lpk_FunAlloc( int nVars ) -{ - Lpk_Fun_t * p; - p = (Lpk_Fun_t *)malloc( sizeof(Lpk_Fun_t) + sizeof(unsigned) * Kit_TruthWordNum(nVars) * 3 ); - memset( p, 0, sizeof(Lpk_Fun_t) ); - return p; -} - -/**Function************************************************************* - - Synopsis [Deletes the function] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_FunFree( Lpk_Fun_t * p ) -{ - free( p ); -} - -/**Function************************************************************* - - Synopsis [Creates the starting function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Lpk_Fun_t * Lpk_FunCreate( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsigned * pTruth, int nLutK, int AreaLim, int DelayLim ) -{ - Lpk_Fun_t * p; - Abc_Obj_t * pNode; - int i; - p = Lpk_FunAlloc( Vec_PtrSize(vLeaves) ); - p->Id = Vec_PtrSize(vLeaves); - p->vNodes = vLeaves; - p->nVars = Vec_PtrSize(vLeaves); - p->nLutK = nLutK; - p->nAreaLim = AreaLim; - p->nDelayLim = DelayLim; - p->uSupp = Kit_TruthSupport( pTruth, p->nVars ); - Kit_TruthCopy( Lpk_FunTruth(p,0), pTruth, p->nVars ); - Vec_PtrForEachEntry( vLeaves, pNode, i ) - { - p->pFanins[i] = i; - p->pDelays[i] = pNode->Level; - } - Vec_PtrPush( p->vNodes, p ); - return p; -} - -/**Function************************************************************* - - Synopsis [Creates the new function with the given truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Lpk_Fun_t * Lpk_FunDup( Lpk_Fun_t * p, unsigned * pTruth ) -{ - Lpk_Fun_t * pNew; - pNew = Lpk_FunAlloc( p->nVars ); - pNew->Id = Vec_PtrSize(p->vNodes); - pNew->vNodes = p->vNodes; - pNew->nVars = p->nVars; - pNew->nLutK = p->nLutK; - pNew->nAreaLim = p->nAreaLim; - pNew->nDelayLim = p->nDelayLim; - pNew->uSupp = Kit_TruthSupport( pTruth, p->nVars ); - Kit_TruthCopy( Lpk_FunTruth(pNew,0), pTruth, p->nVars ); - memcpy( pNew->pFanins, p->pFanins, 16 ); - memcpy( pNew->pDelays, p->pDelays, 16 ); - Vec_PtrPush( p->vNodes, pNew ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [Minimizes support of the function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_FunSuppMinimize( Lpk_Fun_t * p ) -{ - int i, k, nVarsNew; - // compress the truth table - if ( p->uSupp == Kit_BitMask(p->nVars) ) - return 0; - // invalidate support info - p->fSupports = 0; -//Extra_PrintBinary( stdout, &p->uSupp, p->nVars ); printf( "\n" ); - // minimize support - nVarsNew = Kit_WordCountOnes(p->uSupp); - Kit_TruthShrink( Lpk_FunTruth(p, 1), Lpk_FunTruth(p, 0), nVarsNew, p->nVars, p->uSupp, 1 ); - k = 0; - Lpk_SuppForEachVar( p->uSupp, i ) - { - p->pFanins[k] = p->pFanins[i]; - p->pDelays[k] = p->pDelays[i]; -/* - if ( p->fSupports ) - { - p->puSupps[2*k+0] = p->puSupps[2*i+0]; - p->puSupps[2*k+1] = p->puSupps[2*i+1]; - } -*/ - k++; - } - assert( k == nVarsNew ); - p->nVars = k; - p->uSupp = Kit_BitMask(p->nVars); - return 1; -} - -/**Function************************************************************* - - Synopsis [Computes cofactors w.r.t. each variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_FunComputeCofSupps( Lpk_Fun_t * p ) -{ - unsigned * pTruth = Lpk_FunTruth( p, 0 ); - unsigned * pTruth0 = Lpk_FunTruth( p, 1 ); - unsigned * pTruth1 = Lpk_FunTruth( p, 2 ); - int Var; - assert( p->fSupports == 0 ); -// Lpk_SuppForEachVar( p->uSupp, Var ) - for ( Var = 0; Var < (int)p->nVars; Var++ ) - { - Kit_TruthCofactor0New( pTruth0, pTruth, p->nVars, Var ); - Kit_TruthCofactor1New( pTruth1, pTruth, p->nVars, Var ); - p->puSupps[2*Var+0] = Kit_TruthSupport( pTruth0, p->nVars ); - p->puSupps[2*Var+1] = Kit_TruthSupport( pTruth1, p->nVars ); - } - p->fSupports = 1; -} - -/**Function************************************************************* - - Synopsis [Get the delay of the bound set.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_SuppDelay( unsigned uSupp, char * pDelays ) -{ - int Delay, Var; - Delay = 0; - Lpk_SuppForEachVar( uSupp, Var ) - Delay = ABC_MAX( Delay, pDelays[Var] ); - return Delay + 1; -} - -/**Function************************************************************* - - Synopsis [Converts support into variables.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_SuppToVars( unsigned uBoundSet, char * pVars ) -{ - int i, nVars = 0; - Lpk_SuppForEachVar( uBoundSet, i ) - pVars[nVars++] = i; - return nVars; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpkCore.c b/src/opt/lpk/lpkCore.c deleted file mode 100644 index e819a7fb..00000000 --- a/src/opt/lpk/lpkCore.c +++ /dev/null @@ -1,659 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkCore.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkCore.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" -#include "cloud.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Prepares the mapping manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_IfManStart( Lpk_Man_t * p ) -{ - If_Par_t * pPars; - assert( p->pIfMan == NULL ); - // set defaults - pPars = ALLOC( If_Par_t, 1 ); - memset( pPars, 0, sizeof(If_Par_t) ); - // user-controlable paramters - pPars->nLutSize = p->pPars->nLutSize; - pPars->nCutsMax = 16; - pPars->nFlowIters = 0; // 1 - pPars->nAreaIters = 0; // 1 - pPars->DelayTarget = -1; - pPars->fPreprocess = 0; - pPars->fArea = 1; - pPars->fFancy = 0; - pPars->fExpRed = 0; // - pPars->fLatchPaths = 0; - pPars->fSeqMap = 0; - pPars->fVerbose = 0; - // internal parameters - pPars->fTruth = 1; - pPars->fUsePerm = 0; - pPars->nLatches = 0; - pPars->pLutLib = NULL; // Abc_FrameReadLibLut(); - pPars->pTimesArr = NULL; - pPars->pTimesArr = NULL; - pPars->fUseBdds = 0; - pPars->fUseSops = 0; - pPars->fUseCnfs = 0; - pPars->fUseMv = 0; - // start the mapping manager and set its parameters - p->pIfMan = If_ManStart( pPars ); - If_ManSetupSetAll( p->pIfMan, 1000 ); - p->pIfMan->pPars->pTimesArr = ALLOC( float, 32 ); -} - -/**Function************************************************************* - - Synopsis [Returns 1 if at least one entry has changed.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_NodeHasChanged( Lpk_Man_t * p, int iNode ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pTemp; - int i; - vNodes = Vec_VecEntry( p->vVisited, iNode ); - if ( Vec_PtrSize(vNodes) == 0 ) - return 1; - Vec_PtrForEachEntry( vNodes, pTemp, i ) - { - // check if the node has changed - pTemp = Abc_NtkObj( p->pNtk, (int)pTemp ); - if ( pTemp == NULL ) - return 1; - // check if the number of fanouts has changed -// if ( Abc_ObjFanoutNum(pTemp) != (int)Vec_PtrEntry(vNodes, i+1) ) -// return 1; - i++; - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Prepares the mapping manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_ExploreCut( Lpk_Man_t * p, Lpk_Cut_t * pCut, Kit_DsdNtk_t * pNtk ) -{ - extern Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t * pIfObj, Vec_Int_t * vCover ); - Kit_DsdObj_t * pRoot; - If_Obj_t * pDriver, * ppLeaves[16]; - Abc_Obj_t * pLeaf, * pObjNew; - int nGain, i, clk; - int nNodesBef; -// int nOldShared; - - // check special cases - pRoot = Kit_DsdNtkRoot( pNtk ); - if ( pRoot->Type == KIT_DSD_CONST1 ) - { - if ( Kit_DsdLitIsCompl(pNtk->Root) ) - pObjNew = Abc_NtkCreateNodeConst0( p->pNtk ); - else - pObjNew = Abc_NtkCreateNodeConst1( p->pNtk ); - Abc_NtkUpdate( p->pObj, pObjNew, p->vLevels ); - p->nGainTotal += pCut->nNodes - pCut->nNodesDup; - return 1; - } - if ( pRoot->Type == KIT_DSD_VAR ) - { - pObjNew = Abc_NtkObj( p->pNtk, pCut->pLeaves[ Kit_DsdLit2Var(pRoot->pFans[0]) ] ); - if ( Kit_DsdLitIsCompl(pNtk->Root) ^ Kit_DsdLitIsCompl(pRoot->pFans[0]) ) - pObjNew = Abc_NtkCreateNodeInv( p->pNtk, pObjNew ); - Abc_NtkUpdate( p->pObj, pObjNew, p->vLevels ); - p->nGainTotal += pCut->nNodes - pCut->nNodesDup; - return 1; - } - assert( pRoot->Type == KIT_DSD_AND || pRoot->Type == KIT_DSD_XOR || pRoot->Type == KIT_DSD_PRIME ); - - // start the mapping manager - if ( p->pIfMan == NULL ) - Lpk_IfManStart( p ); - - // prepare the mapping manager - If_ManRestart( p->pIfMan ); - // create the PI variables - for ( i = 0; i < p->pPars->nVarsMax; i++ ) - ppLeaves[i] = If_ManCreateCi( p->pIfMan ); - // set the arrival times - Lpk_CutForEachLeaf( p->pNtk, pCut, pLeaf, i ) - p->pIfMan->pPars->pTimesArr[i] = (float)pLeaf->Level; - // prepare the PI cuts - If_ManSetupCiCutSets( p->pIfMan ); - // create the internal nodes - p->fCalledOnce = 0; - p->nCalledSRed = 0; - pDriver = Lpk_MapTree_rec( p, pNtk, ppLeaves, pNtk->Root, NULL ); - if ( pDriver == NULL ) - return 0; - // create the PO node - If_ManCreateCo( p->pIfMan, If_Regular(pDriver) ); - - // perform mapping - p->pIfMan->pPars->fAreaOnly = 1; -clk = clock(); - If_ManPerformMappingComb( p->pIfMan ); -p->timeMap += clock() - clk; - - // compute the gain in area - nGain = pCut->nNodes - pCut->nNodesDup - (int)p->pIfMan->AreaGlo; - if ( p->pPars->fVeryVerbose ) - printf( " Mffc = %2d. Mapped = %2d. Gain = %3d. Depth increase = %d. SReds = %d.\n", - pCut->nNodes - pCut->nNodesDup, (int)p->pIfMan->AreaGlo, nGain, (int)p->pIfMan->RequiredGlo - (int)p->pObj->Level, p->nCalledSRed ); - - // quit if there is no gain - if ( !(nGain > 0 || (p->pPars->fZeroCost && nGain == 0)) ) - return 0; - - // quit if depth increases too much - if ( (int)p->pIfMan->RequiredGlo > Abc_ObjRequiredLevel(p->pObj) ) - return 0; - - // perform replacement - p->nGainTotal += nGain; - p->nChanges++; - if ( p->nCalledSRed ) - p->nBenefited++; - - nNodesBef = Abc_NtkNodeNum(p->pNtk); - // prepare the mapping manager - If_ManCleanNodeCopy( p->pIfMan ); - If_ManCleanCutData( p->pIfMan ); - // set the PIs of the cut - Lpk_CutForEachLeaf( p->pNtk, pCut, pLeaf, i ) - If_ObjSetCopy( If_ManCi(p->pIfMan, i), pLeaf ); - // get the area of mapping - pObjNew = Abc_NodeFromIf_rec( p->pNtk, p->pIfMan, If_Regular(pDriver), p->vCover ); - pObjNew->pData = Hop_NotCond( pObjNew->pData, If_IsComplement(pDriver) ); - // perform replacement - Abc_NtkUpdate( p->pObj, pObjNew, p->vLevels ); -//printf( "%3d : %d-%d=%d(%d) \n", p->nChanges, nNodesBef, Abc_NtkNodeNum(p->pNtk), nNodesBef-Abc_NtkNodeNum(p->pNtk), nGain ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Performs resynthesis for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_ResynthesizeNode( Lpk_Man_t * p ) -{ - static int Count = 0; - Kit_DsdNtk_t * pDsdNtk; - Lpk_Cut_t * pCut; - unsigned * pTruth; - int i, k, nSuppSize, nCutNodes, RetValue, clk; - - // compute the cuts -clk = clock(); - if ( !Lpk_NodeCuts( p ) ) - { -p->timeCuts += clock() - clk; - return 0; - } -p->timeCuts += clock() - clk; - -//return 0; - - if ( p->pPars->fVeryVerbose ) - printf( "Node %5d : Mffc size = %5d. Cuts = %5d.\n", p->pObj->Id, p->nMffc, p->nEvals ); - // try the good cuts - p->nCutsTotal += p->nCuts; - p->nCutsUseful += p->nEvals; - for ( i = 0; i < p->nEvals; i++ ) - { - // get the cut - pCut = p->pCuts + p->pEvals[i]; - if ( p->pPars->fFirst && i == 1 ) - break; - - // skip bad cuts -// printf( "Mffc size = %d. ", Abc_NodeMffcLabel(p->pObj) ); - for ( k = 0; k < (int)pCut->nLeaves; k++ ) - Abc_NtkObj(p->pNtk, pCut->pLeaves[k])->vFanouts.nSize++; - nCutNodes = Abc_NodeMffcLabel(p->pObj); -// printf( "Mffc with cut = %d. ", nCutNodes ); - for ( k = 0; k < (int)pCut->nLeaves; k++ ) - Abc_NtkObj(p->pNtk, pCut->pLeaves[k])->vFanouts.nSize--; -// printf( "Mffc cut = %d. ", (int)pCut->nNodes - (int)pCut->nNodesDup ); -// printf( "\n" ); - if ( nCutNodes != (int)pCut->nNodes - (int)pCut->nNodesDup ) - continue; - - // compute the truth table -clk = clock(); - pTruth = Lpk_CutTruth( p, pCut, 0 ); - nSuppSize = Extra_TruthSupportSize(pTruth, pCut->nLeaves); -p->timeTruth += clock() - clk; - - pDsdNtk = Kit_DsdDecompose( pTruth, pCut->nLeaves ); -// Kit_DsdVerify( pDsdNtk, pTruth, pCut->nLeaves ); - // skip 16-input non-DSD because ISOP will not work - if ( Kit_DsdNtkRoot(pDsdNtk)->nFans == 16 ) - { - Kit_DsdNtkFree( pDsdNtk ); - continue; - } - - // if DSD has nodes that require splitting to fit them into LUTs - // we can skip those cuts that cannot lead to improvement - // (a full DSD network requires V = Nmin * (K-1) + 1 for improvement) - if ( Kit_DsdNonDsdSizeMax(pDsdNtk) > p->pPars->nLutSize && - nSuppSize >= ((int)pCut->nNodes - (int)pCut->nNodesDup - 1) * (p->pPars->nLutSize - 1) + 1 ) - { - Kit_DsdNtkFree( pDsdNtk ); - continue; - } - - if ( p->pPars->fVeryVerbose ) - { -// char * pFileName; - printf( " C%02d: L= %2d/%2d V= %2d/%d N= %d W= %4.2f ", - i, pCut->nLeaves, nSuppSize, pCut->nNodes, pCut->nNodesDup, pCut->nLuts, pCut->Weight ); - Kit_DsdPrint( stdout, pDsdNtk ); - Kit_DsdPrintFromTruth( pTruth, pCut->nLeaves ); -// pFileName = Kit_TruthDumpToFile( pTruth, pCut->nLeaves, Count++ ); -// printf( "Saved truth table in file \"%s\".\n", pFileName ); - } - - // update the network -clk = clock(); - RetValue = Lpk_ExploreCut( p, pCut, pDsdNtk ); -p->timeEval += clock() - clk; - Kit_DsdNtkFree( pDsdNtk ); - if ( RetValue ) - break; - } - return 1; -} - - -/**Function************************************************************* - - Synopsis [Computes supports of the cofactors of the function.] - - Description [This procedure should be called after Lpk_CutTruth(p,pCut,0)] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_ComputeSupports( Lpk_Man_t * p, Lpk_Cut_t * pCut, unsigned * pTruth ) -{ - unsigned * pTruthInv; - int RetValue1, RetValue2; - pTruthInv = Lpk_CutTruth( p, pCut, 1 ); - RetValue1 = Kit_CreateCloudFromTruth( p->pDsdMan->dd, pTruth, pCut->nLeaves, p->vBddDir ); - RetValue2 = Kit_CreateCloudFromTruth( p->pDsdMan->dd, pTruthInv, pCut->nLeaves, p->vBddInv ); - if ( RetValue1 && RetValue2 ) - Kit_TruthCofSupports( p->vBddDir, p->vBddInv, pCut->nLeaves, p->vMemory, p->puSupps ); - else - p->puSupps[0] = p->puSupps[1] = 0; -} - - -/**Function************************************************************* - - Synopsis [Performs resynthesis for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_ResynthesizeNodeNew( Lpk_Man_t * p ) -{ - static int Count = 0; - Abc_Obj_t * pObjNew, * pLeaf; - Lpk_Cut_t * pCut; - unsigned * pTruth; - int nNodesBef, nNodesAft, nCutNodes; - int i, k, clk; - int Required = Abc_ObjRequiredLevel(p->pObj); -// CloudNode * pFun2;//, * pFun1; - - // compute the cuts -clk = clock(); - if ( !Lpk_NodeCuts( p ) ) - { -p->timeCuts += clock() - clk; - return 0; - } -p->timeCuts += clock() - clk; - - if ( p->pPars->fVeryVerbose ) - printf( "Node %5d : Mffc size = %5d. Cuts = %5d. Level = %2d. Req = %2d.\n", - p->pObj->Id, p->nMffc, p->nEvals, p->pObj->Level, Required ); - // try the good cuts - p->nCutsTotal += p->nCuts; - p->nCutsUseful += p->nEvals; - for ( i = 0; i < p->nEvals; i++ ) - { - // get the cut - pCut = p->pCuts + p->pEvals[i]; - if ( p->pPars->fFirst && i == 1 ) - break; -// if ( pCut->Weight < 1.05 ) -// continue; - - // skip bad cuts -// printf( "Mffc size = %d. ", Abc_NodeMffcLabel(p->pObj) ); - for ( k = 0; k < (int)pCut->nLeaves; k++ ) - Abc_NtkObj(p->pNtk, pCut->pLeaves[k])->vFanouts.nSize++; - nCutNodes = Abc_NodeMffcLabel(p->pObj); -// printf( "Mffc with cut = %d. ", nCutNodes ); - for ( k = 0; k < (int)pCut->nLeaves; k++ ) - Abc_NtkObj(p->pNtk, pCut->pLeaves[k])->vFanouts.nSize--; -// printf( "Mffc cut = %d. ", (int)pCut->nNodes - (int)pCut->nNodesDup ); -// printf( "\n" ); - if ( nCutNodes != (int)pCut->nNodes - (int)pCut->nNodesDup ) - continue; - - // collect nodes into the array - Vec_PtrClear( p->vLeaves ); - for ( k = 0; k < (int)pCut->nLeaves; k++ ) - Vec_PtrPush( p->vLeaves, Abc_NtkObj(p->pNtk, pCut->pLeaves[k]) ); - - // compute the truth table -clk = clock(); - pTruth = Lpk_CutTruth( p, pCut, 0 ); -p->timeTruth += clock() - clk; -clk = clock(); - Lpk_ComputeSupports( p, pCut, pTruth ); -p->timeSupps += clock() - clk; -//clk = clock(); -// pFun1 = Lpk_CutTruthBdd( p, pCut ); -//p->timeTruth2 += clock() - clk; -/* -clk = clock(); - Cloud_Restart( p->pDsdMan->dd ); - pFun2 = Kit_TruthToCloud( p->pDsdMan->dd, pTruth, pCut->nLeaves ); - RetValue = Kit_CreateCloud( p->pDsdMan->dd, pFun2, p->vBddNodes ); -p->timeTruth3 += clock() - clk; -*/ -// if ( pFun1 != pFun2 ) -// printf( "Truth tables do not agree!\n" ); -// else -// printf( "Fine!\n" ); - - if ( p->pPars->fVeryVerbose ) - { -// char * pFileName; - int nSuppSize = Extra_TruthSupportSize( pTruth, pCut->nLeaves ); - printf( " C%02d: L= %2d/%2d V= %2d/%d N= %d W= %4.2f ", - i, pCut->nLeaves, nSuppSize, pCut->nNodes, pCut->nNodesDup, pCut->nLuts, pCut->Weight ); - Vec_PtrForEachEntry( p->vLeaves, pLeaf, k ) - printf( "%c=%d ", 'a'+k, Abc_ObjLevel(pLeaf) ); - printf( "\n" ); - Kit_DsdPrintFromTruth( pTruth, pCut->nLeaves ); -// pFileName = Kit_TruthDumpToFile( pTruth, pCut->nLeaves, Count++ ); -// printf( "Saved truth table in file \"%s\".\n", pFileName ); - } - - // update the network - nNodesBef = Abc_NtkNodeNum(p->pNtk); -clk = clock(); - pObjNew = Lpk_Decompose( p, p->pNtk, p->vLeaves, pTruth, p->puSupps, p->pPars->nLutSize, - (int)pCut->nNodes - (int)pCut->nNodesDup - 1 + (int)(p->pPars->fZeroCost > 0), Required ); -p->timeEval += clock() - clk; - nNodesAft = Abc_NtkNodeNum(p->pNtk); - - // perform replacement - if ( pObjNew ) - { - int nGain = (int)pCut->nNodes - (int)pCut->nNodesDup - (nNodesAft - nNodesBef); - assert( nGain >= 1 - p->pPars->fZeroCost ); - assert( Abc_ObjLevel(pObjNew) <= Required ); -/* - if ( nGain <= 0 ) - { - int x = 0; - } - if ( Abc_ObjLevel(pObjNew) > Required ) - { - int x = 0; - } -*/ - p->nGainTotal += nGain; - p->nChanges++; - if ( p->pPars->fVeryVerbose ) - printf( "Performed resynthesis: Gain = %2d. Level = %2d. Req = %2d.\n", nGain, Abc_ObjLevel(pObjNew), Required ); - Abc_NtkUpdate( p->pObj, pObjNew, p->vLevels ); -//printf( "%3d : %d-%d=%d(%d) \n", p->nChanges, nNodesBef, Abc_NtkNodeNum(p->pNtk), nNodesBef-Abc_NtkNodeNum(p->pNtk), nGain ); - break; - } - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Performs resynthesis for one network.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_Resynthesize( Abc_Ntk_t * pNtk, Lpk_Par_t * pPars ) -{ - ProgressBar * pProgress; - Lpk_Man_t * p; - Abc_Obj_t * pObj; - double Delta; - int i, Iter, nNodes, nNodesPrev, clk = clock(); - assert( Abc_NtkIsLogic(pNtk) ); - - // sweep dangling nodes as a preprocessing step - Abc_NtkSweep( pNtk, 0 ); - - // get the number of inputs - pPars->nLutSize = Abc_NtkGetFaninMax( pNtk ); - if ( pPars->nLutSize > 6 ) - pPars->nLutSize = 6; - if ( pPars->nLutSize < 3 ) - pPars->nLutSize = 3; - // adjust the number of crossbars based on LUT size - if ( pPars->nVarsShared > pPars->nLutSize - 2 ) - pPars->nVarsShared = pPars->nLutSize - 2; - // get the max number of LUTs tried - pPars->nVarsMax = pPars->nLutsMax * (pPars->nLutSize - 1) + 1; // V = N * (K-1) + 1 - while ( pPars->nVarsMax > 16 ) - { - pPars->nLutsMax--; - pPars->nVarsMax = pPars->nLutsMax * (pPars->nLutSize - 1) + 1; - - } - if ( pPars->fVerbose ) - { - printf( "Resynthesis for %d %d-LUTs with %d non-MFFC LUTs, %d crossbars, and %d-input cuts.\n", - pPars->nLutsMax, pPars->nLutSize, pPars->nLutsOver, pPars->nVarsShared, pPars->nVarsMax ); - } - - - // convert into the AIG - if ( !Abc_NtkToAig(pNtk) ) - { - fprintf( stdout, "Converting to BDD has failed.\n" ); - return 0; - } - assert( Abc_NtkHasAig(pNtk) ); - - // set the number of levels - Abc_NtkLevel( pNtk ); - Abc_NtkStartReverseLevels( pNtk, pPars->nGrowthLevel ); - - // start the manager - p = Lpk_ManStart( pPars ); - p->pNtk = pNtk; - p->nNodesTotal = Abc_NtkNodeNum(pNtk); - p->vLevels = Vec_VecStart( pNtk->LevelMax ); - if ( p->pPars->fSatur ) - p->vVisited = Vec_VecStart( 0 ); - if ( pPars->fVerbose ) - { - p->nTotalNets = Abc_NtkGetTotalFanins(pNtk); - p->nTotalNodes = Abc_NtkNodeNum(pNtk); - } - - // iterate over the network - nNodesPrev = p->nNodesTotal; - for ( Iter = 1; ; Iter++ ) - { - // expand storage for changed nodes - if ( p->pPars->fSatur ) - Vec_VecExpand( p->vVisited, Abc_NtkObjNumMax(pNtk) + 1 ); - - // consider all nodes - nNodes = Abc_NtkObjNumMax(pNtk); - if ( !pPars->fVeryVerbose ) - pProgress = Extra_ProgressBarStart( stdout, nNodes ); - Abc_NtkForEachNode( pNtk, pObj, i ) - { - // skip all except the final node - if ( pPars->fFirst ) - { - if ( !Abc_ObjIsCo(Abc_ObjFanout0(pObj)) ) - continue; - } - if ( i >= nNodes ) - break; - if ( !pPars->fVeryVerbose ) - Extra_ProgressBarUpdate( pProgress, i, NULL ); - // skip the nodes that did not change - if ( p->pPars->fSatur && !Lpk_NodeHasChanged(p, pObj->Id) ) - continue; - // resynthesize - p->pObj = pObj; - if ( p->pPars->fOldAlgo ) - Lpk_ResynthesizeNode( p ); - else - Lpk_ResynthesizeNodeNew( p ); - } - if ( !pPars->fVeryVerbose ) - Extra_ProgressBarStop( pProgress ); - - // check the increase - Delta = 100.00 * (nNodesPrev - Abc_NtkNodeNum(pNtk)) / p->nNodesTotal; - if ( Delta < 0.05 ) - break; - nNodesPrev = Abc_NtkNodeNum(pNtk); - if ( !p->pPars->fSatur ) - break; - - if ( pPars->fFirst ) - break; - } - Abc_NtkStopReverseLevels( pNtk ); - - if ( pPars->fVerbose ) - { -// Cloud_PrintInfo( p->pDsdMan->dd ); - p->nTotalNets2 = Abc_NtkGetTotalFanins(pNtk); - p->nTotalNodes2 = Abc_NtkNodeNum(pNtk); - printf( "Node gain = %5d. (%.2f %%) ", - p->nTotalNodes-p->nTotalNodes2, 100.0*(p->nTotalNodes-p->nTotalNodes2)/p->nTotalNodes ); - printf( "Edge gain = %5d. (%.2f %%) ", - p->nTotalNets-p->nTotalNets2, 100.0*(p->nTotalNets-p->nTotalNets2)/p->nTotalNets ); - printf( "Muxes = %4d. Dsds = %4d.", p->nMuxes, p->nDsds ); - printf( "\n" ); - printf( "Nodes = %5d (%3d) Cuts = %5d (%4d) Changes = %5d Iter = %2d Benefit = %d.\n", - p->nNodesTotal, p->nNodesOver, p->nCutsTotal, p->nCutsUseful, p->nChanges, Iter, p->nBenefited ); - - printf( "Non-DSD:" ); - for ( i = 3; i <= pPars->nVarsMax; i++ ) - if ( p->nBlocks[i] ) - printf( " %d=%d", i, p->nBlocks[i] ); - printf( "\n" ); - - p->timeTotal = clock() - clk; - p->timeEval = p->timeEval - p->timeMap; - p->timeOther = p->timeTotal - p->timeCuts - p->timeTruth - p->timeEval - p->timeMap; - PRTP( "Cuts ", p->timeCuts, p->timeTotal ); - PRTP( "Truth ", p->timeTruth, p->timeTotal ); - PRTP( "CSupps", p->timeSupps, p->timeTotal ); - PRTP( "Eval ", p->timeEval, p->timeTotal ); - PRTP( " MuxAn", p->timeEvalMuxAn, p->timeEval ); - PRTP( " MuxSp", p->timeEvalMuxSp, p->timeEval ); - PRTP( " DsdAn", p->timeEvalDsdAn, p->timeEval ); - PRTP( " DsdSp", p->timeEvalDsdSp, p->timeEval ); - PRTP( " Other", p->timeEval-p->timeEvalMuxAn-p->timeEvalMuxSp-p->timeEvalDsdAn-p->timeEvalDsdSp, p->timeEval ); - PRTP( "Map ", p->timeMap, p->timeTotal ); - PRTP( "Other ", p->timeOther, p->timeTotal ); - PRTP( "TOTAL ", p->timeTotal, p->timeTotal ); - } - - Lpk_ManStop( p ); - // check the resulting network - if ( !Abc_NtkCheck( pNtk ) ) - { - printf( "Lpk_Resynthesize: The network check has failed.\n" ); - return 0; - } - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpkCut.c b/src/opt/lpk/lpkCut.c deleted file mode 100644 index facd330b..00000000 --- a/src/opt/lpk/lpkCut.c +++ /dev/null @@ -1,683 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkCut.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkCut.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" -#include "cloud.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes the truth table of one cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -CloudNode * Lpk_CutTruthBdd_rec( CloudManager * dd, Hop_Man_t * pMan, Hop_Obj_t * pObj, int nVars ) -{ - CloudNode * pTruth, * pTruth0, * pTruth1; - assert( !Hop_IsComplement(pObj) ); - if ( pObj->pData ) - { - assert( ((unsigned)pObj->pData) & 0xffff0000 ); - return pObj->pData; - } - // get the plan for a new truth table - if ( Hop_ObjIsConst1(pObj) ) - pTruth = dd->one; - else - { - assert( Hop_ObjIsAnd(pObj) ); - // compute the truth tables of the fanins - pTruth0 = Lpk_CutTruthBdd_rec( dd, pMan, Hop_ObjFanin0(pObj), nVars ); - pTruth1 = Lpk_CutTruthBdd_rec( dd, pMan, Hop_ObjFanin1(pObj), nVars ); - pTruth0 = Cloud_NotCond( pTruth0, Hop_ObjFaninC0(pObj) ); - pTruth1 = Cloud_NotCond( pTruth1, Hop_ObjFaninC1(pObj) ); - // creat the truth table of the node - pTruth = Cloud_bddAnd( dd, pTruth0, pTruth1 ); - } - pObj->pData = pTruth; - return pTruth; -} - -/**Function************************************************************* - - Synopsis [Verifies that the factoring is correct.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -CloudNode * Lpk_CutTruthBdd( Lpk_Man_t * p, Lpk_Cut_t * pCut ) -{ - CloudManager * dd = p->pDsdMan->dd; - Hop_Man_t * pManHop = p->pNtk->pManFunc; - Hop_Obj_t * pObjHop; - Abc_Obj_t * pObj, * pFanin; - CloudNode * pTruth; - int i, k, iCount = 0; - -// return NULL; -// Lpk_NodePrintCut( p, pCut ); - // initialize the leaves - Lpk_CutForEachLeaf( p->pNtk, pCut, pObj, i ) - pObj->pCopy = (Abc_Obj_t *)dd->vars[pCut->nLeaves-1-i]; - - // construct truth table in the topological order - Lpk_CutForEachNodeReverse( p->pNtk, pCut, pObj, i ) - { - // get the local AIG - pObjHop = Hop_Regular(pObj->pData); - // clean the data field of the nodes in the AIG subgraph - Hop_ObjCleanData_rec( pObjHop ); - // set the initial truth tables at the fanins - Abc_ObjForEachFanin( pObj, pFanin, k ) - { - assert( ((unsigned)pFanin->pCopy) & 0xffff0000 ); - Hop_ManPi( pManHop, k )->pData = pFanin->pCopy; - } - // compute the truth table of internal nodes - pTruth = Lpk_CutTruthBdd_rec( dd, pManHop, pObjHop, pCut->nLeaves ); - if ( Hop_IsComplement(pObj->pData) ) - pTruth = Cloud_Not(pTruth); - // set the truth table at the node - pObj->pCopy = (Abc_Obj_t *)pTruth; - - } - -// Cloud_bddPrint( dd, pTruth ); -// printf( "Bdd size = %d. Total nodes = %d.\n", Cloud_DagSize( dd, pTruth ), dd->nNodesCur-dd->nVars-1 ); - return pTruth; -} - - -/**Function************************************************************* - - Synopsis [Computes the truth table of one cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned * Lpk_CutTruth_rec( Hop_Man_t * pMan, Hop_Obj_t * pObj, int nVars, Vec_Ptr_t * vTtNodes, int * piCount ) -{ - unsigned * pTruth, * pTruth0, * pTruth1; - assert( !Hop_IsComplement(pObj) ); - if ( pObj->pData ) - { - assert( ((unsigned)pObj->pData) & 0xffff0000 ); - return pObj->pData; - } - // get the plan for a new truth table - pTruth = Vec_PtrEntry( vTtNodes, (*piCount)++ ); - if ( Hop_ObjIsConst1(pObj) ) - Kit_TruthFill( pTruth, nVars ); - else - { - assert( Hop_ObjIsAnd(pObj) ); - // compute the truth tables of the fanins - pTruth0 = Lpk_CutTruth_rec( pMan, Hop_ObjFanin0(pObj), nVars, vTtNodes, piCount ); - pTruth1 = Lpk_CutTruth_rec( pMan, Hop_ObjFanin1(pObj), nVars, vTtNodes, piCount ); - // creat the truth table of the node - Kit_TruthAndPhase( pTruth, pTruth0, pTruth1, nVars, Hop_ObjFaninC0(pObj), Hop_ObjFaninC1(pObj) ); - } - pObj->pData = pTruth; - return pTruth; -} - -/**Function************************************************************* - - Synopsis [Computes the truth able of one cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned * Lpk_CutTruth( Lpk_Man_t * p, Lpk_Cut_t * pCut, int fInv ) -{ - Hop_Man_t * pManHop = p->pNtk->pManFunc; - Hop_Obj_t * pObjHop; - Abc_Obj_t * pObj, * pFanin; - unsigned * pTruth; - int i, k, iCount = 0; -// Lpk_NodePrintCut( p, pCut ); - assert( pCut->nNodes > 0 ); - - // initialize the leaves - Lpk_CutForEachLeaf( p->pNtk, pCut, pObj, i ) - pObj->pCopy = Vec_PtrEntry( p->vTtElems, fInv? pCut->nLeaves-1-i : i ); - - // construct truth table in the topological order - Lpk_CutForEachNodeReverse( p->pNtk, pCut, pObj, i ) - { - // get the local AIG - pObjHop = Hop_Regular(pObj->pData); - // clean the data field of the nodes in the AIG subgraph - Hop_ObjCleanData_rec( pObjHop ); - // set the initial truth tables at the fanins - Abc_ObjForEachFanin( pObj, pFanin, k ) - { - assert( ((unsigned)pFanin->pCopy) & 0xffff0000 ); - Hop_ManPi( pManHop, k )->pData = pFanin->pCopy; - } - // compute the truth table of internal nodes - pTruth = Lpk_CutTruth_rec( pManHop, pObjHop, pCut->nLeaves, p->vTtNodes, &iCount ); - if ( Hop_IsComplement(pObj->pData) ) - Kit_TruthNot( pTruth, pTruth, pCut->nLeaves ); - // set the truth table at the node - pObj->pCopy = (Abc_Obj_t *)pTruth; - } - - // make sure direct truth table is stored elsewhere (assuming the first call for direct truth!!!) - if ( fInv == 0 ) - { - pTruth = Vec_PtrEntry( p->vTtNodes, iCount++ ); - Kit_TruthCopy( pTruth, (unsigned *)pObj->pCopy, pCut->nLeaves ); - } - assert( iCount <= Vec_PtrSize(p->vTtNodes) ); - return pTruth; -} - - -/**Function************************************************************* - - Synopsis [Returns 1 if at least one entry has changed.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_NodeRecordImpact( Lpk_Man_t * p ) -{ - Lpk_Cut_t * pCut; - Vec_Ptr_t * vNodes = Vec_VecEntry( p->vVisited, p->pObj->Id ); - Abc_Obj_t * pNode; - int i, k; - // collect the nodes that impact the given node - Vec_PtrClear( vNodes ); - for ( i = 0; i < p->nCuts; i++ ) - { - pCut = p->pCuts + i; - for ( k = 0; k < (int)pCut->nLeaves; k++ ) - { - pNode = Abc_NtkObj( p->pNtk, pCut->pLeaves[k] ); - if ( pNode->fMarkC ) - continue; - pNode->fMarkC = 1; - Vec_PtrPush( vNodes, (void *)pNode->Id ); - Vec_PtrPush( vNodes, (void *)Abc_ObjFanoutNum(pNode) ); - } - } - // clear the marks - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - pNode = Abc_NtkObj( p->pNtk, (int)pNode ); - pNode->fMarkC = 0; - i++; - } -//printf( "%d ", Vec_PtrSize(vNodes) ); -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the cut has structural DSD.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_NodeCutsCheckDsd( Lpk_Man_t * p, Lpk_Cut_t * pCut ) -{ - Abc_Obj_t * pObj, * pFanin; - int i, k, nCands, fLeavesOnly, RetValue; - assert( pCut->nLeaves > 0 ); - // clear ref counters - memset( p->pRefs, 0, sizeof(int) * pCut->nLeaves ); - // mark cut leaves - Lpk_CutForEachLeaf( p->pNtk, pCut, pObj, i ) - { - assert( pObj->fMarkA == 0 ); - pObj->fMarkA = 1; - pObj->pCopy = (void *)i; - } - // ref leaves pointed from the internal nodes - nCands = 0; - Lpk_CutForEachNode( p->pNtk, pCut, pObj, i ) - { - fLeavesOnly = 1; - Abc_ObjForEachFanin( pObj, pFanin, k ) - if ( pFanin->fMarkA ) - p->pRefs[(int)pFanin->pCopy]++; - else - fLeavesOnly = 0; - if ( fLeavesOnly ) - p->pCands[nCands++] = pObj->Id; - } - // look at the nodes that only point to the leaves - RetValue = 0; - for ( i = 0; i < nCands; i++ ) - { - pObj = Abc_NtkObj( p->pNtk, p->pCands[i] ); - Abc_ObjForEachFanin( pObj, pFanin, k ) - { - assert( pFanin->fMarkA == 1 ); - if ( p->pRefs[(int)pFanin->pCopy] > 1 ) - break; - } - if ( k == Abc_ObjFaninNum(pObj) ) - { - RetValue = 1; - break; - } - } - // unmark cut leaves - Lpk_CutForEachLeaf( p->pNtk, pCut, pObj, i ) - pObj->fMarkA = 0; - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if pDom is contained in pCut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Lpk_NodeCutsOneDominance( Lpk_Cut_t * pDom, Lpk_Cut_t * pCut ) -{ - int i, k; - for ( i = 0; i < (int)pDom->nLeaves; i++ ) - { - for ( k = 0; k < (int)pCut->nLeaves; k++ ) - if ( pDom->pLeaves[i] == pCut->pLeaves[k] ) - break; - if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut - return 0; - } - // every node in pDom is contained in pCut - return 1; -} - -/**Function************************************************************* - - Synopsis [Check if the cut exists.] - - Description [Returns 1 if the cut exists.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_NodeCutsOneFilter( Lpk_Cut_t * pCuts, int nCuts, Lpk_Cut_t * pCutNew ) -{ - Lpk_Cut_t * pCut; - int i, k; - assert( pCutNew->uSign[0] || pCutNew->uSign[1] ); - // try to find the cut - for ( i = 0; i < nCuts; i++ ) - { - pCut = pCuts + i; - if ( pCut->nLeaves == 0 ) - continue; - if ( pCut->nLeaves == pCutNew->nLeaves ) - { - if ( pCut->uSign[0] == pCutNew->uSign[0] && pCut->uSign[1] == pCutNew->uSign[1] ) - { - for ( k = 0; k < (int)pCutNew->nLeaves; k++ ) - if ( pCut->pLeaves[k] != pCutNew->pLeaves[k] ) - break; - if ( k == (int)pCutNew->nLeaves ) - return 1; - } - continue; - } - if ( pCut->nLeaves < pCutNew->nLeaves ) - { - // skip the non-contained cuts - if ( (pCut->uSign[0] & pCutNew->uSign[0]) != pCut->uSign[0] ) - continue; - if ( (pCut->uSign[1] & pCutNew->uSign[1]) != pCut->uSign[1] ) - continue; - // check containment seriously - if ( Lpk_NodeCutsOneDominance( pCut, pCutNew ) ) - return 1; - continue; - } - // check potential containment of other cut - - // skip the non-contained cuts - if ( (pCut->uSign[0] & pCutNew->uSign[0]) != pCutNew->uSign[0] ) - continue; - if ( (pCut->uSign[1] & pCutNew->uSign[1]) != pCutNew->uSign[1] ) - continue; - // check containment seriously - if ( Lpk_NodeCutsOneDominance( pCutNew, pCut ) ) - pCut->nLeaves = 0; // removed - } - return 0; -} - -/**Function************************************************************* - - Synopsis [Prints the given cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_NodePrintCut( Lpk_Man_t * p, Lpk_Cut_t * pCut, int fLeavesOnly ) -{ - Abc_Obj_t * pObj; - int i; - if ( !fLeavesOnly ) - printf( "LEAVES:\n" ); - Lpk_CutForEachLeaf( p->pNtk, pCut, pObj, i ) - printf( "%d,", pObj->Id ); - if ( !fLeavesOnly ) - { - printf( "\nNODES:\n" ); - Lpk_CutForEachNode( p->pNtk, pCut, pObj, i ) - { - printf( "%d,", pObj->Id ); - assert( Abc_ObjIsNode(pObj) ); - } - printf( "\n" ); - } -} - -/**Function************************************************************* - - Synopsis [Set the cut signature.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_NodeCutSignature( Lpk_Cut_t * pCut ) -{ - unsigned i; - pCut->uSign[0] = pCut->uSign[1] = 0; - for ( i = 0; i < pCut->nLeaves; i++ ) - { - pCut->uSign[(pCut->pLeaves[i] & 32) > 0] |= (1 << (pCut->pLeaves[i] & 31)); - if ( i != pCut->nLeaves - 1 ) - assert( pCut->pLeaves[i] < pCut->pLeaves[i+1] ); - } -} - - -/**Function************************************************************* - - Synopsis [Computes the set of all cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_NodeCutsOne( Lpk_Man_t * p, Lpk_Cut_t * pCut, int Node ) -{ - Lpk_Cut_t * pCutNew; - Abc_Obj_t * pObj, * pFanin; - int i, k, j, nLeavesNew; -/* - printf( "Exploring cut " ); - Lpk_NodePrintCut( p, pCut, 1 ); - printf( "with node %d\n", Node ); -*/ - // check if the cut can stand adding one more internal node - if ( pCut->nNodes == LPK_SIZE_MAX ) - return; - - // if the node is a PI, quit - pObj = Abc_NtkObj( p->pNtk, Node ); - if ( Abc_ObjIsCi(pObj) ) - return; - assert( Abc_ObjIsNode(pObj) ); -// assert( Abc_ObjFaninNum(pObj) <= p->pPars->nLutSize ); - - // if the node is not in the MFFC, check the limit - if ( !Abc_NodeIsTravIdCurrent(pObj) ) - { - if ( (int)pCut->nNodesDup == p->pPars->nLutsOver ) - return; - assert( (int)pCut->nNodesDup < p->pPars->nLutsOver ); - } - - // check the possibility of adding this node using the signature - nLeavesNew = pCut->nLeaves - 1; - Abc_ObjForEachFanin( pObj, pFanin, i ) - { - if ( (pCut->uSign[(pFanin->Id & 32) > 0] & (1 << (pFanin->Id & 31))) ) - continue; - if ( ++nLeavesNew > p->pPars->nVarsMax ) - return; - } - - // initialize the set of leaves to the nodes in the cut - assert( p->nCuts < LPK_CUTS_MAX ); - pCutNew = p->pCuts + p->nCuts; - pCutNew->nLeaves = 0; - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - if ( pCut->pLeaves[i] != Node ) - pCutNew->pLeaves[pCutNew->nLeaves++] = pCut->pLeaves[i]; - - // add new nodes - Abc_ObjForEachFanin( pObj, pFanin, i ) - { - // find the place where this node belongs - for ( k = 0; k < (int)pCutNew->nLeaves; k++ ) - if ( pCutNew->pLeaves[k] >= pFanin->Id ) - break; - if ( k < (int)pCutNew->nLeaves && pCutNew->pLeaves[k] == pFanin->Id ) - continue; - // check if there is room - if ( (int)pCutNew->nLeaves == p->pPars->nVarsMax ) - return; - // move all the nodes - for ( j = pCutNew->nLeaves; j > k; j-- ) - pCutNew->pLeaves[j] = pCutNew->pLeaves[j-1]; - pCutNew->pLeaves[k] = pFanin->Id; - pCutNew->nLeaves++; - assert( pCutNew->nLeaves <= LPK_SIZE_MAX ); - - } - // skip the contained cuts - Lpk_NodeCutSignature( pCutNew ); - if ( Lpk_NodeCutsOneFilter( p->pCuts, p->nCuts, pCutNew ) ) - return; - - // update the set of internal nodes - assert( pCut->nNodes < LPK_SIZE_MAX ); - memcpy( pCutNew->pNodes, pCut->pNodes, pCut->nNodes * sizeof(int) ); - pCutNew->nNodes = pCut->nNodes; - pCutNew->nNodesDup = pCut->nNodesDup; - - // check if the node is already there - // if so, move the node to be the last - for ( i = 0; i < (int)pCutNew->nNodes; i++ ) - if ( pCutNew->pNodes[i] == Node ) - { - for ( k = i; k < (int)pCutNew->nNodes - 1; k++ ) - pCutNew->pNodes[k] = pCutNew->pNodes[k+1]; - pCutNew->pNodes[k] = Node; - break; - } - if ( i == (int)pCutNew->nNodes ) // new node - { - pCutNew->pNodes[ pCutNew->nNodes++ ] = Node; - pCutNew->nNodesDup += !Abc_NodeIsTravIdCurrent(pObj); - } - // the number of nodes does not exceed MFFC plus duplications - assert( pCutNew->nNodes <= p->nMffc + pCutNew->nNodesDup ); - // add the cut to storage - assert( p->nCuts < LPK_CUTS_MAX ); - p->nCuts++; -} - -/**Function************************************************************* - - Synopsis [Computes the set of all cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_NodeCuts( Lpk_Man_t * p ) -{ - Lpk_Cut_t * pCut, * pCut2; - int i, k, Temp, nMffc, fChanges; - - // mark the MFFC of the node with the current trav ID - nMffc = p->nMffc = Abc_NodeMffcLabel( p->pObj ); - assert( nMffc > 0 ); - if ( nMffc == 1 ) - return 0; - - // initialize the first cut - pCut = p->pCuts; p->nCuts = 1; - pCut->nNodes = 0; - pCut->nNodesDup = 0; - pCut->nLeaves = 1; - pCut->pLeaves[0] = p->pObj->Id; - // assign the signature - Lpk_NodeCutSignature( pCut ); - - // perform the cut computation - for ( i = 0; i < p->nCuts; i++ ) - { - pCut = p->pCuts + i; - if ( pCut->nLeaves == 0 ) - continue; - - // try to expand the fanins of this cut - for ( k = 0; k < (int)pCut->nLeaves; k++ ) - { - // create a new cut - Lpk_NodeCutsOne( p, pCut, pCut->pLeaves[k] ); - // quit if the number of cuts has exceeded the limit - if ( p->nCuts == LPK_CUTS_MAX ) - break; - } - if ( p->nCuts == LPK_CUTS_MAX ) - break; - } - if ( p->nCuts == LPK_CUTS_MAX ) - p->nNodesOver++; - - // record the impact of this node - if ( p->pPars->fSatur ) - Lpk_NodeRecordImpact( p ); - - // compress the cuts by removing empty ones, those with negative Weight, and decomposable ones - p->nEvals = 0; - for ( i = 0; i < p->nCuts; i++ ) - { - pCut = p->pCuts + i; - if ( pCut->nLeaves < 2 ) - continue; - // compute the minimum number of LUTs needed to implement this cut - // V = N * (K-1) + 1 ~~~~~ N = Ceiling[(V-1)/(K-1)] = (V-1)/(K-1) + [(V-1)%(K-1) > 0] - pCut->nLuts = Lpk_LutNumLuts( pCut->nLeaves, p->pPars->nLutSize ); -// pCut->Weight = (float)1.0 * (pCut->nNodes - pCut->nNodesDup - 1) / pCut->nLuts; //p->pPars->nLutsMax; - pCut->Weight = (float)1.0 * (pCut->nNodes - pCut->nNodesDup) / pCut->nLuts; //p->pPars->nLutsMax; - if ( pCut->Weight <= 1.001 ) -// if ( pCut->Weight <= 0.999 ) - continue; - pCut->fHasDsd = Lpk_NodeCutsCheckDsd( p, pCut ); - if ( pCut->fHasDsd ) - continue; - p->pEvals[p->nEvals++] = i; - } - if ( p->nEvals == 0 ) - return 0; - - // sort the cuts by Weight - do { - fChanges = 0; - for ( i = 0; i < p->nEvals - 1; i++ ) - { - pCut = p->pCuts + p->pEvals[i]; - pCut2 = p->pCuts + p->pEvals[i+1]; - if ( pCut->Weight >= pCut2->Weight - 0.001 ) - continue; - Temp = p->pEvals[i]; - p->pEvals[i] = p->pEvals[i+1]; - p->pEvals[i+1] = Temp; - fChanges = 1; - } - } while ( fChanges ); -/* - for ( i = 0; i < p->nEvals; i++ ) - { - pCut = p->pCuts + p->pEvals[i]; - printf( "Cut %3d : W = %5.2f.\n", i, pCut->Weight ); - } - printf( "\n" ); -*/ - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpkInt.h b/src/opt/lpk/lpkInt.h deleted file mode 100644 index 960599e4..00000000 --- a/src/opt/lpk/lpkInt.h +++ /dev/null @@ -1,246 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkInt.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [Internal declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkInt.h,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __LPK_INT_H__ -#define __LPK_INT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include "abc.h" -#include "kit.h" -#include "if.h" -#include "lpk.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -#define LPK_SIZE_MAX 24 // the largest size of the function -#define LPK_CUTS_MAX 512 // the largest number of cuts considered - -typedef struct Lpk_Man_t_ Lpk_Man_t; -typedef struct Lpk_Cut_t_ Lpk_Cut_t; - -struct Lpk_Cut_t_ -{ - unsigned nLeaves : 6; // (L) the number of leaves - unsigned nNodes : 6; // (M) the number of nodes - unsigned nNodesDup : 6; // (Q) nodes outside of MFFC - unsigned nLuts : 6; // (N) the number of LUTs to try - unsigned unused : 6; // unused - unsigned fHasDsd : 1; // set to 1 if the cut has structural DSD (and so cannot be used) - unsigned fMark : 1; // multipurpose mark - unsigned uSign[2]; // the signature - float Weight; // the weight of the cut: (M - Q)/N(V) (the larger the better) - int Gain; // the gain achieved using this cut - int pLeaves[LPK_SIZE_MAX]; // the leaves of the cut - int pNodes[LPK_SIZE_MAX]; // the nodes of the cut -}; - -struct Lpk_Man_t_ -{ - // parameters - Lpk_Par_t * pPars; // the set of parameters - // current representation - Abc_Ntk_t * pNtk; // the network - Abc_Obj_t * pObj; // the node to resynthesize - // cut representation - int nMffc; // the size of MFFC of the node - int nCuts; // the total number of cuts - int nCutsMax; // the largest possible number of cuts - int nEvals; // the number of good cuts - Lpk_Cut_t pCuts[LPK_CUTS_MAX]; // the storage for cuts - int pEvals[LPK_CUTS_MAX]; // the good cuts - // visited nodes - Vec_Vec_t * vVisited; - // mapping manager - If_Man_t * pIfMan; - Vec_Int_t * vCover; - Vec_Vec_t * vLevels; - // temporary variables - int fCofactoring; // working in the cofactoring mode - int fCalledOnce; // limits the depth of MUX cofactoring - int nCalledSRed; // the number of called to SRed - int pRefs[LPK_SIZE_MAX]; // fanin reference counters - int pCands[LPK_SIZE_MAX]; // internal nodes pointing only to the leaves - Vec_Ptr_t * vLeaves; - // truth table representation - Vec_Ptr_t * vTtElems; // elementary truth tables - Vec_Ptr_t * vTtNodes; // storage for temporary truth tables of the nodes - Vec_Int_t * vMemory; - Vec_Int_t * vBddDir; - Vec_Int_t * vBddInv; - unsigned puSupps[32]; // the supports of the cofactors - unsigned * ppTruths[5][16]; - // variable sets - Vec_Int_t * vSets[8]; - Kit_DsdMan_t* pDsdMan; - // statistics - int nNodesTotal; // total number of nodes - int nNodesOver; // nodes with cuts over the limit - int nCutsTotal; // total number of cuts - int nCutsUseful; // useful cuts - int nGainTotal; // the gain in LUTs - int nChanges; // the number of changed nodes - int nBenefited; // the number of gainful that benefited from decomposition - int nMuxes; - int nDsds; - int nTotalNets; - int nTotalNets2; - int nTotalNodes; - int nTotalNodes2; - // counter of non-DSD blocks - int nBlocks[17]; - // runtime - int timeCuts; - int timeTruth; - int timeSupps; - int timeTruth2; - int timeTruth3; - int timeEval; - int timeMap; - int timeOther; - int timeTotal; - // runtime of eval - int timeEvalMuxAn; - int timeEvalMuxSp; - int timeEvalDsdAn; - int timeEvalDsdSp; - -}; - - -// internal representation of the function to be decomposed -typedef struct Lpk_Fun_t_ Lpk_Fun_t; -struct Lpk_Fun_t_ -{ - Vec_Ptr_t * vNodes; // the array of leaves and decomposition nodes - unsigned Id : 7; // the ID of this node - unsigned nVars : 5; // the number of variables - unsigned nLutK : 4; // the number of LUT inputs - unsigned nAreaLim : 5; // the area limit (the largest allowed) - unsigned nDelayLim : 9; // the delay limit (the largest allowed) - unsigned fSupports : 1; // supports of cofactors were precomputed - unsigned fMark : 1; // marks the MUX-based dec - unsigned uSupp; // the support of this component - unsigned puSupps[32]; // the supports of the cofactors - char pDelays[16]; // the delays of the inputs - char pFanins[16]; // the fanins of this function - unsigned pTruth[0]; // the truth table (contains room for three truth tables) -}; - -// preliminary decomposition result -typedef struct Lpk_Res_t_ Lpk_Res_t; -struct Lpk_Res_t_ -{ - int nBSVars; // the number of bound set variables - unsigned BSVars; // the bound set - int nCofVars; // the number of cofactoring variables - char pCofVars[4]; // the cofactoring variables - int nSuppSizeS; // support size of the smaller (decomposed) function - int nSuppSizeL; // support size of the larger (composition) function - int DelayEst; // estimated delay of the decomposition - int AreaEst; // estimated area of the decomposition - int Variable; // variable in MUX decomposition - int Polarity; // polarity in MUX decomposition -}; - -static inline int Lpk_LutNumVars( int nLutsLim, int nLutK ) { return nLutsLim * (nLutK - 1) + 1; } -static inline int Lpk_LutNumLuts( int nVarsMax, int nLutK ) { return (nVarsMax - 1) / (nLutK - 1) + (int)((nVarsMax - 1) % (nLutK - 1) > 0); } -static inline unsigned * Lpk_FunTruth( Lpk_Fun_t * p, int Num ) { assert( Num < 3 ); return p->pTruth + Kit_TruthWordNum(p->nVars) * Num; } - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// ITERATORS /// -//////////////////////////////////////////////////////////////////////// - -#define Lpk_CutForEachLeaf( pNtk, pCut, pObj, i ) \ - for ( i = 0; (i < (int)(pCut)->nLeaves) && (((pObj) = Abc_NtkObj(pNtk, (pCut)->pLeaves[i])), 1); i++ ) -#define Lpk_CutForEachNode( pNtk, pCut, pObj, i ) \ - for ( i = 0; (i < (int)(pCut)->nNodes) && (((pObj) = Abc_NtkObj(pNtk, (pCut)->pNodes[i])), 1); i++ ) -#define Lpk_CutForEachNodeReverse( pNtk, pCut, pObj, i ) \ - for ( i = (int)(pCut)->nNodes - 1; (i >= 0) && (((pObj) = Abc_NtkObj(pNtk, (pCut)->pNodes[i])), 1); i-- ) -#define Lpk_SuppForEachVar( Supp, Var )\ - for ( Var = 0; Var < 16; Var++ )\ - if ( !(Supp & (1<<Var)) ) {} else - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== lpkAbcDec.c ============================================================*/ -extern Abc_Obj_t * Lpk_Decompose( Lpk_Man_t * pMan, Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsigned * pTruth, unsigned * puSupps, int nLutK, int AreaLim, int DelayLim ); -/*=== lpkAbcDsd.c ============================================================*/ -extern Lpk_Res_t * Lpk_DsdAnalize( Lpk_Man_t * pMan, Lpk_Fun_t * p, int nShared ); -extern Lpk_Fun_t * Lpk_DsdSplit( Lpk_Man_t * pMan, Lpk_Fun_t * p, char * pCofVars, int nCofVars, unsigned uBoundSet ); -/*=== lpkAbcMux.c ============================================================*/ -extern Lpk_Res_t * Lpk_MuxAnalize( Lpk_Man_t * pMan, Lpk_Fun_t * p ); -extern Lpk_Fun_t * Lpk_MuxSplit( Lpk_Man_t * pMan, Lpk_Fun_t * p, int Var, int Pol ); -/*=== lpkAbcUtil.c ============================================================*/ -extern Lpk_Fun_t * Lpk_FunAlloc( int nVars ); -extern void Lpk_FunFree( Lpk_Fun_t * p ); -extern Lpk_Fun_t * Lpk_FunCreate( Abc_Ntk_t * pNtk, Vec_Ptr_t * vLeaves, unsigned * pTruth, int nLutK, int AreaLim, int DelayLim ); -extern Lpk_Fun_t * Lpk_FunDup( Lpk_Fun_t * p, unsigned * pTruth ); -extern int Lpk_FunSuppMinimize( Lpk_Fun_t * p ); -extern void Lpk_FunComputeCofSupps( Lpk_Fun_t * p ); -extern int Lpk_SuppDelay( unsigned uSupp, char * pDelays ); -extern int Lpk_SuppToVars( unsigned uBoundSet, char * pVars ); - - -/*=== lpkCut.c =========================================================*/ -extern unsigned * Lpk_CutTruth( Lpk_Man_t * p, Lpk_Cut_t * pCut, int fInv ); -extern int Lpk_NodeCuts( Lpk_Man_t * p ); -/*=== lpkMap.c =========================================================*/ -extern Lpk_Man_t * Lpk_ManStart( Lpk_Par_t * pPars ); -extern void Lpk_ManStop( Lpk_Man_t * p ); -/*=== lpkMap.c =========================================================*/ -extern If_Obj_t * Lpk_MapPrime( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves ); -extern If_Obj_t * Lpk_MapTree_rec( Lpk_Man_t * p, Kit_DsdNtk_t * pNtk, If_Obj_t ** ppLeaves, int iLit, If_Obj_t * pResult ); -/*=== lpkMulti.c =======================================================*/ -extern If_Obj_t * Lpk_MapTreeMulti( Lpk_Man_t * p, unsigned * pTruth, int nLeaves, If_Obj_t ** ppLeaves ); -/*=== lpkMux.c =========================================================*/ -extern If_Obj_t * Lpk_MapTreeMux_rec( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves ); -extern If_Obj_t * Lpk_MapSuppRedDec_rec( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves ); -/*=== lpkSets.c =========================================================*/ -extern unsigned Lpk_MapSuppRedDecSelect( Lpk_Man_t * p, unsigned * pTruth, int nVars, int * piVar, int * piVarReused ); - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/lpk/lpkMan.c b/src/opt/lpk/lpkMan.c deleted file mode 100644 index af6a5307..00000000 --- a/src/opt/lpk/lpkMan.c +++ /dev/null @@ -1,122 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkMan.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Lpk_Man_t * Lpk_ManStart( Lpk_Par_t * pPars ) -{ - Lpk_Man_t * p; - int i, nWords; - assert( pPars->nLutsMax <= 16 ); - assert( pPars->nVarsMax > 0 && pPars->nVarsMax <= 16 ); - p = ALLOC( Lpk_Man_t, 1 ); - memset( p, 0, sizeof(Lpk_Man_t) ); - p->pPars = pPars; - p->nCutsMax = LPK_CUTS_MAX; - p->vTtElems = Vec_PtrAllocTruthTables( pPars->nVarsMax ); - p->vTtNodes = Vec_PtrAllocSimInfo( 1024, Abc_TruthWordNum(pPars->nVarsMax) ); - p->vCover = Vec_IntAlloc( 1 << 12 ); - p->vLeaves = Vec_PtrAlloc( 32 ); - for ( i = 0; i < 8; i++ ) - p->vSets[i] = Vec_IntAlloc(100); - p->pDsdMan = Kit_DsdManAlloc( pPars->nVarsMax, 64 ); - p->vMemory = Vec_IntAlloc( 1024 * 32 ); - p->vBddDir = Vec_IntAlloc( 256 ); - p->vBddInv = Vec_IntAlloc( 256 ); - // allocate temporary storage for truth tables - nWords = Kit_TruthWordNum(pPars->nVarsMax); - p->ppTruths[0][0] = ALLOC( unsigned, 32 * nWords ); - p->ppTruths[1][0] = p->ppTruths[0][0] + 1 * nWords; - for ( i = 1; i < 2; i++ ) - p->ppTruths[1][i] = p->ppTruths[1][0] + i * nWords; - p->ppTruths[2][0] = p->ppTruths[1][0] + 2 * nWords; - for ( i = 1; i < 4; i++ ) - p->ppTruths[2][i] = p->ppTruths[2][0] + i * nWords; - p->ppTruths[3][0] = p->ppTruths[2][0] + 4 * nWords; - for ( i = 1; i < 8; i++ ) - p->ppTruths[3][i] = p->ppTruths[3][0] + i * nWords; - p->ppTruths[4][0] = p->ppTruths[3][0] + 8 * nWords; - for ( i = 1; i < 16; i++ ) - p->ppTruths[4][i] = p->ppTruths[4][0] + i * nWords; - return p; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_ManStop( Lpk_Man_t * p ) -{ - int i; - free( p->ppTruths[0][0] ); - Vec_IntFree( p->vBddDir ); - Vec_IntFree( p->vBddInv ); - Vec_IntFree( p->vMemory ); - Kit_DsdManFree( p->pDsdMan ); - for ( i = 0; i < 8; i++ ) - Vec_IntFree(p->vSets[i]); - if ( p->pIfMan ) - { - void * pPars = p->pIfMan->pPars; - If_ManStop( p->pIfMan ); - free( pPars ); - } - if ( p->vLevels ) - Vec_VecFree( p->vLevels ); - if ( p->vVisited ) - Vec_VecFree( p->vVisited ); - Vec_PtrFree( p->vLeaves ); - Vec_IntFree( p->vCover ); - Vec_PtrFree( p->vTtElems ); - Vec_PtrFree( p->vTtNodes ); - free( p ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpkMap.c b/src/opt/lpk/lpkMap.c deleted file mode 100644 index 698aeea1..00000000 --- a/src/opt/lpk/lpkMap.c +++ /dev/null @@ -1,205 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkMap.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkMap.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Transforms the decomposition graph into the AIG.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -If_Obj_t * Lpk_MapPrimeInternal( If_Man_t * pIfMan, Kit_Graph_t * pGraph ) -{ - Kit_Node_t * pNode; - If_Obj_t * pAnd0, * pAnd1; - int i; - // check for constant function - if ( Kit_GraphIsConst(pGraph) ) - return If_ManConst1(pIfMan); - // check for a literal - if ( Kit_GraphIsVar(pGraph) ) - return Kit_GraphVar(pGraph)->pFunc; - // build the AIG nodes corresponding to the AND gates of the graph - Kit_GraphForEachNode( pGraph, pNode, i ) - { - pAnd0 = Kit_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc; - pAnd1 = Kit_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc; - pNode->pFunc = If_ManCreateAnd( pIfMan, - If_NotCond( If_Regular(pAnd0), If_IsComplement(pAnd0) ^ pNode->eEdge0.fCompl ), - If_NotCond( If_Regular(pAnd1), If_IsComplement(pAnd1) ^ pNode->eEdge1.fCompl ) ); - } - return pNode->pFunc; -} - -/**Function************************************************************* - - Synopsis [Strashes one logic node using its SOP.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -If_Obj_t * Lpk_MapPrime( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves ) -{ - Kit_Graph_t * pGraph; - Kit_Node_t * pNode; - If_Obj_t * pRes; - int i; - // derive the factored form - pGraph = Kit_TruthToGraph( pTruth, nVars, p->vCover ); - if ( pGraph == NULL ) - return NULL; - // collect the fanins - Kit_GraphForEachLeaf( pGraph, pNode, i ) - pNode->pFunc = ppLeaves[i]; - // perform strashing - pRes = Lpk_MapPrimeInternal( p->pIfMan, pGraph ); - pRes = If_NotCond( pRes, Kit_GraphIsComplement(pGraph) ); - Kit_GraphFree( pGraph ); - return pRes; -} - -/**Function************************************************************* - - Synopsis [Prepares the mapping manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -If_Obj_t * Lpk_MapTree_rec( Lpk_Man_t * p, Kit_DsdNtk_t * pNtk, If_Obj_t ** ppLeaves, int iLit, If_Obj_t * pResult ) -{ - Kit_DsdObj_t * pObj; - If_Obj_t * pObjNew = NULL, * pObjNew2 = NULL, * pFansNew[16]; - unsigned i, iLitFanin; - - assert( iLit >= 0 ); - - // consider the case of a gate - pObj = Kit_DsdNtkObj( pNtk, Kit_DsdLit2Var(iLit) ); - if ( pObj == NULL ) - { - pObjNew = ppLeaves[Kit_DsdLit2Var(iLit)]; - return If_NotCond( pObjNew, Kit_DsdLitIsCompl(iLit) ); - } - if ( pObj->Type == KIT_DSD_CONST1 ) - { - return If_NotCond( If_ManConst1(p->pIfMan), Kit_DsdLitIsCompl(iLit) ); - } - if ( pObj->Type == KIT_DSD_VAR ) - { - pObjNew = ppLeaves[Kit_DsdLit2Var(pObj->pFans[0])]; - return If_NotCond( pObjNew, Kit_DsdLitIsCompl(iLit) ^ Kit_DsdLitIsCompl(pObj->pFans[0]) ); - } - if ( pObj->Type == KIT_DSD_AND ) - { - assert( pObj->nFans == 2 ); - pFansNew[0] = Lpk_MapTree_rec( p, pNtk, ppLeaves, pObj->pFans[0], NULL ); - pFansNew[1] = pResult? pResult : Lpk_MapTree_rec( p, pNtk, ppLeaves, pObj->pFans[1], NULL ); - if ( pFansNew[0] == NULL || pFansNew[1] == NULL ) - return NULL; - pObjNew = If_ManCreateAnd( p->pIfMan, pFansNew[0], pFansNew[1] ); - return If_NotCond( pObjNew, Kit_DsdLitIsCompl(iLit) ); - } - if ( pObj->Type == KIT_DSD_XOR ) - { - int fCompl = Kit_DsdLitIsCompl(iLit); - assert( pObj->nFans == 2 ); - pFansNew[0] = Lpk_MapTree_rec( p, pNtk, ppLeaves, pObj->pFans[0], NULL ); - pFansNew[1] = pResult? pResult : Lpk_MapTree_rec( p, pNtk, ppLeaves, pObj->pFans[1], NULL ); - if ( pFansNew[0] == NULL || pFansNew[1] == NULL ) - return NULL; - fCompl ^= If_IsComplement(pFansNew[0]) ^ If_IsComplement(pFansNew[1]); - pObjNew = If_ManCreateXor( p->pIfMan, If_Regular(pFansNew[0]), If_Regular(pFansNew[1]) ); - return If_NotCond( pObjNew, fCompl ); - } - assert( pObj->Type == KIT_DSD_PRIME ); - p->nBlocks[pObj->nFans]++; - - // solve for the inputs - Kit_DsdObjForEachFanin( pNtk, pObj, iLitFanin, i ) - { - if ( i == 0 ) - pFansNew[i] = pResult? pResult : Lpk_MapTree_rec( p, pNtk, ppLeaves, iLitFanin, NULL ); - else - pFansNew[i] = Lpk_MapTree_rec( p, pNtk, ppLeaves, iLitFanin, NULL ); - if ( pFansNew[i] == NULL ) - return NULL; - } -/* - if ( !p->fCofactoring && p->pPars->nVarsShared > 0 && (int)pObj->nFans > p->pPars->nLutSize ) - { - pObjNew = Lpk_MapTreeMulti( p, Kit_DsdObjTruth(pObj), pObj->nFans, pFansNew ); - return If_NotCond( pObjNew, Kit_DsdLitIsCompl(iLit) ); - } -*/ -/* - if ( (int)pObj->nFans > p->pPars->nLutSize ) - { - pObjNew2 = Lpk_MapTreeMux_rec( p, Kit_DsdObjTruth(pObj), pObj->nFans, pFansNew ); -// if ( pObjNew2 ) -// return If_NotCond( pObjNew2, Kit_DsdLitIsCompl(iLit) ); - } -*/ - - // find best cofactoring variable - if ( p->pPars->nVarsShared > 0 && (int)pObj->nFans > p->pPars->nLutSize ) - { - pObjNew2 = Lpk_MapSuppRedDec_rec( p, Kit_DsdObjTruth(pObj), pObj->nFans, pFansNew ); - if ( pObjNew2 ) - return If_NotCond( pObjNew2, Kit_DsdLitIsCompl(iLit) ); - } - - pObjNew = Lpk_MapPrime( p, Kit_DsdObjTruth(pObj), pObj->nFans, pFansNew ); - - // add choice - if ( pObjNew && pObjNew2 ) - { - If_ObjSetChoice( If_Regular(pObjNew), If_Regular(pObjNew2) ); - If_ManCreateChoice( p->pIfMan, If_Regular(pObjNew) ); - } - return If_NotCond( pObjNew, Kit_DsdLitIsCompl(iLit) ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpkMulti.c b/src/opt/lpk/lpkMulti.c deleted file mode 100644 index 82cf3578..00000000 --- a/src/opt/lpk/lpkMulti.c +++ /dev/null @@ -1,495 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkMulti.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkMulti.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Records variable order.] - - Description [Increaments Order[x][y] by 1 if x should be above y in the DSD.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_CreateVarOrder( Kit_DsdNtk_t * pNtk, char pTable[][16] ) -{ - Kit_DsdObj_t * pObj; - unsigned uSuppFanins, k; - int Above[16], Below[16]; - int nAbove, nBelow, iFaninLit, i, x, y; - // iterate through the nodes - Kit_DsdNtkForEachObj( pNtk, pObj, i ) - { - // collect fanin support of this node - nAbove = 0; - uSuppFanins = 0; - Kit_DsdObjForEachFanin( pNtk, pObj, iFaninLit, k ) - { - if ( Kit_DsdLitIsLeaf( pNtk, iFaninLit ) ) - Above[nAbove++] = Kit_DsdLit2Var(iFaninLit); - else - uSuppFanins |= Kit_DsdLitSupport( pNtk, iFaninLit ); - } - // find the below variables - nBelow = 0; - for ( y = 0; y < 16; y++ ) - if ( uSuppFanins & (1 << y) ) - Below[nBelow++] = y; - // create all pairs - for ( x = 0; x < nAbove; x++ ) - for ( y = 0; y < nBelow; y++ ) - pTable[Above[x]][Below[y]]++; - } -} - -/**Function************************************************************* - - Synopsis [Creates commmon variable order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_CreateCommonOrder( char pTable[][16], int piCofVar[], int nCBars, int pPrios[], int nVars, int fVerbose ) -{ - int Score[16] = {0}, pPres[16]; - int i, y, x, iVarBest, ScoreMax, PrioCount; - - // mark the present variables - for ( i = 0; i < nVars; i++ ) - pPres[i] = 1; - // remove cofactored variables - for ( i = 0; i < nCBars; i++ ) - pPres[piCofVar[i]] = 0; - - // compute scores for each leaf - for ( i = 0; i < nVars; i++ ) - { - if ( pPres[i] == 0 ) - continue; - for ( y = 0; y < nVars; y++ ) - Score[i] += pTable[i][y]; - for ( x = 0; x < nVars; x++ ) - Score[i] -= pTable[x][i]; - } - - // print the scores - if ( fVerbose ) - { - printf( "Scores: " ); - for ( i = 0; i < nVars; i++ ) - printf( "%c=%d ", 'a'+i, Score[i] ); - printf( " " ); - printf( "Prios: " ); - } - - // derive variable priority - // variables with equal score receive the same priority - for ( i = 0; i < nVars; i++ ) - pPrios[i] = 16; - - // iterate until variables remain - for ( PrioCount = 1; ; PrioCount++ ) - { - // find the present variable with the highest score - iVarBest = -1; - ScoreMax = -100000; - for ( i = 0; i < nVars; i++ ) - { - if ( pPres[i] == 0 ) - continue; - if ( ScoreMax < Score[i] ) - { - ScoreMax = Score[i]; - iVarBest = i; - } - } - if ( iVarBest == -1 ) - break; - // give the next priority to all vars having this score - if ( fVerbose ) - printf( "%d=", PrioCount ); - for ( i = 0; i < nVars; i++ ) - { - if ( pPres[i] == 0 ) - continue; - if ( Score[i] == ScoreMax ) - { - pPrios[i] = PrioCount; - pPres[i] = 0; - if ( fVerbose ) - printf( "%c", 'a'+i ); - } - } - if ( fVerbose ) - printf( " " ); - } - if ( fVerbose ) - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Finds components with the highest priority.] - - Description [Returns the number of components selected.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_FindHighest( Kit_DsdNtk_t ** ppNtks, int * piLits, int nSize, int * pPrio, int * pDecision ) -{ - Kit_DsdObj_t * pObj; - unsigned uSupps[8], uSuppFanin, uSuppTotal, uSuppLarge; - int i, pTriv[8], PrioMin, iVarMax, nComps, fOneNonTriv; - - // find individual support and total support - uSuppTotal = 0; - for ( i = 0; i < nSize; i++ ) - { - pTriv[i] = 1; - if ( piLits[i] < 0 ) - uSupps[i] = 0; - else if ( Kit_DsdLitIsLeaf(ppNtks[i], piLits[i]) ) - uSupps[i] = Kit_DsdLitSupport( ppNtks[i], piLits[i] ); - else - { - pObj = Kit_DsdNtkObj( ppNtks[i], Kit_DsdLit2Var(piLits[i]) ); - if ( pObj->Type == KIT_DSD_PRIME ) - { - pTriv[i] = 0; - uSuppFanin = Kit_DsdLitSupport( ppNtks[i], pObj->pFans[0] ); - } - else - { - assert( pObj->nFans == 2 ); - if ( !Kit_DsdLitIsLeaf(ppNtks[i], pObj->pFans[0]) ) - pTriv[i] = 0; - uSuppFanin = Kit_DsdLitSupport( ppNtks[i], pObj->pFans[1] ); - } - uSupps[i] = Kit_DsdLitSupport( ppNtks[i], piLits[i] ) & ~uSuppFanin; - } - assert( uSupps[i] <= 0xFFFF ); - uSuppTotal |= uSupps[i]; - } - if ( uSuppTotal == 0 ) - return 0; - - // find one support variable with the highest priority - PrioMin = ABC_INFINITY; - iVarMax = -1; - for ( i = 0; i < 16; i++ ) - if ( uSuppTotal & (1 << i) ) - if ( PrioMin > pPrio[i] ) - { - PrioMin = pPrio[i]; - iVarMax = i; - } - assert( iVarMax != -1 ); - - // select components, which have this variable - nComps = 0; - fOneNonTriv = 0; - uSuppLarge = 0; - for ( i = 0; i < nSize; i++ ) - if ( uSupps[i] & (1<<iVarMax) ) - { - if ( pTriv[i] || !fOneNonTriv ) - { - if ( !pTriv[i] ) - { - uSuppLarge = uSupps[i]; - fOneNonTriv = 1; - } - pDecision[i] = 1; - nComps++; - } - else - pDecision[i] = 0; - } - else - pDecision[i] = 0; - - // add other non-trivial not-taken components whose support is contained in the current large component support - if ( fOneNonTriv ) - for ( i = 0; i < nSize; i++ ) - if ( !pTriv[i] && pDecision[i] == 0 && (uSupps[i] & ~uSuppLarge) == 0 ) - { - pDecision[i] = 1; - nComps++; - } - - return nComps; -} - -/**Function************************************************************* - - Synopsis [Prepares the mapping manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -If_Obj_t * Lpk_MapTreeMulti_rec( Lpk_Man_t * p, Kit_DsdNtk_t ** ppNtks, int * piLits, int * piCofVar, int nCBars, If_Obj_t ** ppLeaves, int nLeaves, int * pPrio ) -{ - Kit_DsdObj_t * pObj; - If_Obj_t * pObjsNew[4][8], * pResPrev; - int piLitsNew[8], pDecision[8]; - int i, k, nComps, nSize; - - // find which of the variables is highest in the order - nSize = (1 << nCBars); - nComps = Lpk_FindHighest( ppNtks, piLits, nSize, pPrio, pDecision ); - if ( nComps == 0 ) - return If_Not( If_ManConst1(p->pIfMan) ); - - // iterate over the nodes - if ( p->pPars->fVeryVerbose ) - printf( "Decision: " ); - for ( i = 0; i < nSize; i++ ) - { - if ( pDecision[i] ) - { - if ( p->pPars->fVeryVerbose ) - printf( "%d ", i ); - assert( piLits[i] >= 0 ); - pObj = Kit_DsdNtkObj( ppNtks[i], Kit_DsdLit2Var(piLits[i]) ); - if ( pObj == NULL ) - piLitsNew[i] = -2; - else if ( pObj->Type == KIT_DSD_PRIME ) - piLitsNew[i] = pObj->pFans[0]; - else - piLitsNew[i] = pObj->pFans[1]; - } - else - piLitsNew[i] = piLits[i]; - } - if ( p->pPars->fVeryVerbose ) - printf( "\n" ); - - // call again - pResPrev = Lpk_MapTreeMulti_rec( p, ppNtks, piLitsNew, piCofVar, nCBars, ppLeaves, nLeaves, pPrio ); - - // create new set of nodes - for ( i = 0; i < nSize; i++ ) - { - if ( pDecision[i] ) - pObjsNew[nCBars][i] = Lpk_MapTree_rec( p, ppNtks[i], ppLeaves, piLits[i], pResPrev ); - else if ( piLits[i] == -1 ) - pObjsNew[nCBars][i] = If_ManConst1(p->pIfMan); - else if ( piLits[i] == -2 ) - pObjsNew[nCBars][i] = If_Not( If_ManConst1(p->pIfMan) ); - else - pObjsNew[nCBars][i] = pResPrev; - } - - // create MUX using these outputs - for ( k = nCBars; k > 0; k-- ) - { - nSize /= 2; - for ( i = 0; i < nSize; i++ ) - pObjsNew[k-1][i] = If_ManCreateMux( p->pIfMan, pObjsNew[k][2*i+0], pObjsNew[k][2*i+1], ppLeaves[piCofVar[k-1]] ); - } - assert( nSize == 1 ); - return pObjsNew[0][0]; -} - -/**Function************************************************************* - - Synopsis [Prepares the mapping manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -If_Obj_t * Lpk_MapTreeMulti( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves ) -{ - static Counter = 0; - If_Obj_t * pResult; - Kit_DsdNtk_t * ppNtks[8] = {0}, * pTemp; - Kit_DsdObj_t * pRoot; - int piCofVar[4], pPrios[16], pFreqs[16] = {0}, piLits[16]; - int i, k, nCBars, nSize, nMemSize; - unsigned * ppCofs[4][8], uSupport; - char pTable[16][16] = {0}; - int fVerbose = p->pPars->fVeryVerbose; - - Counter++; -// printf( "Run %d.\n", Counter ); - - // allocate storage for cofactors - nMemSize = Kit_TruthWordNum(nVars); - ppCofs[0][0] = ALLOC( unsigned, 32 * nMemSize ); - nSize = 0; - for ( i = 0; i < 4; i++ ) - for ( k = 0; k < 8; k++ ) - ppCofs[i][k] = ppCofs[0][0] + nMemSize * nSize++; - assert( nSize == 32 ); - - // find the best cofactoring variables - nCBars = Kit_DsdCofactoring( pTruth, nVars, piCofVar, p->pPars->nVarsShared, 0 ); -// nCBars = 2; -// piCofVar[0] = 0; -// piCofVar[1] = 1; - - - // copy the function - Kit_TruthCopy( ppCofs[0][0], pTruth, nVars ); - - // decompose w.r.t. these variables - for ( k = 0; k < nCBars; k++ ) - { - nSize = (1 << k); - for ( i = 0; i < nSize; i++ ) - { - Kit_TruthCofactor0New( ppCofs[k+1][2*i+0], ppCofs[k][i], nVars, piCofVar[k] ); - Kit_TruthCofactor1New( ppCofs[k+1][2*i+1], ppCofs[k][i], nVars, piCofVar[k] ); - } - } - nSize = (1 << nCBars); - // compute DSD networks - for ( i = 0; i < nSize; i++ ) - { - ppNtks[i] = Kit_DsdDecompose( ppCofs[nCBars][i], nVars ); - ppNtks[i] = Kit_DsdExpand( pTemp = ppNtks[i] ); - Kit_DsdNtkFree( pTemp ); - if ( fVerbose ) - { - printf( "Cof%d%d: ", nCBars, i ); - Kit_DsdPrint( stdout, ppNtks[i] ); - } - } - - // compute variable frequences - for ( i = 0; i < nSize; i++ ) - { - uSupport = Kit_TruthSupport( ppCofs[nCBars][i], nVars ); - for ( k = 0; k < nVars; k++ ) - if ( uSupport & (1<<k) ) - pFreqs[k]++; - } - - // find common variable order - for ( i = 0; i < nSize; i++ ) - { - Kit_DsdGetSupports( ppNtks[i] ); - Lpk_CreateVarOrder( ppNtks[i], pTable ); - } - Lpk_CreateCommonOrder( pTable, piCofVar, nCBars, pPrios, nVars, fVerbose ); - // update priorities with frequences - for ( i = 0; i < nVars; i++ ) - pPrios[i] = pPrios[i] * 256 + (16 - pFreqs[i]) * 16 + i; - - if ( fVerbose ) - printf( "After restructuring with priority:\n" ); - - if ( Counter == 1 ) - { - int x = 0; - } - // transform all networks according to the variable order - for ( i = 0; i < nSize; i++ ) - { - ppNtks[i] = Kit_DsdShrink( pTemp = ppNtks[i], pPrios ); - Kit_DsdNtkFree( pTemp ); - Kit_DsdGetSupports( ppNtks[i] ); - assert( ppNtks[i]->pSupps[0] <= 0xFFFF ); - // undec nodes should be rotated in such a way that the first input has as many shared inputs as possible - Kit_DsdRotate( ppNtks[i], pFreqs ); - // print the resulting networks - if ( fVerbose ) - { - printf( "Cof%d%d: ", nCBars, i ); - Kit_DsdPrint( stdout, ppNtks[i] ); - } - } - - for ( i = 0; i < nSize; i++ ) - { - // collect the roots - pRoot = Kit_DsdNtkRoot(ppNtks[i]); - if ( pRoot->Type == KIT_DSD_CONST1 ) - piLits[i] = Kit_DsdLitIsCompl(ppNtks[i]->Root)? -2: -1; - else if ( pRoot->Type == KIT_DSD_VAR ) - piLits[i] = Kit_DsdLitNotCond( pRoot->pFans[0], Kit_DsdLitIsCompl(ppNtks[i]->Root) ); - else - piLits[i] = ppNtks[i]->Root; - } - - - // recursively construct AIG for mapping - p->fCofactoring = 1; - pResult = Lpk_MapTreeMulti_rec( p, ppNtks, piLits, piCofVar, nCBars, ppLeaves, nVars, pPrios ); - p->fCofactoring = 0; - - if ( fVerbose ) - printf( "\n" ); - - // verify the transformations - nSize = (1 << nCBars); - for ( i = 0; i < nSize; i++ ) - Kit_DsdTruth( ppNtks[i], ppCofs[nCBars][i] ); - // mux the truth tables - for ( k = nCBars-1; k >= 0; k-- ) - { - nSize = (1 << k); - for ( i = 0; i < nSize; i++ ) - Kit_TruthMuxVar( ppCofs[k][i], ppCofs[k+1][2*i+0], ppCofs[k+1][2*i+1], nVars, piCofVar[k] ); - } - if ( !Extra_TruthIsEqual( pTruth, ppCofs[0][0], nVars ) ) - printf( "Verification failed.\n" ); - - - // free the networks - for ( i = 0; i < 8; i++ ) - if ( ppNtks[i] ) - Kit_DsdNtkFree( ppNtks[i] ); - free( ppCofs[0][0] ); - - return pResult; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpkMux.c b/src/opt/lpk/lpkMux.c deleted file mode 100644 index ed046ad7..00000000 --- a/src/opt/lpk/lpkMux.c +++ /dev/null @@ -1,247 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkMux.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkMux.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Find the best cofactoring variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Lpk_MapTreeBestCofVar( Lpk_Man_t * p, unsigned * pTruth, int nVars, unsigned * pCof0, unsigned * pCof1 ) -{ - int i, iBestVar, nSuppSizeCur0, nSuppSizeCur1, nSuppSizeCur, nSuppSizeMin; - // iterate through variables - iBestVar = -1; - nSuppSizeMin = KIT_INFINITY; - for ( i = 0; i < nVars; i++ ) - { - // cofactor the functiona and get support sizes - Kit_TruthCofactor0New( pCof0, pTruth, nVars, i ); - Kit_TruthCofactor1New( pCof1, pTruth, nVars, i ); - nSuppSizeCur0 = Kit_TruthSupportSize( pCof0, nVars ); - nSuppSizeCur1 = Kit_TruthSupportSize( pCof1, nVars ); - nSuppSizeCur = nSuppSizeCur0 + nSuppSizeCur1; - // skip cofactoring that goes above the limit - if ( nSuppSizeCur0 > p->pPars->nLutSize || nSuppSizeCur1 > p->pPars->nLutSize ) - continue; - // compare this variable with other variables - if ( nSuppSizeMin > nSuppSizeCur ) - { - nSuppSizeMin = nSuppSizeCur; - iBestVar = i; - } - } - // cofactor w.r.t. this variable - if ( iBestVar != -1 ) - { - Kit_TruthCofactor0New( pCof0, pTruth, nVars, iBestVar ); - Kit_TruthCofactor1New( pCof1, pTruth, nVars, iBestVar ); - } - return iBestVar; -} - -/**Function************************************************************* - - Synopsis [Maps the function by the best cofactoring.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -If_Obj_t * Lpk_MapTreeMux_rec( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves ) -{ - unsigned * pCof0 = Vec_PtrEntry( p->vTtNodes, 0 ); - unsigned * pCof1 = Vec_PtrEntry( p->vTtNodes, 1 ); - If_Obj_t * pObj0, * pObj1; - Kit_DsdNtk_t * ppNtks[2]; - int iBestVar; - assert( nVars > 3 ); - p->fCalledOnce = 1; - // cofactor w.r.t. the best variable - iBestVar = Lpk_MapTreeBestCofVar( p, pTruth, nVars, pCof0, pCof1 ); - if ( iBestVar == -1 ) - return NULL; - // decompose the functions - ppNtks[0] = Kit_DsdDecompose( pCof0, nVars ); - ppNtks[1] = Kit_DsdDecompose( pCof1, nVars ); - if ( p->pPars->fVeryVerbose ) - { - printf( "Cofactoring w.r.t. var %c (%d -> %d+%d supp vars):\n", - 'a'+iBestVar, nVars, Kit_TruthSupportSize(pCof0, nVars), Kit_TruthSupportSize(pCof1, nVars) ); - Kit_DsdPrintExpanded( ppNtks[0] ); - Kit_DsdPrintExpanded( ppNtks[1] ); - } - // map the DSD structures - pObj0 = Lpk_MapTree_rec( p, ppNtks[0], ppLeaves, ppNtks[0]->Root, NULL ); - pObj1 = Lpk_MapTree_rec( p, ppNtks[1], ppLeaves, ppNtks[1]->Root, NULL ); - Kit_DsdNtkFree( ppNtks[0] ); - Kit_DsdNtkFree( ppNtks[1] ); - return If_ManCreateMux( p->pIfMan, pObj0, pObj1, ppLeaves[iBestVar] ); -} - - - -/**Function************************************************************* - - Synopsis [Implements support-reducing decomposition.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -If_Obj_t * Lpk_MapSuppRedDec_rec( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves ) -{ - Kit_DsdNtk_t * pNtkDec, * pNtkComp, * ppNtks[2], * pTemp; - If_Obj_t * pObjNew; - unsigned * pCof0 = Vec_PtrEntry( p->vTtNodes, 0 ); - unsigned * pCof1 = Vec_PtrEntry( p->vTtNodes, 1 ); - unsigned * pDec0 = Vec_PtrEntry( p->vTtNodes, 2 ); - unsigned * pDec1 = Vec_PtrEntry( p->vTtNodes, 3 ); - unsigned * pDec = Vec_PtrEntry( p->vTtNodes, 4 ); - unsigned * pCo00 = Vec_PtrEntry( p->vTtNodes, 5 ); - unsigned * pCo01 = Vec_PtrEntry( p->vTtNodes, 6 ); - unsigned * pCo10 = Vec_PtrEntry( p->vTtNodes, 7 ); - unsigned * pCo11 = Vec_PtrEntry( p->vTtNodes, 8 ); - unsigned * pCo0 = Vec_PtrEntry( p->vTtNodes, 9 ); - unsigned * pCo1 = Vec_PtrEntry( p->vTtNodes, 10 ); - unsigned * pCo = Vec_PtrEntry( p->vTtNodes, 11 ); - int TrueMint0, TrueMint1, FalseMint0, FalseMint1; - int uSubsets, uSubset0, uSubset1, iVar, iVarReused, i; - - // determine if supp-red decomposition exists - uSubsets = Lpk_MapSuppRedDecSelect( p, pTruth, nVars, &iVar, &iVarReused ); - if ( uSubsets == 0 ) - return NULL; - p->nCalledSRed++; - - // get the cofactors - Kit_TruthCofactor0New( pCof0, pTruth, nVars, iVar ); - Kit_TruthCofactor1New( pCof1, pTruth, nVars, iVar ); - - // get the bound sets - uSubset0 = uSubsets & 0xFFFF; - uSubset1 = uSubsets >> 16; - - // compute the decomposed functions - ppNtks[0] = Kit_DsdDecompose( pCof0, nVars ); - ppNtks[1] = Kit_DsdDecompose( pCof1, nVars ); - ppNtks[0] = Kit_DsdExpand( pTemp = ppNtks[0] ); Kit_DsdNtkFree( pTemp ); - ppNtks[1] = Kit_DsdExpand( pTemp = ppNtks[1] ); Kit_DsdNtkFree( pTemp ); - Kit_DsdTruthPartial( p->pDsdMan, ppNtks[0], pDec0, uSubset0 ); - Kit_DsdTruthPartial( p->pDsdMan, ppNtks[1], pDec1, uSubset1 ); -// Kit_DsdTruthPartialTwo( p->pDsdMan, ppNtks[0], uSubset0, iVarReused, pCo0, pDec0 ); -// Kit_DsdTruthPartialTwo( p->pDsdMan, ppNtks[1], uSubset1, iVarReused, pCo1, pDec1 ); - Kit_DsdNtkFree( ppNtks[0] ); - Kit_DsdNtkFree( ppNtks[1] ); -//Kit_DsdPrintFromTruth( pDec0, nVars ); -//Kit_DsdPrintFromTruth( pDec1, nVars ); - // get the decomposed function - Kit_TruthMuxVar( pDec, pDec0, pDec1, nVars, iVar ); - - // find any true assignments of the decomposed functions - TrueMint0 = Kit_TruthFindFirstBit( pDec0, nVars ); - TrueMint1 = Kit_TruthFindFirstBit( pDec1, nVars ); - assert( TrueMint0 >= 0 && TrueMint1 >= 0 ); - // find any false assignments of the decomposed functions - FalseMint0 = Kit_TruthFindFirstZero( pDec0, nVars ); - FalseMint1 = Kit_TruthFindFirstZero( pDec1, nVars ); - assert( FalseMint0 >= 0 && FalseMint1 >= 0 ); - - // cofactor the cofactors according to these minterms - Kit_TruthCopy( pCo00, pCof0, nVars ); - Kit_TruthCopy( pCo01, pCof0, nVars ); - for ( i = 0; i < nVars; i++ ) - if ( uSubset0 & (1 << i) ) - { - if ( FalseMint0 & (1 << i) ) - Kit_TruthCofactor1( pCo00, nVars, i ); - else - Kit_TruthCofactor0( pCo00, nVars, i ); - if ( TrueMint0 & (1 << i) ) - Kit_TruthCofactor1( pCo01, nVars, i ); - else - Kit_TruthCofactor0( pCo01, nVars, i ); - } - Kit_TruthCopy( pCo10, pCof1, nVars ); - Kit_TruthCopy( pCo11, pCof1, nVars ); - for ( i = 0; i < nVars; i++ ) - if ( uSubset1 & (1 << i) ) - { - if ( FalseMint1 & (1 << i) ) - Kit_TruthCofactor1( pCo10, nVars, i ); - else - Kit_TruthCofactor0( pCo10, nVars, i ); - if ( TrueMint1 & (1 << i) ) - Kit_TruthCofactor1( pCo11, nVars, i ); - else - Kit_TruthCofactor0( pCo11, nVars, i ); - } - - // derive the functions by composing them with the new variable (iVarReused) - Kit_TruthMuxVar( pCo0, pCo00, pCo01, nVars, iVarReused ); - Kit_TruthMuxVar( pCo1, pCo10, pCo11, nVars, iVarReused ); -//Kit_DsdPrintFromTruth( pCo0, nVars ); -//Kit_DsdPrintFromTruth( pCo1, nVars ); - - // derive the composition function - Kit_TruthMuxVar( pCo , pCo0 , pCo1 , nVars, iVar ); - - // process the decomposed function - pNtkDec = Kit_DsdDecompose( pDec, nVars ); - pNtkComp = Kit_DsdDecompose( pCo, nVars ); -//Kit_DsdPrint( stdout, pNtkDec ); -//Kit_DsdPrint( stdout, pNtkComp ); -//printf( "cofactored variable %c\n", 'a' + iVar ); -//printf( "reused variable %c\n", 'a' + iVarReused ); - - ppLeaves[iVarReused] = Lpk_MapTree_rec( p, pNtkDec, ppLeaves, pNtkDec->Root, NULL ); - pObjNew = Lpk_MapTree_rec( p, pNtkComp, ppLeaves, pNtkComp->Root, NULL ); - - Kit_DsdNtkFree( pNtkDec ); - Kit_DsdNtkFree( pNtkComp ); - return pObjNew; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpkSets.c b/src/opt/lpk/lpkSets.c deleted file mode 100644 index 90e46863..00000000 --- a/src/opt/lpk/lpkSets.c +++ /dev/null @@ -1,440 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpkSets.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpkSets.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Lpk_Set_t_ Lpk_Set_t; -struct Lpk_Set_t_ -{ - char iVar; // the cofactoring variable - char Over; // the overlap in supports - char SRed; // the support reduction - char Size; // the size of the boundset - unsigned uSubset0; // the first subset (with removed) - unsigned uSubset1; // the second subset (with removed) -}; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Recursively computes decomposable subsets.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Lpk_ComputeSets_rec( Kit_DsdNtk_t * p, int iLit, Vec_Int_t * vSets ) -{ - unsigned i, iLitFanin, uSupport, uSuppCur; - Kit_DsdObj_t * pObj; - // consider the case of simple gate - pObj = Kit_DsdNtkObj( p, Kit_DsdLit2Var(iLit) ); - if ( pObj == NULL ) - return (1 << Kit_DsdLit2Var(iLit)); - if ( pObj->Type == KIT_DSD_AND || pObj->Type == KIT_DSD_XOR ) - { - unsigned uSupps[16], Limit, s; - uSupport = 0; - Kit_DsdObjForEachFanin( p, pObj, iLitFanin, i ) - { - uSupps[i] = Lpk_ComputeSets_rec( p, iLitFanin, vSets ); - uSupport |= uSupps[i]; - } - // create all subsets, except empty and full - Limit = (1 << pObj->nFans) - 1; - for ( s = 1; s < Limit; s++ ) - { - uSuppCur = 0; - for ( i = 0; i < pObj->nFans; i++ ) - if ( s & (1 << i) ) - uSuppCur |= uSupps[i]; - Vec_IntPush( vSets, uSuppCur ); - } - return uSupport; - } - assert( pObj->Type == KIT_DSD_PRIME ); - // get the cumulative support of all fanins - uSupport = 0; - Kit_DsdObjForEachFanin( p, pObj, iLitFanin, i ) - { - uSuppCur = Lpk_ComputeSets_rec( p, iLitFanin, vSets ); - uSupport |= uSuppCur; - Vec_IntPush( vSets, uSuppCur ); - } - return uSupport; -} - -/**Function************************************************************* - - Synopsis [Computes the set of subsets of decomposable variables.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Lpk_ComputeSets( Kit_DsdNtk_t * p, Vec_Int_t * vSets ) -{ - unsigned uSupport, Entry; - int Number, i; - assert( p->nVars <= 16 ); - Vec_IntClear( vSets ); - Vec_IntPush( vSets, 0 ); - if ( Kit_DsdNtkRoot(p)->Type == KIT_DSD_CONST1 ) - return 0; - if ( Kit_DsdNtkRoot(p)->Type == KIT_DSD_VAR ) - { - uSupport = ( 1 << Kit_DsdLit2Var(Kit_DsdNtkRoot(p)->pFans[0]) ); - Vec_IntPush( vSets, uSupport ); - return uSupport; - } - uSupport = Lpk_ComputeSets_rec( p, p->Root, vSets ); - assert( (uSupport & 0xFFFF0000) == 0 ); - Vec_IntPush( vSets, uSupport ); - // set the remaining variables - Vec_IntForEachEntry( vSets, Number, i ) - { - Entry = Number; - Vec_IntWriteEntry( vSets, i, Entry | ((uSupport & ~Entry) << 16) ); - } - return uSupport; -} - -/**Function************************************************************* - - Synopsis [Prints the sets of subsets.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static void Lpk_PrintSetOne( int uSupport ) -{ - unsigned k; - for ( k = 0; k < 16; k++ ) - if ( uSupport & (1<<k) ) - printf( "%c", 'a'+k ); - printf( " " ); -} -/**Function************************************************************* - - Synopsis [Prints the sets of subsets.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static void Lpk_PrintSets( Vec_Int_t * vSets ) -{ - unsigned uSupport; - int Number, i; - printf( "Subsets(%d): ", Vec_IntSize(vSets) ); - Vec_IntForEachEntry( vSets, Number, i ) - { - uSupport = Number; - Lpk_PrintSetOne( uSupport ); - } - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Computes maximal support reducing bound-sets.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_ComposeSets( Vec_Int_t * vSets0, Vec_Int_t * vSets1, int nVars, int iCofVar, - Lpk_Set_t * pStore, int * pSize, int nSizeLimit ) -{ - static int nTravId = 0; // the number of the times this is visited - static int TravId[1<<16] = {0}; // last visited - static char SRed[1<<16]; // best support reduction - static char Over[1<<16]; // best overlaps - static unsigned Parents[1<<16]; // best set of parents - static unsigned short Used[1<<16]; // storage for used subsets - int nSuppSize, nSuppOver, nSuppRed, nUsed, nMinOver, i, k, s; - unsigned Entry, Entry0, Entry1; - unsigned uSupp, uSupp0, uSupp1, uSuppTotal; - Lpk_Set_t * pEntry; - - if ( nTravId == (1 << 30) ) - memset( TravId, 0, sizeof(int) * (1 << 16) ); - - // collect support reducing subsets - nUsed = 0; - nTravId++; - uSuppTotal = Kit_BitMask(nVars) & ~(1<<iCofVar); - Vec_IntForEachEntry( vSets0, Entry0, i ) - Vec_IntForEachEntry( vSets1, Entry1, k ) - { - uSupp0 = (Entry0 & 0xFFFF); - uSupp1 = (Entry1 & 0xFFFF); - // skip trivial - if ( uSupp0 == 0 || uSupp1 == 0 || (uSupp0 | uSupp1) == uSuppTotal ) - continue; - if ( Kit_WordHasOneBit(uSupp0) && Kit_WordHasOneBit(uSupp1) ) - continue; - // get the entry - Entry = Entry0 | Entry1; - uSupp = Entry & 0xFFFF; - // set the bound set size - nSuppSize = Kit_WordCountOnes( uSupp ); - // get the number of overlapping vars - nSuppOver = Kit_WordCountOnes( Entry & (Entry >> 16) ); - // get the support reduction - nSuppRed = nSuppSize - 1 - nSuppOver; - // only consider support-reducing subsets - if ( nSuppRed <= 0 ) - continue; - // check if this support is already used - if ( TravId[uSupp] < nTravId ) - { - Used[nUsed++] = uSupp; - - TravId[uSupp] = nTravId; - SRed[uSupp] = nSuppRed; - Over[uSupp] = nSuppOver; - Parents[uSupp] = (k << 16) | i; - } - else if ( TravId[uSupp] == nTravId && SRed[uSupp] < nSuppRed ) - { - TravId[uSupp] = nTravId; - SRed[uSupp] = nSuppRed; - Over[uSupp] = nSuppOver; - Parents[uSupp] = (k << 16) | i; - } - } - - // find the minimum overlap - nMinOver = 1000; - for ( s = 0; s < nUsed; s++ ) - if ( nMinOver > Over[Used[s]] ) - nMinOver = Over[Used[s]]; - - - // collect the accumulated ones - for ( s = 0; s < nUsed; s++ ) - if ( Over[Used[s]] == nMinOver ) - { - // save the entry - if ( *pSize == nSizeLimit ) - return; - pEntry = pStore + (*pSize)++; - - i = Parents[Used[s]] & 0xFFFF; - k = Parents[Used[s]] >> 16; - - pEntry->uSubset0 = Vec_IntEntry(vSets0, i); - pEntry->uSubset1 = Vec_IntEntry(vSets1, k); - Entry = pEntry->uSubset0 | pEntry->uSubset1; - - // record the cofactoring variable - pEntry->iVar = iCofVar; - // set the bound set size - pEntry->Size = Kit_WordCountOnes( Entry & 0xFFFF ); - // get the number of overlapping vars - pEntry->Over = Kit_WordCountOnes( Entry & (Entry >> 16) ); - // get the support reduction - pEntry->SRed = pEntry->Size - 1 - pEntry->Over; - assert( pEntry->SRed > 0 ); - } -} - -/**Function************************************************************* - - Synopsis [Prints one set.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Lpk_MapSuppPrintSet( Lpk_Set_t * pSet, int i ) -{ - unsigned Entry; - Entry = pSet->uSubset0 | pSet->uSubset1; - printf( "%2d : ", i ); - printf( "Var = %c ", 'a' + pSet->iVar ); - printf( "Size = %2d ", pSet->Size ); - printf( "Over = %2d ", pSet->Over ); - printf( "SRed = %2d ", pSet->SRed ); - Lpk_PrintSetOne( Entry ); - printf( " " ); - Lpk_PrintSetOne( Entry >> 16 ); - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Evaluates the cofactors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Lpk_MapSuppRedDecSelect( Lpk_Man_t * p, unsigned * pTruth, int nVars, int * piVar, int * piVarReused ) -{ - static int nStoreSize = 256; - static Lpk_Set_t pStore[256], * pSet, * pSetBest; - Kit_DsdNtk_t * ppNtks[2], * pTemp; - Vec_Int_t * vSets0 = p->vSets[0]; - Vec_Int_t * vSets1 = p->vSets[1]; - unsigned * pCof0 = Vec_PtrEntry( p->vTtNodes, 0 ); - unsigned * pCof1 = Vec_PtrEntry( p->vTtNodes, 1 ); - int nSets, i, SizeMax;//, SRedMax; - unsigned Entry; - int fVerbose = p->pPars->fVeryVerbose; -// int fVerbose = 0; - - // collect decomposable subsets for each pair of cofactors - if ( fVerbose ) - { - printf( "\nExploring support-reducing bound-sets of function:\n" ); - Kit_DsdPrintFromTruth( pTruth, nVars ); - } - nSets = 0; - for ( i = 0; i < nVars; i++ ) - { - if ( fVerbose ) - printf( "Evaluating variable %c:\n", 'a'+i ); - // evaluate the cofactor pair - Kit_TruthCofactor0New( pCof0, pTruth, nVars, i ); - Kit_TruthCofactor1New( pCof1, pTruth, nVars, i ); - // decompose and expand - ppNtks[0] = Kit_DsdDecompose( pCof0, nVars ); - ppNtks[1] = Kit_DsdDecompose( pCof1, nVars ); - ppNtks[0] = Kit_DsdExpand( pTemp = ppNtks[0] ); Kit_DsdNtkFree( pTemp ); - ppNtks[1] = Kit_DsdExpand( pTemp = ppNtks[1] ); Kit_DsdNtkFree( pTemp ); - if ( fVerbose ) - Kit_DsdPrint( stdout, ppNtks[0] ); - if ( fVerbose ) - Kit_DsdPrint( stdout, ppNtks[1] ); - // compute subsets - Lpk_ComputeSets( ppNtks[0], vSets0 ); - Lpk_ComputeSets( ppNtks[1], vSets1 ); - // print subsets - if ( fVerbose ) - Lpk_PrintSets( vSets0 ); - if ( fVerbose ) - Lpk_PrintSets( vSets1 ); - // free the networks - Kit_DsdNtkFree( ppNtks[0] ); - Kit_DsdNtkFree( ppNtks[1] ); - // evaluate the pair - Lpk_ComposeSets( vSets0, vSets1, nVars, i, pStore, &nSets, nStoreSize ); - } - - // print the results - if ( fVerbose ) - printf( "\n" ); - if ( fVerbose ) - for ( i = 0; i < nSets; i++ ) - Lpk_MapSuppPrintSet( pStore + i, i ); - - // choose the best subset - SizeMax = 0; - pSetBest = NULL; - for ( i = 0; i < nSets; i++ ) - { - pSet = pStore + i; - if ( pSet->Size > p->pPars->nLutSize - 1 ) - continue; - if ( SizeMax < pSet->Size ) - { - pSetBest = pSet; - SizeMax = pSet->Size; - } - } -/* - // if the best is not choosen, select the one with largest reduction - SRedMax = 0; - if ( pSetBest == NULL ) - { - for ( i = 0; i < nSets; i++ ) - { - pSet = pStore + i; - if ( SRedMax < pSet->SRed ) - { - pSetBest = pSet; - SRedMax = pSet->SRed; - } - } - } -*/ - if ( pSetBest == NULL ) - { - if ( fVerbose ) - printf( "Could not select a subset.\n" ); - return 0; - } - else - { - if ( fVerbose ) - printf( "Selected the following subset:\n" ); - if ( fVerbose ) - Lpk_MapSuppPrintSet( pSetBest, pSetBest - pStore ); - } - - // prepare the return result - // get the remaining variables - Entry = ((pSetBest->uSubset0 >> 16) | (pSetBest->uSubset1 >> 16)); - // get the variables to be removed - Entry = Kit_BitMask(nVars) & ~(1<<pSetBest->iVar) & ~Entry; - // make sure there are some - otherwise it is not supp-red - assert( Entry ); - // remember the first such variable - *piVarReused = Kit_WordFindFirstBit( Entry ); - *piVar = pSetBest->iVar; - return (pSetBest->uSubset1 << 16) | (pSetBest->uSubset0 & 0xFFFF); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/lpk_.c b/src/opt/lpk/lpk_.c deleted file mode 100644 index d8555e08..00000000 --- a/src/opt/lpk/lpk_.c +++ /dev/null @@ -1,48 +0,0 @@ -/**CFile**************************************************************** - - FileName [lpk_.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Fast Boolean matching for LUT structures.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - April 28, 2007.] - - Revision [$Id: lpk_.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "lpkInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/lpk/module.make b/src/opt/lpk/module.make deleted file mode 100644 index 26a54894..00000000 --- a/src/opt/lpk/module.make +++ /dev/null @@ -1,11 +0,0 @@ -SRC += src/opt/lpk/lpkCore.c \ - src/opt/lpk/lpkAbcDec.c \ - src/opt/lpk/lpkAbcMux.c \ - src/opt/lpk/lpkAbcDsd.c \ - src/opt/lpk/lpkAbcUtil.c \ - src/opt/lpk/lpkCut.c \ - src/opt/lpk/lpkMan.c \ - src/opt/lpk/lpkMap.c \ - src/opt/lpk/lpkMulti.c \ - src/opt/lpk/lpkMux.c \ - src/opt/lpk/lpkSets.c diff --git a/src/opt/res/module.make b/src/opt/res/module.make deleted file mode 100644 index 52d8a315..00000000 --- a/src/opt/res/module.make +++ /dev/null @@ -1,7 +0,0 @@ -SRC += src/opt/res/resCore.c \ - src/opt/res/resDivs.c \ - src/opt/res/resFilter.c \ - src/opt/res/resSat.c \ - src/opt/res/resSim.c \ - src/opt/res/resStrash.c \ - src/opt/res/resWin.c diff --git a/src/opt/res/res.h b/src/opt/res/res.h deleted file mode 100644 index 3c3431bf..00000000 --- a/src/opt/res/res.h +++ /dev/null @@ -1,75 +0,0 @@ -/**CFile**************************************************************** - - FileName [res.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: res.h,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __RES_H__ -#define __RES_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Res_Par_t_ Res_Par_t; -struct Res_Par_t_ -{ - // general parameters - int nWindow; // window size - int nGrowthLevel; // the maximum allowed growth in level after one iteration of resynthesis - int nSimWords; // the number of simulation words - int nCands; // the number of candidates to try - int fArea; // performs optimization for area - int fDelay; // performs optimization for delay - int fVerbose; // enable basic stats - int fVeryVerbose; // enable detailed stats -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== resCore.c ==========================================================*/ -extern int Abc_NtkResynthesize( Abc_Ntk_t * pNtk, Res_Par_t * pPars ); - - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/res/resCore.c b/src/opt/res/resCore.c deleted file mode 100644 index cb448fc0..00000000 --- a/src/opt/res/resCore.c +++ /dev/null @@ -1,419 +0,0 @@ -/**CFile**************************************************************** - - FileName [resCore.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [Top-level resynthesis procedure.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: resCore.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "resInt.h" -#include "kit.h" -#include "satStore.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Res_Man_t_ Res_Man_t; -struct Res_Man_t_ -{ - // general parameters - Res_Par_t * pPars; - // specialized manager - Res_Win_t * pWin; // windowing manager - Abc_Ntk_t * pAig; // the strashed window - Res_Sim_t * pSim; // simulation manager - Sto_Man_t * pCnf; // the CNF of the SAT problem - Int_Man_t * pMan; // interpolation manager; - Vec_Int_t * vMem; // memory for intermediate SOPs - Vec_Vec_t * vResubs; // resubstitution candidates of the AIG - Vec_Vec_t * vResubsW; // resubstitution candidates of the window - Vec_Vec_t * vLevels; // levelized structure for updating - // statistics - int nWins; // the number of windows tried - int nWinNodes; // the total number of window nodes - int nDivNodes; // the total number of divisors - int nWinsTriv; // the total number of trivial windows - int nWinsUsed; // the total number of useful windows (with at least one candidate) - int nConstsUsed; // the total number of constant nodes under ODC - int nCandSets; // the total number of candidates - int nProvedSets; // the total number of proved groups - int nSimEmpty; // the empty simulation info - int nTotalNets; // the total number of nets - int nTotalNodes; // the total number of nodess - int nTotalNets2; // the total number of nets - int nTotalNodes2; // the total number of nodess - // runtime - int timeWin; // windowing - int timeDiv; // divisors - int timeAig; // strashing - int timeSim; // simulation - int timeCand; // resubstitution candidates - int timeSatTotal; // SAT solving total - int timeSatSat; // SAT solving (sat calls) - int timeSatUnsat; // SAT solving (unsat calls) - int timeSatSim; // SAT solving (simulation) - int timeInt; // interpolation - int timeUpd; // updating - int timeTotal; // total runtime -}; - -extern Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph ); - -extern int s_ResynTime; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocate resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Res_Man_t * Res_ManAlloc( Res_Par_t * pPars ) -{ - Res_Man_t * p; - p = ALLOC( Res_Man_t, 1 ); - memset( p, 0, sizeof(Res_Man_t) ); - assert( pPars->nWindow > 0 && pPars->nWindow < 100 ); - assert( pPars->nCands > 0 && pPars->nCands < 100 ); - p->pPars = pPars; - p->pWin = Res_WinAlloc(); - p->pSim = Res_SimAlloc( pPars->nSimWords ); - p->pMan = Int_ManAlloc(); - p->vMem = Vec_IntAlloc( 0 ); - p->vResubs = Vec_VecStart( pPars->nCands ); - p->vResubsW = Vec_VecStart( pPars->nCands ); - p->vLevels = Vec_VecStart( 32 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Deallocate resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_ManFree( Res_Man_t * p ) -{ - if ( p->pPars->fVerbose ) - { - printf( "Reduction in nodes = %5d. (%.2f %%) ", - p->nTotalNodes-p->nTotalNodes2, - 100.0*(p->nTotalNodes-p->nTotalNodes2)/p->nTotalNodes ); - printf( "Reduction in edges = %5d. (%.2f %%) ", - p->nTotalNets-p->nTotalNets2, - 100.0*(p->nTotalNets-p->nTotalNets2)/p->nTotalNets ); - printf( "\n" ); - - printf( "Winds = %d. ", p->nWins ); - printf( "Nodes = %d. (Ave = %5.1f) ", p->nWinNodes, 1.0*p->nWinNodes/p->nWins ); - printf( "Divs = %d. (Ave = %5.1f) ", p->nDivNodes, 1.0*p->nDivNodes/p->nWins ); - printf( "\n" ); - printf( "WinsTriv = %d. ", p->nWinsTriv ); - printf( "SimsEmpt = %d. ", p->nSimEmpty ); - printf( "Const = %d. ", p->nConstsUsed ); - printf( "WindUsed = %d. ", p->nWinsUsed ); - printf( "Cands = %d. ", p->nCandSets ); - printf( "Proved = %d.", p->nProvedSets ); - printf( "\n" ); - - PRTP( "Windowing ", p->timeWin, p->timeTotal ); - PRTP( "Divisors ", p->timeDiv, p->timeTotal ); - PRTP( "Strashing ", p->timeAig, p->timeTotal ); - PRTP( "Simulation ", p->timeSim, p->timeTotal ); - PRTP( "Candidates ", p->timeCand, p->timeTotal ); - PRTP( "SAT solver ", p->timeSatTotal, p->timeTotal ); - PRTP( " sat ", p->timeSatSat, p->timeTotal ); - PRTP( " unsat ", p->timeSatUnsat, p->timeTotal ); - PRTP( " simul ", p->timeSatSim, p->timeTotal ); - PRTP( "Interpol ", p->timeInt, p->timeTotal ); - PRTP( "Undating ", p->timeUpd, p->timeTotal ); - PRTP( "TOTAL ", p->timeTotal, p->timeTotal ); - } - Res_WinFree( p->pWin ); - if ( p->pAig ) Abc_NtkDelete( p->pAig ); - Res_SimFree( p->pSim ); - if ( p->pCnf ) Sto_ManFree( p->pCnf ); - Int_ManFree( p->pMan ); - Vec_IntFree( p->vMem ); - Vec_VecFree( p->vResubs ); - Vec_VecFree( p->vResubsW ); - Vec_VecFree( p->vLevels ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Incrementally updates level of the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_UpdateNetwork( Abc_Obj_t * pObj, Vec_Ptr_t * vFanins, Hop_Obj_t * pFunc, Vec_Vec_t * vLevels ) -{ - Abc_Obj_t * pObjNew, * pFanin; - int k; - // create the new node - pObjNew = Abc_NtkCreateNode( pObj->pNtk ); - pObjNew->pData = pFunc; - Vec_PtrForEachEntry( vFanins, pFanin, k ) - Abc_ObjAddFanin( pObjNew, pFanin ); - // replace the old node by the new node - // update the level of the node - Abc_NtkUpdate( pObj, pObjNew, vLevels ); -} - -/**Function************************************************************* - - Synopsis [Entrace into the resynthesis package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkResynthesize( Abc_Ntk_t * pNtk, Res_Par_t * pPars ) -{ - ProgressBar * pProgress; - Res_Man_t * p; - Abc_Obj_t * pObj; - Hop_Obj_t * pFunc; - Kit_Graph_t * pGraph; - Vec_Ptr_t * vFanins; - unsigned * puTruth; - int i, k, RetValue, nNodesOld, nFanins, nFaninsMax; - int clk, clkTotal = clock(); - - // start the manager - p = Res_ManAlloc( pPars ); - p->nTotalNets = Abc_NtkGetTotalFanins(pNtk); - p->nTotalNodes = Abc_NtkNodeNum(pNtk); - nFaninsMax = Abc_NtkGetFaninMax(pNtk); - if ( nFaninsMax > 8 ) - nFaninsMax = 8; - - // perform the network sweep - Abc_NtkSweep( pNtk, 0 ); - - // convert into the AIG - if ( !Abc_NtkToAig(pNtk) ) - { - fprintf( stdout, "Converting to BDD has failed.\n" ); - Res_ManFree( p ); - return 0; - } - assert( Abc_NtkHasAig(pNtk) ); - - // set the number of levels - Abc_NtkLevel( pNtk ); - Abc_NtkStartReverseLevels( pNtk, pPars->nGrowthLevel ); - - // try resynthesizing nodes in the topological order - nNodesOld = Abc_NtkObjNumMax(pNtk); - pProgress = Extra_ProgressBarStart( stdout, nNodesOld ); - Abc_NtkForEachObj( pNtk, pObj, i ) - { - Extra_ProgressBarUpdate( pProgress, i, NULL ); - if ( !Abc_ObjIsNode(pObj) ) - continue; - if ( Abc_ObjFaninNum(pObj) > 8 ) - continue; - if ( pObj->Id > nNodesOld ) - break; - - // create the window for this node -clk = clock(); - RetValue = Res_WinCompute( pObj, p->pPars->nWindow/10, p->pPars->nWindow%10, p->pWin ); -p->timeWin += clock() - clk; - if ( !RetValue ) - continue; - p->nWinsTriv += Res_WinIsTrivial( p->pWin ); - - if ( p->pPars->fVeryVerbose ) - { - printf( "%5d (lev=%2d) : ", pObj->Id, pObj->Level ); - printf( "Win = %3d/%3d/%4d/%3d ", - Vec_PtrSize(p->pWin->vLeaves), - Vec_PtrSize(p->pWin->vBranches), - Vec_PtrSize(p->pWin->vNodes), - Vec_PtrSize(p->pWin->vRoots) ); - } - - // collect the divisors -clk = clock(); - Res_WinDivisors( p->pWin, Abc_ObjRequiredLevel(pObj) - 1 ); -p->timeDiv += clock() - clk; - - p->nWins++; - p->nWinNodes += Vec_PtrSize(p->pWin->vNodes); - p->nDivNodes += Vec_PtrSize( p->pWin->vDivs); - - if ( p->pPars->fVeryVerbose ) - { - printf( "D = %3d ", Vec_PtrSize(p->pWin->vDivs) ); - printf( "D+ = %3d ", p->pWin->nDivsPlus ); - } - - // create the AIG for the window -clk = clock(); - if ( p->pAig ) Abc_NtkDelete( p->pAig ); - p->pAig = Res_WndStrash( p->pWin ); -p->timeAig += clock() - clk; - - if ( p->pPars->fVeryVerbose ) - { - printf( "AIG = %4d ", Abc_NtkNodeNum(p->pAig) ); - printf( "\n" ); - } - - // prepare simulation info -clk = clock(); - RetValue = Res_SimPrepare( p->pSim, p->pAig, Vec_PtrSize(p->pWin->vLeaves), 0 ); //p->pPars->fVerbose ); -p->timeSim += clock() - clk; - if ( !RetValue ) - { - p->nSimEmpty++; - continue; - } - - // consider the case of constant node - if ( p->pSim->fConst0 || p->pSim->fConst1 ) - { - p->nConstsUsed++; - - pFunc = p->pSim->fConst1? Hop_ManConst1(pNtk->pManFunc) : Hop_ManConst0(pNtk->pManFunc); - vFanins = Vec_VecEntry( p->vResubsW, 0 ); - Vec_PtrClear( vFanins ); - Res_UpdateNetwork( pObj, vFanins, pFunc, p->vLevels ); - continue; - } - -// printf( " " ); - - // find resub candidates for the node -clk = clock(); - if ( p->pPars->fArea ) - RetValue = Res_FilterCandidates( p->pWin, p->pAig, p->pSim, p->vResubs, p->vResubsW, nFaninsMax, 1 ); - else - RetValue = Res_FilterCandidates( p->pWin, p->pAig, p->pSim, p->vResubs, p->vResubsW, nFaninsMax, 0 ); -p->timeCand += clock() - clk; - p->nCandSets += RetValue; - if ( RetValue == 0 ) - continue; - -// printf( "%d(%d) ", Vec_PtrSize(p->pWin->vDivs), RetValue ); - - p->nWinsUsed++; - - // iterate through candidate resubstitutions - Vec_VecForEachLevel( p->vResubs, vFanins, k ) - { - if ( Vec_PtrSize(vFanins) == 0 ) - break; - - // solve the SAT problem and get clauses -clk = clock(); - if ( p->pCnf ) Sto_ManFree( p->pCnf ); - p->pCnf = Res_SatProveUnsat( p->pAig, vFanins ); - if ( p->pCnf == NULL ) - { -p->timeSatSat += clock() - clk; -// printf( " Sat\n" ); -// printf( "-" ); - continue; - } -p->timeSatUnsat += clock() - clk; -// printf( "+" ); - - p->nProvedSets++; -// printf( " Unsat\n" ); -// continue; -// printf( "Proved %d.\n", k ); - - // write it into a file -// Sto_ManDumpClauses( p->pCnf, "trace.cnf" ); - - // interpolate the problem if it was UNSAT -clk = clock(); - nFanins = Int_ManInterpolate( p->pMan, p->pCnf, 0, &puTruth ); -p->timeInt += clock() - clk; - if ( nFanins != Vec_PtrSize(vFanins) - 2 ) - continue; - assert( puTruth ); -// Extra_PrintBinary( stdout, puTruth, 1 << nFanins ); printf( "\n" ); - - // transform interpolant into the AIG - pGraph = Kit_TruthToGraph( puTruth, nFanins, p->vMem ); - - // derive the AIG for the decomposition tree - pFunc = Kit_GraphToHop( pNtk->pManFunc, pGraph ); - Kit_GraphFree( pGraph ); - - // update the network -clk = clock(); - Res_UpdateNetwork( pObj, Vec_VecEntry(p->vResubsW, k), pFunc, p->vLevels ); -p->timeUpd += clock() - clk; - break; - } -// printf( "\n" ); - } - Extra_ProgressBarStop( pProgress ); - Abc_NtkStopReverseLevels( pNtk ); - -p->timeSatSim += p->pSim->timeSat; -p->timeSatTotal = p->timeSatSat + p->timeSatUnsat + p->timeSatSim; - - p->nTotalNets2 = Abc_NtkGetTotalFanins(pNtk); - p->nTotalNodes2 = Abc_NtkNodeNum(pNtk); - - // quit resubstitution manager -p->timeTotal = clock() - clkTotal; - Res_ManFree( p ); - -s_ResynTime += clock() - clkTotal; - // check the resulting network - if ( !Abc_NtkCheck( pNtk ) ) - { - fprintf( stdout, "Abc_NtkResynthesize(): Network check has failed.\n" ); - return 0; - } - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/res/resDivs.c b/src/opt/res/resDivs.c deleted file mode 100644 index cc75b90f..00000000 --- a/src/opt/res/resDivs.c +++ /dev/null @@ -1,285 +0,0 @@ -/**CFile**************************************************************** - - FileName [resDivs.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [Collect divisors for the given window.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: resDivs.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "resInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Res_WinMarkTfi( Res_Win_t * p ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Adds candidate divisors of the node to its window.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_WinDivisors( Res_Win_t * p, int nLevDivMax ) -{ - Abc_Obj_t * pObj, * pFanout, * pFanin; - int k, f, m; - - // set the maximum level of the divisors - p->nLevDivMax = nLevDivMax; - - // mark the TFI with the current trav ID - Abc_NtkIncrementTravId( p->pNode->pNtk ); - Res_WinMarkTfi( p ); - - // mark with the current trav ID those nodes that should not be divisors: - // (1) the node and its TFO - // (2) the MFFC of the node - // (3) the node's fanins (these are treated as a special case) - Abc_NtkIncrementTravId( p->pNode->pNtk ); - Res_WinSweepLeafTfo_rec( p->pNode, p->nLevDivMax ); - Res_WinVisitMffc( p->pNode ); - Abc_ObjForEachFanin( p->pNode, pObj, k ) - Abc_NodeSetTravIdCurrent( pObj ); - - // at this point the nodes are marked with two trav IDs: - // nodes to be collected as divisors are marked with previous trav ID - // nodes to be avoided as divisors are marked with current trav ID - - // start collecting the divisors - Vec_PtrClear( p->vDivs ); - Vec_PtrForEachEntry( p->vLeaves, pObj, k ) - { - assert( (int)pObj->Level >= p->nLevLeafMin ); - if ( !Abc_NodeIsTravIdPrevious(pObj) ) - continue; - if ( (int)pObj->Level > p->nLevDivMax ) - continue; - Vec_PtrPush( p->vDivs, pObj ); - } - // add the internal nodes to the data structure - Vec_PtrForEachEntry( p->vNodes, pObj, k ) - { - if ( !Abc_NodeIsTravIdPrevious(pObj) ) - continue; - if ( (int)pObj->Level > p->nLevDivMax ) - continue; - Vec_PtrPush( p->vDivs, pObj ); - } - - // explore the fanouts of already collected divisors - p->nDivsPlus = 0; - Vec_PtrForEachEntry( p->vDivs, pObj, k ) - { - // consider fanouts of this node - Abc_ObjForEachFanout( pObj, pFanout, f ) - { - // stop if there are too many fanouts - if ( f > 20 ) - break; - // skip nodes that are already added - if ( Abc_NodeIsTravIdPrevious(pFanout) ) - continue; - // skip nodes in the TFO or in the MFFC of node - if ( Abc_NodeIsTravIdCurrent(pFanout) ) - continue; - // skip COs - if ( !Abc_ObjIsNode(pFanout) ) - continue; - // skip nodes with large level - if ( (int)pFanout->Level >= p->nLevDivMax ) - continue; - // skip nodes whose fanins are not divisors - Abc_ObjForEachFanin( pFanout, pFanin, m ) - if ( !Abc_NodeIsTravIdPrevious(pFanin) ) - break; - if ( m < Abc_ObjFaninNum(pFanout) ) - continue; - // add the node to the divisors - Vec_PtrPush( p->vDivs, pFanout ); - Vec_PtrPush( p->vNodes, pFanout ); - Abc_NodeSetTravIdPrevious( pFanout ); - p->nDivsPlus++; - } - } -/* - printf( "Node level = %d. ", Abc_ObjLevel(p->pNode) ); - Vec_PtrForEachEntryStart( p->vDivs, pObj, k, Vec_PtrSize(p->vDivs)-p->nDivsPlus ) - printf( "%d ", Abc_ObjLevel(pObj) ); - printf( "\n" ); -*/ -//printf( "%d ", p->nDivsPlus ); -} - -/**Function************************************************************* - - Synopsis [Marks the TFI cone of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_WinMarkTfi_rec( Res_Win_t * p, Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanin; - int i; - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return; - Abc_NodeSetTravIdCurrent( pObj ); - assert( Abc_ObjIsNode(pObj) ); - // visit the fanins of the node - Abc_ObjForEachFanin( pObj, pFanin, i ) - Res_WinMarkTfi_rec( p, pFanin ); -} - -/**Function************************************************************* - - Synopsis [Marks the TFI cone of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_WinMarkTfi( Res_Win_t * p ) -{ - Abc_Obj_t * pObj; - int i; - // mark the leaves - Vec_PtrForEachEntry( p->vLeaves, pObj, i ) - Abc_NodeSetTravIdCurrent( pObj ); - // start from the node - Res_WinMarkTfi_rec( p, p->pNode ); -} - -/**Function************************************************************* - - Synopsis [Marks the TFO of the collected nodes up to the given level.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_WinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit ) -{ - Abc_Obj_t * pFanout; - int i; - if ( Abc_ObjIsCo(pObj) || (int)pObj->Level > nLevelLimit ) - return; - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return; - Abc_NodeSetTravIdCurrent( pObj ); - Abc_ObjForEachFanout( pObj, pFanout, i ) - Res_WinSweepLeafTfo_rec( pFanout, nLevelLimit ); -} - -/**Function************************************************************* - - Synopsis [Dereferences the node's MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_NodeDeref_rec( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pFanin; - int i, Counter = 1; - if ( Abc_ObjIsCi(pNode) ) - return 0; - Abc_NodeSetTravIdCurrent( pNode ); - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - assert( pFanin->vFanouts.nSize > 0 ); - if ( --pFanin->vFanouts.nSize == 0 ) - Counter += Res_NodeDeref_rec( pFanin ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [References the node's MFFC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_NodeRef_rec( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pFanin; - int i, Counter = 1; - if ( Abc_ObjIsCi(pNode) ) - return 0; - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - if ( pFanin->vFanouts.nSize++ == 0 ) - Counter += Res_NodeRef_rec( pFanin ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Labels MFFC of the node with the current trav ID.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_WinVisitMffc( Abc_Obj_t * pNode ) -{ - int Count1, Count2; - assert( Abc_ObjIsNode(pNode) ); - // dereference the node (mark with the current trav ID) - Count1 = Res_NodeDeref_rec( pNode ); - // reference it back - Count2 = Res_NodeRef_rec( pNode ); - assert( Count1 == Count2 ); - return Count1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/res/resFilter.c b/src/opt/res/resFilter.c deleted file mode 100644 index f2ca41d3..00000000 --- a/src/opt/res/resFilter.c +++ /dev/null @@ -1,434 +0,0 @@ -/**CFile**************************************************************** - - FileName [resFilter.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [Filtering resubstitution candidates.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: resFilter.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "resInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static unsigned * Res_FilterCollectFaninInfo( Res_Win_t * pWin, Res_Sim_t * pSim, unsigned uMask ); -static int Res_FilterCriticalFanin( Abc_Obj_t * pNode ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Finds sets of feasible candidates.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW, int nFaninsMax, int fArea ) -{ - Abc_Obj_t * pFanin, * pFanin2, * pFaninTemp; - unsigned * pInfo, * pInfoDiv, * pInfoDiv2; - int Counter, RetValue, i, i2, d, d2, iDiv, iDiv2, k; - - // check that the info the node is one - pInfo = Vec_PtrEntry( pSim->vOuts, 1 ); - RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut ); - if ( RetValue == 0 ) - { -// printf( "Failed 1!\n" ); - return 0; - } - - // collect the fanin info - pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~0 ); - RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut ); - if ( RetValue == 0 ) - { -// printf( "Failed 2!\n" ); - return 0; - } - - // try removing each fanin -// printf( "Fanins: " ); - Counter = 0; - Vec_VecClear( vResubs ); - Vec_VecClear( vResubsW ); - Abc_ObjForEachFanin( pWin->pNode, pFanin, i ) - { - if ( fArea && Abc_ObjFanoutNum(pFanin) > 1 ) - continue; - // get simulation info without this fanin - pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << i) ); - RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut ); - if ( RetValue ) - { -// printf( "Node %4d. Candidate fanin %4d.\n", pWin->pNode->Id, pFanin->Id ); - // collect the nodes - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); - Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k ) - { - if ( k != i ) - { - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); - Vec_VecPush( vResubsW, Counter, pFaninTemp ); - } - } - Counter++; - if ( Counter == Vec_VecSize(vResubs) ) - return Counter; - } - } - - // try replacing each critical fanin by a non-critical fanin - Abc_ObjForEachFanin( pWin->pNode, pFanin, i ) - { - if ( Abc_ObjFanoutNum(pFanin) > 1 ) - continue; - // get simulation info without this fanin - pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << i) ); - // go over the set of divisors - for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ ) - { - pInfoDiv = Vec_PtrEntry( pSim->vOuts, d ); - iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2); - if ( !Abc_InfoIsOrOne( pInfo, pInfoDiv, pSim->nWordsOut ) ) - continue; - // collect the nodes - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); - // collect the remaning fanins and the divisor - Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k ) - { - if ( k != i ) - { - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); - Vec_VecPush( vResubsW, Counter, pFaninTemp ); - } - } - // collect the divisor - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) ); - Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) ); - Counter++; - if ( Counter == Vec_VecSize(vResubs) ) - return Counter; - } - } - - // consider the case when two fanins can be added instead of one - if ( Abc_ObjFaninNum(pWin->pNode) < nFaninsMax ) - { - // try to replace each critical fanin by two non-critical fanins - Abc_ObjForEachFanin( pWin->pNode, pFanin, i ) - { - if ( Abc_ObjFanoutNum(pFanin) > 1 ) - continue; - // get simulation info without this fanin - pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << i) ); - // go over the set of divisors - for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ ) - { - pInfoDiv = Vec_PtrEntry( pSim->vOuts, d ); - iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2); - // go through the second divisor - for ( d2 = d + 1; d2 < Abc_NtkPoNum(pAig); d2++ ) - { - pInfoDiv2 = Vec_PtrEntry( pSim->vOuts, d2 ); - iDiv2 = d2 - (Abc_ObjFaninNum(pWin->pNode) + 2); - if ( !Abc_InfoIsOrOne3( pInfo, pInfoDiv, pInfoDiv2, pSim->nWordsOut ) ) - continue; - // collect the nodes - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); - // collect the remaning fanins and the divisor - Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k ) - { - if ( k != i ) - { - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); - Vec_VecPush( vResubsW, Counter, pFaninTemp ); - } - } - // collect the divisor - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) ); - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d2) ); - Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) ); - Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv2) ); - Counter++; - if ( Counter == Vec_VecSize(vResubs) ) - return Counter; - } - } - } - } - - // try to replace two nets by one - if ( !fArea ) - { - Abc_ObjForEachFanin( pWin->pNode, pFanin, i ) - { - for ( i2 = i + 1; i2 < Abc_ObjFaninNum(pWin->pNode); i2++ ) - { - pFanin2 = Abc_ObjFanin(pWin->pNode, i2); - // get simulation info without these fanins - pInfo = Res_FilterCollectFaninInfo( pWin, pSim, (~(1 << i)) & (~(1 << i2)) ); - // go over the set of divisors - for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ ) - { - pInfoDiv = Vec_PtrEntry( pSim->vOuts, d ); - iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2); - if ( !Abc_InfoIsOrOne( pInfo, pInfoDiv, pSim->nWordsOut ) ) - continue; - // collect the nodes - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); - // collect the remaning fanins and the divisor - Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k ) - { - if ( k != i && k != i2 ) - { - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); - Vec_VecPush( vResubsW, Counter, pFaninTemp ); - } - } - // collect the divisor - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) ); - Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) ); - Counter++; - if ( Counter == Vec_VecSize(vResubs) ) - return Counter; - } - } - } - } - return Counter; -} - - -/**Function************************************************************* - - Synopsis [Finds sets of feasible candidates.] - - Description [This procedure is a special case of the above.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_FilterCandidatesArea( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW, int nFaninsMax ) -{ - Abc_Obj_t * pFanin; - unsigned * pInfo, * pInfoDiv, * pInfoDiv2; - int Counter, RetValue, d, d2, k, iDiv, iDiv2, iBest; - - // check that the info the node is one - pInfo = Vec_PtrEntry( pSim->vOuts, 1 ); - RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut ); - if ( RetValue == 0 ) - { -// printf( "Failed 1!\n" ); - return 0; - } - - // collect the fanin info - pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~0 ); - RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut ); - if ( RetValue == 0 ) - { -// printf( "Failed 2!\n" ); - return 0; - } - - // try removing fanins -// printf( "Fanins: " ); - Counter = 0; - Vec_VecClear( vResubs ); - Vec_VecClear( vResubsW ); - // get the best fanins - iBest = Res_FilterCriticalFanin( pWin->pNode ); - if ( iBest == -1 ) - return 0; - - // get the info without the critical fanin - pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << iBest) ); - RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut ); - if ( RetValue ) - { -// printf( "Can be done without one!\n" ); - // collect the nodes - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); - Abc_ObjForEachFanin( pWin->pNode, pFanin, k ) - { - if ( k != iBest ) - { - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); - Vec_VecPush( vResubsW, Counter, pFanin ); - } - } - Counter++; -// printf( "*" ); - return Counter; - } - - // go through the divisors - for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ ) - { - pInfoDiv = Vec_PtrEntry( pSim->vOuts, d ); - iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2); - if ( !Abc_InfoIsOrOne( pInfo, pInfoDiv, pSim->nWordsOut ) ) - continue; -//if ( Abc_ObjLevel(pWin->pNode) <= Abc_ObjLevel( Vec_PtrEntry(pWin->vDivs, iDiv) ) ) -// printf( "Node level = %d. Divisor level = %d.\n", Abc_ObjLevel(pWin->pNode), Abc_ObjLevel( Vec_PtrEntry(pWin->vDivs, iDiv) ) ); - // collect the nodes - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); - // collect the remaning fanins and the divisor - Abc_ObjForEachFanin( pWin->pNode, pFanin, k ) - { - if ( k != iBest ) - { - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); - Vec_VecPush( vResubsW, Counter, pFanin ); - } - } - // collect the divisor - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) ); - Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) ); - Counter++; - - if ( Counter == Vec_VecSize(vResubs) ) - break; - } - - if ( Counter > 0 || Abc_ObjFaninNum(pWin->pNode) >= nFaninsMax ) - return Counter; - - // try to find the node pairs - for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ ) - { - pInfoDiv = Vec_PtrEntry( pSim->vOuts, d ); - iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2); - // go through the second divisor - for ( d2 = d + 1; d2 < Abc_NtkPoNum(pAig); d2++ ) - { - pInfoDiv2 = Vec_PtrEntry( pSim->vOuts, d2 ); - iDiv2 = d2 - (Abc_ObjFaninNum(pWin->pNode) + 2); - - if ( !Abc_InfoIsOrOne3( pInfo, pInfoDiv, pInfoDiv2, pSim->nWordsOut ) ) - continue; - // collect the nodes - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) ); - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) ); - // collect the remaning fanins and the divisor - Abc_ObjForEachFanin( pWin->pNode, pFanin, k ) - { - if ( k != iBest ) - { - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) ); - Vec_VecPush( vResubsW, Counter, pFanin ); - } - } - // collect the divisor - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) ); - Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d2) ); - Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) ); - Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv2) ); - Counter++; - - if ( Counter == Vec_VecSize(vResubs) ) - break; - } - if ( Counter == Vec_VecSize(vResubs) ) - break; - } - return Counter; -} - - -/**Function************************************************************* - - Synopsis [Finds sets of feasible candidates.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned * Res_FilterCollectFaninInfo( Res_Win_t * pWin, Res_Sim_t * pSim, unsigned uMask ) -{ - Abc_Obj_t * pFanin; - unsigned * pInfo; - int i; - pInfo = Vec_PtrEntry( pSim->vOuts, 0 ); - Abc_InfoClear( pInfo, pSim->nWordsOut ); - Abc_ObjForEachFanin( pWin->pNode, pFanin, i ) - { - if ( uMask & (1 << i) ) - Abc_InfoOr( pInfo, Vec_PtrEntry(pSim->vOuts, 2+i), pSim->nWordsOut ); - } - return pInfo; -} - - -/**Function************************************************************* - - Synopsis [Returns the index of the most critical fanin.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_FilterCriticalFanin( Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pFanin; - int i, iBest = -1, CostMax = 0, CostCur; - Abc_ObjForEachFanin( pNode, pFanin, i ) - { - if ( !Abc_ObjIsNode(pFanin) ) - continue; - if ( Abc_ObjFanoutNum(pFanin) > 1 ) - continue; - CostCur = Res_WinVisitMffc( pFanin ); - if ( CostMax < CostCur ) - { - CostMax = CostCur; - iBest = i; - } - } -// if ( CostMax > 0 ) -// printf( "<%d>", CostMax ); - return iBest; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/res/resInt.h b/src/opt/res/resInt.h deleted file mode 100644 index 5aae46cc..00000000 --- a/src/opt/res/resInt.h +++ /dev/null @@ -1,137 +0,0 @@ -/**CFile**************************************************************** - - FileName [resInt.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [Internal declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: resInt.h,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __RES_INT_H__ -#define __RES_INT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include "res.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Res_Win_t_ Res_Win_t; -struct Res_Win_t_ -{ - // windowing parameters - Abc_Obj_t * pNode; // the node in the center - int nWinTfiMax; // the fanin levels - int nWinTfoMax; // the fanout levels - int nLevDivMax; // the maximum divisor level - // internal windowing parameters - int nFanoutLimit; // the limit on the fanout count of a TFO node (if more, the node is treated as a root) - int nLevTfiMinus; // the number of additional levels to search from TFO below the level of leaves - // derived windowing parameters - int nLevLeafMin; // the minimum level of a leaf - int nLevTravMin; // the minimum level to search from TFO - int nDivsPlus; // the number of additional divisors - // the window data - Vec_Ptr_t * vRoots; // outputs of the window - Vec_Ptr_t * vLeaves; // inputs of the window - Vec_Ptr_t * vBranches; // side nodes of the window - Vec_Ptr_t * vNodes; // internal nodes of the window - Vec_Ptr_t * vDivs; // candidate divisors of the node - // temporary data - Vec_Vec_t * vMatrix; // TFI nodes below the given node -}; - -typedef struct Res_Sim_t_ Res_Sim_t; -struct Res_Sim_t_ -{ - Abc_Ntk_t * pAig; // AIG for simulation - int nTruePis; // the number of true PIs of the window - int fConst0; // the node can be replaced by constant 0 - int fConst1; // the node can be replaced by constant 0 - // simulation parameters - int nWords; // the number of simulation words - int nPats; // the number of patterns - int nWordsIn; // the number of simulation words in the input patterns - int nPatsIn; // the number of patterns in the input patterns - int nBytesIn; // the number of bytes in the input patterns - int nWordsOut; // the number of simulation words in the output patterns - int nPatsOut; // the number of patterns in the output patterns - // simulation info - Vec_Ptr_t * vPats; // input simulation patterns - Vec_Ptr_t * vPats0; // input simulation patterns - Vec_Ptr_t * vPats1; // input simulation patterns - Vec_Ptr_t * vOuts; // output simulation info - int nPats0; // the number of 0-patterns accumulated - int nPats1; // the number of 1-patterns accumulated - // resub candidates - Vec_Vec_t * vCands; // resubstitution candidates - // statistics - int timeSat; -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== resDivs.c ==========================================================*/ -extern void Res_WinDivisors( Res_Win_t * p, int nLevDivMax ); -extern void Res_WinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit ); -extern int Res_WinVisitMffc( Abc_Obj_t * pNode ); -/*=== resFilter.c ==========================================================*/ -extern int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW, int nFaninsMax, int fArea ); -extern int Res_FilterCandidatesArea( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW, int nFaninsMax ); -/*=== resSat.c ==========================================================*/ -extern void * Res_SatProveUnsat( Abc_Ntk_t * pAig, Vec_Ptr_t * vFanins ); -extern int Res_SatSimulate( Res_Sim_t * p, int nPats, int fOnSet ); -/*=== resSim.c ==========================================================*/ -extern Res_Sim_t * Res_SimAlloc( int nWords ); -extern void Res_SimFree( Res_Sim_t * p ); -extern int Res_SimPrepare( Res_Sim_t * p, Abc_Ntk_t * pAig, int nTruePis, int fVerbose ); -/*=== resStrash.c ==========================================================*/ -extern Abc_Ntk_t * Res_WndStrash( Res_Win_t * p ); -/*=== resWnd.c ==========================================================*/ -extern void Res_UpdateNetwork( Abc_Obj_t * pObj, Vec_Ptr_t * vFanins, Hop_Obj_t * pFunc, Vec_Vec_t * vLevels ); -/*=== resWnd.c ==========================================================*/ -extern Res_Win_t * Res_WinAlloc(); -extern void Res_WinFree( Res_Win_t * p ); -extern int Res_WinIsTrivial( Res_Win_t * p ); -extern int Res_WinCompute( Abc_Obj_t * pNode, int nWinTfiMax, int nWinTfoMax, Res_Win_t * p ); - - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/res/resSat.c b/src/opt/res/resSat.c deleted file mode 100644 index dd0e7a23..00000000 --- a/src/opt/res/resSat.c +++ /dev/null @@ -1,407 +0,0 @@ -/**CFile**************************************************************** - - FileName [resSat.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [Interface with the SAT solver.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: resSat.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "resInt.h" -#include "hop.h" -#include "satSolver.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -extern int Res_SatAddConst1( sat_solver * pSat, int iVar, int fCompl ); -extern int Res_SatAddEqual( sat_solver * pSat, int iVar0, int iVar1, int fCompl ); -extern int Res_SatAddAnd( sat_solver * pSat, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1 ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Loads AIG into the SAT solver for checking resubstitution.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Res_SatProveUnsat( Abc_Ntk_t * pAig, Vec_Ptr_t * vFanins ) -{ - void * pCnf = NULL; - sat_solver * pSat; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj; - int i, nNodes, status; - - // make sure fanins contain POs of the AIG - pObj = Vec_PtrEntry( vFanins, 0 ); - assert( pObj->pNtk == pAig && Abc_ObjIsPo(pObj) ); - - // collect reachable nodes - vNodes = Abc_NtkDfsNodes( pAig, (Abc_Obj_t **)vFanins->pArray, vFanins->nSize ); - - // assign unique numbers to each node - nNodes = 0; - Abc_AigConst1(pAig)->pCopy = (void *)nNodes++; - Abc_NtkForEachPi( pAig, pObj, i ) - pObj->pCopy = (void *)nNodes++; - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = (void *)nNodes++; - Vec_PtrForEachEntry( vFanins, pObj, i ) // useful POs - pObj->pCopy = (void *)nNodes++; - - // start the solver - pSat = sat_solver_new(); - sat_solver_store_alloc( pSat ); - - // add clause for the constant node - Res_SatAddConst1( pSat, (int)Abc_AigConst1(pAig)->pCopy, 0 ); - // add clauses for AND gates - Vec_PtrForEachEntry( vNodes, pObj, i ) - Res_SatAddAnd( pSat, (int)pObj->pCopy, - (int)Abc_ObjFanin0(pObj)->pCopy, (int)Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); - Vec_PtrFree( vNodes ); - // add clauses for POs - Vec_PtrForEachEntry( vFanins, pObj, i ) - Res_SatAddEqual( pSat, (int)pObj->pCopy, - (int)Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) ); - // add trivial clauses - pObj = Vec_PtrEntry(vFanins, 0); - Res_SatAddConst1( pSat, (int)pObj->pCopy, 0 ); // care-set - pObj = Vec_PtrEntry(vFanins, 1); - Res_SatAddConst1( pSat, (int)pObj->pCopy, 0 ); // on-set - - // bookmark the clauses of A - sat_solver_store_mark_clauses_a( pSat ); - - // duplicate the clauses - pObj = Vec_PtrEntry(vFanins, 1); - Sat_SolverDoubleClauses( pSat, (int)pObj->pCopy ); - // add the equality constraints - Vec_PtrForEachEntryStart( vFanins, pObj, i, 2 ) - Res_SatAddEqual( pSat, (int)pObj->pCopy, ((int)pObj->pCopy) + nNodes, 0 ); - - // bookmark the roots - sat_solver_store_mark_roots( pSat ); - - // solve the problem - status = sat_solver_solve( pSat, NULL, NULL, (sint64)10000, (sint64)0, (sint64)0, (sint64)0 ); - if ( status == l_False ) - { - pCnf = sat_solver_store_release( pSat ); -// printf( "unsat\n" ); - } - else if ( status == l_True ) - { -// printf( "sat\n" ); - } - else - { -// printf( "undef\n" ); - } - sat_solver_delete( pSat ); - return pCnf; -} - -/**Function************************************************************* - - Synopsis [Loads AIG into the SAT solver for constrained simulation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Res_SatSimulateConstr( Abc_Ntk_t * pAig, int fOnSet ) -{ - sat_solver * pSat; - Vec_Ptr_t * vFanins; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj; - int i, nNodes; - - // start the array - vFanins = Vec_PtrAlloc( 2 ); - pObj = Abc_NtkPo( pAig, 0 ); - Vec_PtrPush( vFanins, pObj ); - pObj = Abc_NtkPo( pAig, 1 ); - Vec_PtrPush( vFanins, pObj ); - - // collect reachable nodes - vNodes = Abc_NtkDfsNodes( pAig, (Abc_Obj_t **)vFanins->pArray, vFanins->nSize ); - - // assign unique numbers to each node - nNodes = 0; - Abc_AigConst1(pAig)->pCopy = (void *)nNodes++; - Abc_NtkForEachPi( pAig, pObj, i ) - pObj->pCopy = (void *)nNodes++; - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = (void *)nNodes++; - Vec_PtrForEachEntry( vFanins, pObj, i ) // useful POs - pObj->pCopy = (void *)nNodes++; - - // start the solver - pSat = sat_solver_new(); - - // add clause for the constant node - Res_SatAddConst1( pSat, (int)Abc_AigConst1(pAig)->pCopy, 0 ); - // add clauses for AND gates - Vec_PtrForEachEntry( vNodes, pObj, i ) - Res_SatAddAnd( pSat, (int)pObj->pCopy, - (int)Abc_ObjFanin0(pObj)->pCopy, (int)Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) ); - Vec_PtrFree( vNodes ); - // add clauses for the first PO - pObj = Abc_NtkPo( pAig, 0 ); - Res_SatAddEqual( pSat, (int)pObj->pCopy, - (int)Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) ); - // add clauses for the second PO - pObj = Abc_NtkPo( pAig, 1 ); - Res_SatAddEqual( pSat, (int)pObj->pCopy, - (int)Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) ); - - // add trivial clauses - pObj = Abc_NtkPo( pAig, 0 ); - Res_SatAddConst1( pSat, (int)pObj->pCopy, 0 ); // care-set - - pObj = Abc_NtkPo( pAig, 1 ); - Res_SatAddConst1( pSat, (int)pObj->pCopy, !fOnSet ); // on-set - - Vec_PtrFree( vFanins ); - return pSat; -} - -/**Function************************************************************* - - Synopsis [Loads AIG into the SAT solver for constrained simulation.] - - Description [Returns 1 if the required number of patterns are found. - Returns 0 if the solver ran out of time or proved a constant. - In the latter, case one of the flags, fConst0 or fConst1, are set to 1.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_SatSimulate( Res_Sim_t * p, int nPatsLimit, int fOnSet ) -{ - Vec_Int_t * vLits; - Vec_Ptr_t * vPats; - sat_solver * pSat; - int RetValue, i, k, value, status, Lit, Var, iPat; - int clk = clock(); - -//printf( "Looking for %s: ", fOnSet? "onset " : "offset" ); - - // decide what problem should be solved - Lit = toLitCond( (int)Abc_NtkPo(p->pAig,1)->pCopy, !fOnSet ); - if ( fOnSet ) - { - iPat = p->nPats1; - vPats = p->vPats1; - } - else - { - iPat = p->nPats0; - vPats = p->vPats0; - } - assert( iPat < nPatsLimit ); - - // derive the SAT solver - pSat = Res_SatSimulateConstr( p->pAig, fOnSet ); - pSat->fSkipSimplify = 1; - status = sat_solver_simplify( pSat ); - if ( status == 0 ) - { - if ( iPat == 0 ) - { -// if ( fOnSet ) -// p->fConst0 = 1; -// else -// p->fConst1 = 1; - RetValue = 0; - } - goto finish; - } - - // enumerate through the SAT assignments - RetValue = 1; - vLits = Vec_IntAlloc( 32 ); - for ( k = iPat; k < nPatsLimit; k++ ) - { - // solve with the assumption -// status = sat_solver_solve( pSat, &Lit, &Lit + 1, (sint64)10000, (sint64)0, (sint64)0, (sint64)0 ); - status = sat_solver_solve( pSat, NULL, NULL, (sint64)10000, (sint64)0, (sint64)0, (sint64)0 ); - if ( status == l_False ) - { -//printf( "Const %d\n", !fOnSet ); - if ( k == 0 ) - { - if ( fOnSet ) - p->fConst0 = 1; - else - p->fConst1 = 1; - RetValue = 0; - } - break; - } - else if ( status == l_True ) - { - // save the pattern - Vec_IntClear( vLits ); - for ( i = 0; i < p->nTruePis; i++ ) - { - Var = (int)Abc_NtkPi(p->pAig,i)->pCopy; - value = (int)(pSat->model.ptr[Var] == l_True); - if ( value ) - Abc_InfoSetBit( Vec_PtrEntry(vPats, i), k ); - Lit = toLitCond( Var, value ); - Vec_IntPush( vLits, Lit ); -// printf( "%d", value ); - } -// printf( "\n" ); - - status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ); - if ( status == 0 ) - { - k++; - RetValue = 1; - break; - } - } - else - { -//printf( "Undecided\n" ); - if ( k == 0 ) - RetValue = 0; - else - RetValue = 1; - break; - } - } - Vec_IntFree( vLits ); -//printf( "Found %d patterns\n", k - iPat ); - - // set the new number of patterns - if ( fOnSet ) - p->nPats1 = k; - else - p->nPats0 = k; - -finish: - - sat_solver_delete( pSat ); -p->timeSat += clock() - clk; - return RetValue; -} - - -/**Function************************************************************* - - Synopsis [Asserts equality of the variable to a constant.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_SatAddConst1( sat_solver * pSat, int iVar, int fCompl ) -{ - lit Lit = toLitCond( iVar, fCompl ); - if ( !sat_solver_addclause( pSat, &Lit, &Lit + 1 ) ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Asserts equality of two variables.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_SatAddEqual( sat_solver * pSat, int iVar0, int iVar1, int fCompl ) -{ - lit Lits[2]; - - Lits[0] = toLitCond( iVar0, 0 ); - Lits[1] = toLitCond( iVar1, !fCompl ); - if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) ) - return 0; - - Lits[0] = toLitCond( iVar0, 1 ); - Lits[1] = toLitCond( iVar1, fCompl ); - if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) ) - return 0; - - return 1; -} - -/**Function************************************************************* - - Synopsis [Adds constraints for the two-input AND-gate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_SatAddAnd( sat_solver * pSat, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1 ) -{ - lit Lits[3]; - - Lits[0] = toLitCond( iVar, 1 ); - Lits[1] = toLitCond( iVar0, fCompl0 ); - if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) ) - return 0; - - Lits[0] = toLitCond( iVar, 1 ); - Lits[1] = toLitCond( iVar1, fCompl1 ); - if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) ) - return 0; - - Lits[0] = toLitCond( iVar, 0 ); - Lits[1] = toLitCond( iVar0, !fCompl0 ); - Lits[2] = toLitCond( iVar1, !fCompl1 ); - if ( !sat_solver_addclause( pSat, Lits, Lits + 3 ) ) - return 0; - - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/res/resSim.c b/src/opt/res/resSim.c deleted file mode 100644 index 5c1dd2b6..00000000 --- a/src/opt/res/resSim.c +++ /dev/null @@ -1,790 +0,0 @@ -/**CFile**************************************************************** - - FileName [resSim.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [Simulation engine.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: resSim.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "resInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocate simulation engine.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Res_Sim_t * Res_SimAlloc( int nWords ) -{ - Res_Sim_t * p; - p = ALLOC( Res_Sim_t, 1 ); - memset( p, 0, sizeof(Res_Sim_t) ); - // simulation parameters - p->nWords = nWords; - p->nPats = p->nWords * 8 * sizeof(unsigned); - p->nWordsIn = p->nPats; - p->nBytesIn = p->nPats * sizeof(unsigned); - p->nPatsIn = p->nPats * 8 * sizeof(unsigned); - p->nWordsOut = p->nPats * p->nWords; - p->nPatsOut = p->nPats * p->nPats; - // simulation info - p->vPats = Vec_PtrAllocSimInfo( 1024, p->nWordsIn ); - p->vPats0 = Vec_PtrAllocSimInfo( 128, p->nWords ); - p->vPats1 = Vec_PtrAllocSimInfo( 128, p->nWords ); - p->vOuts = Vec_PtrAllocSimInfo( 128, p->nWordsOut ); - // resub candidates - p->vCands = Vec_VecStart( 16 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Allocate simulation engine.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimAdjust( Res_Sim_t * p, Abc_Ntk_t * pAig, int nTruePis ) -{ - srand( 0xABC ); - - assert( Abc_NtkIsStrash(pAig) ); - p->pAig = pAig; - p->nTruePis = nTruePis; - if ( Vec_PtrSize(p->vPats) < Abc_NtkObjNumMax(pAig)+1 ) - { - Vec_PtrFree( p->vPats ); - p->vPats = Vec_PtrAllocSimInfo( Abc_NtkObjNumMax(pAig)+1, p->nWordsIn ); - } - if ( Vec_PtrSize(p->vPats0) < nTruePis ) - { - Vec_PtrFree( p->vPats0 ); - p->vPats0 = Vec_PtrAllocSimInfo( nTruePis, p->nWords ); - } - if ( Vec_PtrSize(p->vPats1) < nTruePis ) - { - Vec_PtrFree( p->vPats1 ); - p->vPats1 = Vec_PtrAllocSimInfo( nTruePis, p->nWords ); - } - if ( Vec_PtrSize(p->vOuts) < Abc_NtkPoNum(pAig) ) - { - Vec_PtrFree( p->vOuts ); - p->vOuts = Vec_PtrAllocSimInfo( Abc_NtkPoNum(pAig), p->nWordsOut ); - } - // clean storage info for patterns - Abc_InfoClear( Vec_PtrEntry(p->vPats0,0), p->nWords * nTruePis ); - Abc_InfoClear( Vec_PtrEntry(p->vPats1,0), p->nWords * nTruePis ); - p->nPats0 = 0; - p->nPats1 = 0; - p->fConst0 = 0; - p->fConst1 = 0; -} - -/**Function************************************************************* - - Synopsis [Free simulation engine.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimFree( Res_Sim_t * p ) -{ - Vec_PtrFree( p->vPats ); - Vec_PtrFree( p->vPats0 ); - Vec_PtrFree( p->vPats1 ); - Vec_PtrFree( p->vOuts ); - Vec_VecFree( p->vCands ); - free( p ); -} - - -/**Function************************************************************* - - Synopsis [Sets random PI simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_InfoRandomBytes( unsigned * p, int nWords ) -{ - int i, Num; - for ( i = nWords - 1; i >= 0; i-- ) - { - Num = rand(); - p[i] = (Num & 1)? 0xff : 0; - p[i] = (p[i] << 8) | ((Num & 2)? 0xff : 0); - p[i] = (p[i] << 8) | ((Num & 4)? 0xff : 0); - p[i] = (p[i] << 8) | ((Num & 8)? 0xff : 0); - } -// Extra_PrintBinary( stdout, p, 32 ); printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Sets random PI simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimSetRandomBytes( Res_Sim_t * p ) -{ - Abc_Obj_t * pObj; - unsigned * pInfo; - int i; - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); - if ( i < p->nTruePis ) - Abc_InfoRandomBytes( pInfo, p->nWordsIn ); - else - Abc_InfoRandom( pInfo, p->nWordsIn ); - } -/* - // double-check that all are byte-patterns - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - if ( i == p->nTruePis ) - break; - pInfoC = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id ); - for ( k = 0; k < p->nBytesIn; k++ ) - assert( pInfoC[k] == 0 || pInfoC[k] == 0xff ); - } -*/ -} - -/**Function************************************************************* - - Synopsis [Sets random PI simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimSetDerivedBytes( Res_Sim_t * p, int fUseWalk ) -{ - Vec_Ptr_t * vPatsSource[2]; - int nPatsSource[2]; - Abc_Obj_t * pObj; - unsigned char * pInfo; - int i, k, z, s, nPats; - - // set several random patterns - assert( p->nBytesIn % 32 == 0 ); - nPats = p->nBytesIn/8; - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - if ( i == p->nTruePis ) - break; - Abc_InfoRandomBytes( Vec_PtrEntry(p->vPats, pObj->Id), nPats/4 ); - } - - // set special patterns - if ( fUseWalk ) - { - for ( z = 0; z < 2; z++ ) - { - // set the zero pattern - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - if ( i == p->nTruePis ) - break; - pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id ); - pInfo[nPats] = z ? 0xff : 0; - } - if ( ++nPats == p->nBytesIn ) - return; - // set the walking zero pattern - for ( k = 0; k < p->nTruePis; k++ ) - { - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - if ( i == p->nTruePis ) - break; - pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id ); - pInfo[nPats] = ((i == k) ^ z) ? 0xff : 0; - } - if ( ++nPats == p->nBytesIn ) - return; - } - } - } - - // decide what patterns to set first - if ( p->nPats0 < p->nPats1 ) - { - nPatsSource[0] = p->nPats0; - vPatsSource[0] = p->vPats0; - nPatsSource[1] = p->nPats1; - vPatsSource[1] = p->vPats1; - } - else - { - nPatsSource[0] = p->nPats1; - vPatsSource[0] = p->vPats1; - nPatsSource[1] = p->nPats0; - vPatsSource[1] = p->vPats0; - } - for ( z = 0; z < 2; z++ ) - { - for ( s = nPatsSource[z] - 1; s >= 0; s-- ) - { -// if ( s == 0 ) -// printf( "Patterns:\n" ); - // set the given source pattern - for ( k = 0; k < p->nTruePis; k++ ) - { - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - if ( i == p->nTruePis ) - break; - pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id ); - if ( (i == k) ^ Abc_InfoHasBit( Vec_PtrEntry(vPatsSource[z], i), s ) ) - { - pInfo[nPats] = 0xff; -// if ( s == 0 ) -// printf( "1" ); - } - else - { - pInfo[nPats] = 0; -// if ( s == 0 ) -// printf( "0" ); - } - } -// if ( s == 0 ) -// printf( "\n" ); - if ( ++nPats == p->nBytesIn ) - return; - } - } - } - // clean the rest - for ( z = nPats; z < p->nBytesIn; z++ ) - { - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - if ( i == p->nTruePis ) - break; - pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id ); - memset( pInfo + nPats, 0, p->nBytesIn - nPats ); - } - } -/* - // double-check that all are byte-patterns - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - if ( i == p->nTruePis ) - break; - pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id ); - for ( k = 0; k < p->nBytesIn; k++ ) - assert( pInfo[k] == 0 || pInfo[k] == 0xff ); - } -*/ -} - -/**Function************************************************************* - - Synopsis [Sets given PI simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimSetGiven( Res_Sim_t * p, Vec_Ptr_t * vInfo ) -{ - Abc_Obj_t * pObj; - unsigned * pInfo, * pInfo2; - int i, w; - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - if ( i == p->nTruePis ) - break; - pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); - pInfo2 = Vec_PtrEntry( vInfo, i ); - for ( w = 0; w < p->nWords; w++ ) - pInfo[w] = pInfo2[w]; - } -} - -/**Function************************************************************* - - Synopsis [Simulates one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimPerformOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ) -{ - unsigned * pInfo, * pInfo1, * pInfo2; - int k, fComp1, fComp2; - // simulate the internal nodes - assert( Abc_ObjIsNode(pNode) ); - pInfo = Vec_PtrEntry(vSimInfo, pNode->Id); - pInfo1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode)); - pInfo2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode)); - fComp1 = Abc_ObjFaninC0(pNode); - fComp2 = Abc_ObjFaninC1(pNode); - if ( fComp1 && fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = ~pInfo1[k] & ~pInfo2[k]; - else if ( fComp1 && !fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = ~pInfo1[k] & pInfo2[k]; - else if ( !fComp1 && fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = pInfo1[k] & ~pInfo2[k]; - else // if ( fComp1 && fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = pInfo1[k] & pInfo2[k]; -} - -/**Function************************************************************* - - Synopsis [Simulates one CO node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimTransferOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ) -{ - unsigned * pInfo, * pInfo1; - int k, fComp1; - // simulate the internal nodes - assert( Abc_ObjIsCo(pNode) ); - pInfo = Vec_PtrEntry(vSimInfo, pNode->Id); - pInfo1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode)); - fComp1 = Abc_ObjFaninC0(pNode); - if ( fComp1 ) - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = ~pInfo1[k]; - else - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = pInfo1[k]; -} - -/**Function************************************************************* - - Synopsis [Performs one round of simulation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimPerformRound( Res_Sim_t * p, int nWords ) -{ - Abc_Obj_t * pObj; - int i; - Abc_InfoFill( Vec_PtrEntry(p->vPats,0), nWords ); - Abc_AigForEachAnd( p->pAig, pObj, i ) - Res_SimPerformOne( pObj, p->vPats, nWords ); - Abc_NtkForEachPo( p->pAig, pObj, i ) - Res_SimTransferOne( pObj, p->vPats, nWords ); -} - - -/**Function************************************************************* - - Synopsis [Pads the extra space with duplicated simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimPadSimInfo( Vec_Ptr_t * vPats, int nPats, int nWords ) -{ - unsigned * pInfo; - int i, w, iWords; - assert( nPats > 0 && nPats < nWords * 8 * (int) sizeof(unsigned) ); - // pad the first word - if ( nPats < 8 * sizeof(unsigned) ) - { - Vec_PtrForEachEntry( vPats, pInfo, i ) - if ( pInfo[0] & 1 ) - pInfo[0] |= ((~0) << nPats); - nPats = 8 * sizeof(unsigned); - } - // pad the empty words - iWords = nPats / (8 * sizeof(unsigned)); - Vec_PtrForEachEntry( vPats, pInfo, i ) - { - for ( w = iWords; w < nWords; w++ ) - pInfo[w] = pInfo[0]; - } -} - -/**Function************************************************************* - - Synopsis [Duplicates the simulation info to fill the space.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimDeriveInfoReplicate( Res_Sim_t * p ) -{ - unsigned * pInfo, * pInfo2; - Abc_Obj_t * pObj; - int i, j, w; - Abc_NtkForEachPo( p->pAig, pObj, i ) - { - pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); - pInfo2 = Vec_PtrEntry( p->vOuts, i ); - for ( j = 0; j < p->nPats; j++ ) - for ( w = 0; w < p->nWords; w++ ) - *pInfo2++ = pInfo[w]; - } -} - -/**Function************************************************************* - - Synopsis [Complement the simulation info if necessary.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimDeriveInfoComplement( Res_Sim_t * p ) -{ - unsigned * pInfo, * pInfo2; - Abc_Obj_t * pObj; - int i, j, w; - Abc_NtkForEachPo( p->pAig, pObj, i ) - { - pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); - pInfo2 = Vec_PtrEntry( p->vOuts, i ); - for ( j = 0; j < p->nPats; j++, pInfo2 += p->nWords ) - if ( Abc_InfoHasBit( pInfo, j ) ) - for ( w = 0; w < p->nWords; w++ ) - pInfo2[w] = ~pInfo2[w]; - } -} - -/**Function************************************************************* - - Synopsis [Prints output patterns.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimPrintOutPatterns( Res_Sim_t * p, Abc_Ntk_t * pAig ) -{ - Abc_Obj_t * pObj; - unsigned * pInfo2; - int i; - Abc_NtkForEachPo( pAig, pObj, i ) - { - pInfo2 = Vec_PtrEntry( p->vOuts, i ); - Extra_PrintBinary( stdout, pInfo2, p->nPatsOut ); - printf( "\n" ); - } -} - -/**Function************************************************************* - - Synopsis [Prints output patterns.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimPrintNodePatterns( Res_Sim_t * p, Abc_Ntk_t * pAig ) -{ - unsigned * pInfo; - pInfo = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id ); - Extra_PrintBinary( stdout, pInfo, p->nPats ); - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Counts the number of patters of different type.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimCountResults( Res_Sim_t * p, int * pnDcs, int * pnOnes, int * pnZeros, int fVerbose ) -{ - unsigned char * pInfoCare, * pInfoNode; - int i, nTotal = 0; - pInfoCare = (unsigned char *)Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 0)->Id ); - pInfoNode = (unsigned char *)Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id ); - for ( i = 0; i < p->nBytesIn; i++ ) - { - if ( !pInfoCare[i] ) - (*pnDcs)++; - else if ( !pInfoNode[i] ) - (*pnZeros)++; - else - (*pnOnes)++; - } - nTotal += *pnDcs; - nTotal += *pnZeros; - nTotal += *pnOnes; - if ( fVerbose ) - { - printf( "Dc = %7.2f %% ", 100.0*(*pnDcs) /nTotal ); - printf( "On = %7.2f %% ", 100.0*(*pnOnes) /nTotal ); - printf( "Off = %7.2f %% ", 100.0*(*pnZeros)/nTotal ); - } -} - -/**Function************************************************************* - - Synopsis [Counts the number of patters of different type.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimCollectPatterns( Res_Sim_t * p, int fVerbose ) -{ - Abc_Obj_t * pObj; - unsigned char * pInfoCare, * pInfoNode, * pInfo; - int i, j; - pInfoCare = (unsigned char *)Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 0)->Id ); - pInfoNode = (unsigned char *)Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id ); - for ( i = 0; i < p->nBytesIn; i++ ) - { - // skip don't-care patterns - if ( !pInfoCare[i] ) - continue; - // separate offset and onset patterns - assert( pInfoNode[i] == 0 || pInfoNode[i] == 0xff ); - if ( !pInfoNode[i] ) - { - if ( p->nPats0 >= p->nPats ) - continue; - Abc_NtkForEachPi( p->pAig, pObj, j ) - { - if ( j == p->nTruePis ) - break; - pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id ); - assert( pInfo[i] == 0 || pInfo[i] == 0xff ); - if ( pInfo[i] ) - Abc_InfoSetBit( Vec_PtrEntry(p->vPats0, j), p->nPats0 ); - } - p->nPats0++; - } - else - { - if ( p->nPats1 >= p->nPats ) - continue; - Abc_NtkForEachPi( p->pAig, pObj, j ) - { - if ( j == p->nTruePis ) - break; - pInfo = (unsigned char *)Vec_PtrEntry( p->vPats, pObj->Id ); - assert( pInfo[i] == 0 || pInfo[i] == 0xff ); - if ( pInfo[i] ) - Abc_InfoSetBit( Vec_PtrEntry(p->vPats1, j), p->nPats1 ); - } - p->nPats1++; - } - if ( p->nPats0 >= p->nPats && p->nPats1 >= p->nPats ) - break; - } - if ( fVerbose ) - { - printf( "| " ); - printf( "On = %3d ", p->nPats1 ); - printf( "Off = %3d ", p->nPats0 ); - printf( "\n" ); - } -} - -/**Function************************************************************* - - Synopsis [Verifies the last pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_SimVerifyValue( Res_Sim_t * p, int fOnSet ) -{ - Abc_Obj_t * pObj; - unsigned * pInfo, * pInfo2; - int i, value; - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - if ( i == p->nTruePis ) - break; - if ( fOnSet ) - { - pInfo2 = Vec_PtrEntry( p->vPats1, i ); - value = Abc_InfoHasBit( pInfo2, p->nPats1 - 1 ); - } - else - { - pInfo2 = Vec_PtrEntry( p->vPats0, i ); - value = Abc_InfoHasBit( pInfo2, p->nPats0 - 1 ); - } - pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); - pInfo[0] = value ? ~0 : 0; - } - Res_SimPerformRound( p, 1 ); - pObj = Abc_NtkPo( p->pAig, 1 ); - pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); - assert( pInfo[0] == 0 || pInfo[0] == ~0 ); - return pInfo[0] > 0; -} - -/**Function************************************************************* - - Synopsis [Prepares simulation info for candidate filtering.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_SimPrepare( Res_Sim_t * p, Abc_Ntk_t * pAig, int nTruePis, int fVerbose ) -{ - int i, nOnes = 0, nZeros = 0, nDcs = 0; - if ( fVerbose ) - printf( "\n" ); - // prepare the manager - Res_SimAdjust( p, pAig, nTruePis ); - // estimate the number of patterns - Res_SimSetRandomBytes( p ); - Res_SimPerformRound( p, p->nWordsIn ); - Res_SimCountResults( p, &nDcs, &nOnes, &nZeros, fVerbose ); - // collect the patterns - Res_SimCollectPatterns( p, fVerbose ); - // add more patterns using constraint simulation - if ( p->nPats0 < 8 ) - { - if ( !Res_SatSimulate( p, 16, 0 ) ) - return p->fConst0 || p->fConst1; -// return 0; -// printf( "Value0 = %d\n", Res_SimVerifyValue( p, 0 ) ); - } - if ( p->nPats1 < 8 ) - { - if ( !Res_SatSimulate( p, 16, 1 ) ) - return p->fConst0 || p->fConst1; -// return 0; -// printf( "Value1 = %d\n", Res_SimVerifyValue( p, 1 ) ); - } - // generate additional patterns - for ( i = 0; i < 2; i++ ) - { - if ( p->nPats0 > p->nPats*7/8 && p->nPats1 > p->nPats*7/8 ) - break; - Res_SimSetDerivedBytes( p, i==0 ); - Res_SimPerformRound( p, p->nWordsIn ); - Res_SimCountResults( p, &nDcs, &nOnes, &nZeros, fVerbose ); - Res_SimCollectPatterns( p, fVerbose ); - } - // create bit-matrix info - if ( p->nPats0 < p->nPats ) - Res_SimPadSimInfo( p->vPats0, p->nPats0, p->nWords ); - if ( p->nPats1 < p->nPats ) - Res_SimPadSimInfo( p->vPats1, p->nPats1, p->nWords ); - // resimulate 0-patterns - Res_SimSetGiven( p, p->vPats0 ); - Res_SimPerformRound( p, p->nWords ); -//Res_SimPrintNodePatterns( p, pAig ); - Res_SimDeriveInfoReplicate( p ); - // resimulate 1-patterns - Res_SimSetGiven( p, p->vPats1 ); - Res_SimPerformRound( p, p->nWords ); -//Res_SimPrintNodePatterns( p, pAig ); - Res_SimDeriveInfoComplement( p ); - // print output patterns -// Res_SimPrintOutPatterns( p, pAig ); - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/res/resSim_old.c b/src/opt/res/resSim_old.c deleted file mode 100644 index 23ce29e4..00000000 --- a/src/opt/res/resSim_old.c +++ /dev/null @@ -1,521 +0,0 @@ -/**CFile**************************************************************** - - FileName [resSim.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [Simulation engine.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: resSim.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "resInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocate simulation engine.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Res_Sim_t * Res_SimAlloc( int nWords ) -{ - Res_Sim_t * p; - p = ALLOC( Res_Sim_t, 1 ); - memset( p, 0, sizeof(Res_Sim_t) ); - // simulation parameters - p->nWords = nWords; - p->nPats = 8 * sizeof(unsigned) * p->nWords; - p->nWordsOut = p->nPats * p->nWords; - p->nPatsOut = p->nPats * p->nPats; - // simulation info - p->vPats = Vec_PtrAllocSimInfo( 1024, p->nWords ); - p->vPats0 = Vec_PtrAllocSimInfo( 128, p->nWords ); - p->vPats1 = Vec_PtrAllocSimInfo( 128, p->nWords ); - p->vOuts = Vec_PtrAllocSimInfo( 128, p->nWordsOut ); - // resub candidates - p->vCands = Vec_VecStart( 16 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Allocate simulation engine.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimAdjust( Res_Sim_t * p, Abc_Ntk_t * pAig ) -{ - srand( 0xABC ); - - assert( Abc_NtkIsStrash(pAig) ); - p->pAig = pAig; - if ( Vec_PtrSize(p->vPats) < Abc_NtkObjNumMax(pAig)+1 ) - { - Vec_PtrFree( p->vPats ); - p->vPats = Vec_PtrAllocSimInfo( Abc_NtkObjNumMax(pAig)+1, p->nWords ); - } - if ( Vec_PtrSize(p->vPats0) < Abc_NtkPiNum(pAig) ) - { - Vec_PtrFree( p->vPats0 ); - p->vPats0 = Vec_PtrAllocSimInfo( Abc_NtkPiNum(pAig), p->nWords ); - } - if ( Vec_PtrSize(p->vPats1) < Abc_NtkPiNum(pAig) ) - { - Vec_PtrFree( p->vPats1 ); - p->vPats1 = Vec_PtrAllocSimInfo( Abc_NtkPiNum(pAig), p->nWords ); - } - if ( Vec_PtrSize(p->vOuts) < Abc_NtkPoNum(pAig) ) - { - Vec_PtrFree( p->vOuts ); - p->vOuts = Vec_PtrAllocSimInfo( Abc_NtkPoNum(pAig), p->nWordsOut ); - } - // clean storage info for patterns - Abc_InfoClear( Vec_PtrEntry(p->vPats0,0), p->nWords * Abc_NtkPiNum(pAig) ); - Abc_InfoClear( Vec_PtrEntry(p->vPats1,0), p->nWords * Abc_NtkPiNum(pAig) ); - p->nPats0 = 0; - p->nPats1 = 0; -} - -/**Function************************************************************* - - Synopsis [Free simulation engine.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimFree( Res_Sim_t * p ) -{ - Vec_PtrFree( p->vPats ); - Vec_PtrFree( p->vPats0 ); - Vec_PtrFree( p->vPats1 ); - Vec_PtrFree( p->vOuts ); - Vec_VecFree( p->vCands ); - free( p ); -} - - -/**Function************************************************************* - - Synopsis [Sets random PI simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimSetRandom( Res_Sim_t * p ) -{ - Abc_Obj_t * pObj; - unsigned * pInfo; - int i; - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); - Abc_InfoRandom( pInfo, p->nWords ); - } -} - -/**Function************************************************************* - - Synopsis [Sets given PI simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimSetGiven( Res_Sim_t * p, Vec_Ptr_t * vInfo ) -{ - Abc_Obj_t * pObj; - unsigned * pInfo, * pInfo2; - int i, w; - Abc_NtkForEachPi( p->pAig, pObj, i ) - { - pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); - pInfo2 = Vec_PtrEntry( vInfo, i ); - for ( w = 0; w < p->nWords; w++ ) - pInfo[w] = pInfo2[w]; - } -} - -/**Function************************************************************* - - Synopsis [Simulates one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimPerformOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ) -{ - unsigned * pInfo, * pInfo1, * pInfo2; - int k, fComp1, fComp2; - // simulate the internal nodes - assert( Abc_ObjIsNode(pNode) ); - pInfo = Vec_PtrEntry(vSimInfo, pNode->Id); - pInfo1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode)); - pInfo2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode)); - fComp1 = Abc_ObjFaninC0(pNode); - fComp2 = Abc_ObjFaninC1(pNode); - if ( fComp1 && fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = ~pInfo1[k] & ~pInfo2[k]; - else if ( fComp1 && !fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = ~pInfo1[k] & pInfo2[k]; - else if ( !fComp1 && fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = pInfo1[k] & ~pInfo2[k]; - else // if ( fComp1 && fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = pInfo1[k] & pInfo2[k]; -} - -/**Function************************************************************* - - Synopsis [Simulates one CO node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimTransferOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ) -{ - unsigned * pInfo, * pInfo1; - int k, fComp1; - // simulate the internal nodes - assert( Abc_ObjIsCo(pNode) ); - pInfo = Vec_PtrEntry(vSimInfo, pNode->Id); - pInfo1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode)); - fComp1 = Abc_ObjFaninC0(pNode); - if ( fComp1 ) - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = ~pInfo1[k]; - else - for ( k = 0; k < nSimWords; k++ ) - pInfo[k] = pInfo1[k]; -} - -/**Function************************************************************* - - Synopsis [Performs one round of simulation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimPerformRound( Res_Sim_t * p ) -{ - Abc_Obj_t * pObj; - int i; - Abc_InfoFill( Vec_PtrEntry(p->vPats,0), p->nWords ); - Abc_AigForEachAnd( p->pAig, pObj, i ) - Res_SimPerformOne( pObj, p->vPats, p->nWords ); - Abc_NtkForEachPo( p->pAig, pObj, i ) - Res_SimTransferOne( pObj, p->vPats, p->nWords ); -} - -/**Function************************************************************* - - Synopsis [Processes simulation patterns.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimProcessPats( Res_Sim_t * p ) -{ - Abc_Obj_t * pObj; - unsigned * pInfoCare, * pInfoNode; - int i, j, nDcs = 0; - pInfoCare = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 0)->Id ); - pInfoNode = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id ); - for ( i = 0; i < p->nPats; i++ ) - { - // skip don't-care patterns - if ( !Abc_InfoHasBit(pInfoCare, i) ) - { - nDcs++; - continue; - } - // separate offset and onset patterns - if ( !Abc_InfoHasBit(pInfoNode, i) ) - { - if ( p->nPats0 >= p->nPats ) - continue; - Abc_NtkForEachPi( p->pAig, pObj, j ) - if ( Abc_InfoHasBit( Vec_PtrEntry(p->vPats, pObj->Id), i ) ) - Abc_InfoSetBit( Vec_PtrEntry(p->vPats0, j), p->nPats0 ); - p->nPats0++; - } - else - { - if ( p->nPats1 >= p->nPats ) - continue; - Abc_NtkForEachPi( p->pAig, pObj, j ) - if ( Abc_InfoHasBit( Vec_PtrEntry(p->vPats, pObj->Id), i ) ) - Abc_InfoSetBit( Vec_PtrEntry(p->vPats1, j), p->nPats1 ); - p->nPats1++; - } - } -} - -/**Function************************************************************* - - Synopsis [Pads the extra space with duplicated simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimPadSimInfo( Vec_Ptr_t * vPats, int nPats, int nWords ) -{ - unsigned * pInfo; - int i, w, iWords; - assert( nPats > 0 && nPats < nWords * 8 * (int) sizeof(unsigned) ); - // pad the first word - if ( nPats < 8 * sizeof(unsigned) ) - { - Vec_PtrForEachEntry( vPats, pInfo, i ) - if ( pInfo[0] & 1 ) - pInfo[0] |= ((~0) << nPats); - nPats = 8 * sizeof(unsigned); - } - // pad the empty words - iWords = nPats / (8 * sizeof(unsigned)); - Vec_PtrForEachEntry( vPats, pInfo, i ) - { - for ( w = iWords; w < nWords; w++ ) - pInfo[w] = pInfo[0]; - } -} - -/**Function************************************************************* - - Synopsis [Duplicates the simulation info to fill the space.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimDeriveInfoReplicate( Res_Sim_t * p ) -{ - unsigned * pInfo, * pInfo2; - Abc_Obj_t * pObj; - int i, j, w; - Abc_NtkForEachPo( p->pAig, pObj, i ) - { - pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); - pInfo2 = Vec_PtrEntry( p->vOuts, i ); - for ( j = 0; j < p->nPats; j++ ) - for ( w = 0; w < p->nWords; w++ ) - *pInfo2++ = pInfo[w]; - } -} - -/**Function************************************************************* - - Synopsis [Complement the simulation info if necessary.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimDeriveInfoComplement( Res_Sim_t * p ) -{ - unsigned * pInfo, * pInfo2; - Abc_Obj_t * pObj; - int i, j, w; - Abc_NtkForEachPo( p->pAig, pObj, i ) - { - pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); - pInfo2 = Vec_PtrEntry( p->vOuts, i ); - for ( j = 0; j < p->nPats; j++, pInfo2 += p->nWords ) - if ( Abc_InfoHasBit( pInfo, j ) ) - for ( w = 0; w < p->nWords; w++ ) - pInfo2[w] = ~pInfo2[w]; - } -} - -/**Function************************************************************* - - Synopsis [Free simulation engine.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimReportOne( Res_Sim_t * p ) -{ - unsigned * pInfoCare, * pInfoNode; - int i, nDcs, nOnes, nZeros; - pInfoCare = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 0)->Id ); - pInfoNode = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id ); - nDcs = nOnes = nZeros = 0; - for ( i = 0; i < p->nPats; i++ ) - { - // skip don't-care patterns - if ( !Abc_InfoHasBit(pInfoCare, i) ) - { - nDcs++; - continue; - } - // separate offset and onset patterns - if ( !Abc_InfoHasBit(pInfoNode, i) ) - nZeros++; - else - nOnes++; - } - printf( "On = %3d (%7.2f %%) ", nOnes, 100.0*nOnes/p->nPats ); - printf( "Off = %3d (%7.2f %%) ", nZeros, 100.0*nZeros/p->nPats ); - printf( "Dc = %3d (%7.2f %%) ", nDcs, 100.0*nDcs/p->nPats ); - printf( "P0 = %3d ", p->nPats0 ); - printf( "P1 = %3d ", p->nPats1 ); - if ( p->nPats0 < 4 || p->nPats1 < 4 ) - printf( "*" ); - printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Prints output patterns.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_SimPrintOutPatterns( Res_Sim_t * p, Abc_Ntk_t * pAig ) -{ - Abc_Obj_t * pObj; - unsigned * pInfo2; - int i; - Abc_NtkForEachPo( pAig, pObj, i ) - { - pInfo2 = Vec_PtrEntry( p->vOuts, i ); - Extra_PrintBinary( stdout, pInfo2, p->nPatsOut ); - printf( "\n" ); - } -} - -/**Function************************************************************* - - Synopsis [Prepares simulation info for candidate filtering.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_SimPrepare( Res_Sim_t * p, Abc_Ntk_t * pAig, int nTruePis, int fVerbose ) -{ - int Limit; - // prepare the manager - Res_SimAdjust( p, pAig ); - // collect 0/1 simulation info - for ( Limit = 0; Limit < 10; Limit++ ) - { - Res_SimSetRandom( p ); - Res_SimPerformRound( p ); - Res_SimProcessPats( p ); - if ( !(p->nPats0 < p->nPats || p->nPats1 < p->nPats) ) - break; - } -// printf( "%d ", Limit ); - // report the last set of patterns -// Res_SimReportOne( p ); -// printf( "\n" ); - // quit if there is not enough -// if ( p->nPats0 < 4 || p->nPats1 < 4 ) - if ( p->nPats0 < 4 || p->nPats1 < 4 ) - { -// Res_SimReportOne( p ); - return 0; - } - // create bit-matrix info - if ( p->nPats0 < p->nPats ) - Res_SimPadSimInfo( p->vPats0, p->nPats0, p->nWords ); - if ( p->nPats1 < p->nPats ) - Res_SimPadSimInfo( p->vPats1, p->nPats1, p->nWords ); - // resimulate 0-patterns - Res_SimSetGiven( p, p->vPats0 ); - Res_SimPerformRound( p ); - Res_SimDeriveInfoReplicate( p ); - // resimulate 1-patterns - Res_SimSetGiven( p, p->vPats1 ); - Res_SimPerformRound( p ); - Res_SimDeriveInfoComplement( p ); - // print output patterns -// Res_SimPrintOutPatterns( p, pAig ); - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/res/resStrash.c b/src/opt/res/resStrash.c deleted file mode 100644 index fde842a4..00000000 --- a/src/opt/res/resStrash.c +++ /dev/null @@ -1,117 +0,0 @@ -/**CFile**************************************************************** - - FileName [resStrash.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [Structural hashing of the nodes in the window.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: resStrash.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "resInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -extern Abc_Obj_t * Abc_ConvertAigToAig( Abc_Ntk_t * pAig, Abc_Obj_t * pObjOld ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Structurally hashes the given window.] - - Description [The first PO is the observability condition. The second - is the node's function. The remaining POs are the candidate divisors.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Res_WndStrash( Res_Win_t * p ) -{ - Vec_Ptr_t * vPairs; - Abc_Ntk_t * pAig; - Abc_Obj_t * pObj, * pMiter; - int i; - assert( Abc_NtkHasAig(p->pNode->pNtk) ); -// Abc_NtkCleanCopy( p->pNode->pNtk ); - // create the network - pAig = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); - pAig->pName = Extra_UtilStrsav( "window" ); - // create the inputs - Vec_PtrForEachEntry( p->vLeaves, pObj, i ) - pObj->pCopy = Abc_NtkCreatePi( pAig ); - Vec_PtrForEachEntry( p->vBranches, pObj, i ) - pObj->pCopy = Abc_NtkCreatePi( pAig ); - // go through the nodes in the topological order - Vec_PtrForEachEntry( p->vNodes, pObj, i ) - { - pObj->pCopy = Abc_ConvertAigToAig( pAig, pObj ); - if ( pObj == p->pNode ) - pObj->pCopy = Abc_ObjNot( pObj->pCopy ); - } - // collect the POs - vPairs = Vec_PtrAlloc( 2 * Vec_PtrSize(p->vRoots) ); - Vec_PtrForEachEntry( p->vRoots, pObj, i ) - { - Vec_PtrPush( vPairs, pObj->pCopy ); - Vec_PtrPush( vPairs, NULL ); - } - // mark the TFO of the node - Abc_NtkIncrementTravId( p->pNode->pNtk ); - Res_WinSweepLeafTfo_rec( p->pNode, (int)p->pNode->Level + p->nWinTfoMax ); - // update strashing of the node - p->pNode->pCopy = Abc_ObjNot( p->pNode->pCopy ); - Abc_NodeSetTravIdPrevious( p->pNode ); - // redo strashing in the TFO - Vec_PtrForEachEntry( p->vNodes, pObj, i ) - { - if ( Abc_NodeIsTravIdCurrent(pObj) ) - pObj->pCopy = Abc_ConvertAigToAig( pAig, pObj ); - } - // collect the POs - Vec_PtrForEachEntry( p->vRoots, pObj, i ) - Vec_PtrWriteEntry( vPairs, 2 * i + 1, pObj->pCopy ); - // add the miter - pMiter = Abc_AigMiter( pAig->pManFunc, vPairs ); - Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), pMiter ); - Vec_PtrFree( vPairs ); - // add the node - Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), p->pNode->pCopy ); - // add the fanins - Abc_ObjForEachFanin( p->pNode, pObj, i ) - Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), pObj->pCopy ); - // add the divisors - Vec_PtrForEachEntry( p->vDivs, pObj, i ) - Abc_ObjAddFanin( Abc_NtkCreatePo(pAig), pObj->pCopy ); - // add the names - Abc_NtkAddDummyPiNames( pAig ); - Abc_NtkAddDummyPoNames( pAig ); - // check the resulting network - if ( !Abc_NtkCheck( pAig ) ) - fprintf( stdout, "Res_WndStrash(): Network check has failed.\n" ); - return pAig; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/res/resWin.c b/src/opt/res/resWin.c deleted file mode 100644 index a3648925..00000000 --- a/src/opt/res/resWin.c +++ /dev/null @@ -1,485 +0,0 @@ -/**CFile**************************************************************** - - FileName [resWin.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [Windowing algorithm.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: resWin.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "resInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates the window.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Res_Win_t * Res_WinAlloc() -{ - Res_Win_t * p; - // start the manager - p = ALLOC( Res_Win_t, 1 ); - memset( p, 0, sizeof(Res_Win_t) ); - // set internal parameters - p->nFanoutLimit = 10; - p->nLevTfiMinus = 3; - // allocate storage - p->vRoots = Vec_PtrAlloc( 256 ); - p->vLeaves = Vec_PtrAlloc( 256 ); - p->vBranches = Vec_PtrAlloc( 256 ); - p->vNodes = Vec_PtrAlloc( 256 ); - p->vDivs = Vec_PtrAlloc( 256 ); - p->vMatrix = Vec_VecStart( 128 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Frees the window.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_WinFree( Res_Win_t * p ) -{ - Vec_PtrFree( p->vRoots ); - Vec_PtrFree( p->vLeaves ); - Vec_PtrFree( p->vBranches ); - Vec_PtrFree( p->vNodes ); - Vec_PtrFree( p->vDivs ); - Vec_VecFree( p->vMatrix ); - free( p ); -} - - - -/**Function************************************************************* - - Synopsis [Collect the limited TFI cone of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_WinCollectLeavesAndNodes( Res_Win_t * p ) -{ - Vec_Ptr_t * vFront; - Abc_Obj_t * pObj, * pTemp; - int i, k, m; - - assert( p->nWinTfiMax > 0 ); - assert( Vec_VecSize(p->vMatrix) > p->nWinTfiMax ); - - // start matrix with the node - Vec_VecClear( p->vMatrix ); - Vec_VecPush( p->vMatrix, 0, p->pNode ); - Abc_NtkIncrementTravId( p->pNode->pNtk ); - Abc_NodeSetTravIdCurrent( p->pNode ); - - // collect the leaves (nodes pTemp such that "p->pNode->Level - pTemp->Level > p->nWinTfiMax") - Vec_PtrClear( p->vLeaves ); - Vec_VecForEachLevelStartStop( p->vMatrix, vFront, i, 0, p->nWinTfiMax ) - { - Vec_PtrForEachEntry( vFront, pObj, k ) - { - Abc_ObjForEachFanin( pObj, pTemp, m ) - { - if ( Abc_NodeIsTravIdCurrent( pTemp ) ) - continue; - Abc_NodeSetTravIdCurrent( pTemp ); - if ( Abc_ObjIsCi(pTemp) || (int)(p->pNode->Level - pTemp->Level) > p->nWinTfiMax ) - Vec_PtrPush( p->vLeaves, pTemp ); - else - Vec_VecPush( p->vMatrix, p->pNode->Level - pTemp->Level, pTemp ); - } - } - } - if ( Vec_PtrSize(p->vLeaves) == 0 ) - return 0; - - // collect the nodes in the reverse order - Vec_PtrClear( p->vNodes ); - Vec_VecForEachLevelReverseStartStop( p->vMatrix, vFront, i, p->nWinTfiMax, 0 ) - { - Vec_PtrForEachEntry( vFront, pObj, k ) - Vec_PtrPush( p->vNodes, pObj ); - Vec_PtrClear( vFront ); - } - - // get the lowest leaf level - p->nLevLeafMin = ABC_INFINITY; - Vec_PtrForEachEntry( p->vLeaves, pObj, k ) - p->nLevLeafMin = ABC_MIN( p->nLevLeafMin, (int)pObj->Level ); - - // set minimum traversal level - p->nLevTravMin = ABC_MAX( ((int)p->pNode->Level) - p->nWinTfiMax - p->nLevTfiMinus, p->nLevLeafMin ); - assert( p->nLevTravMin >= 0 ); - return 1; -} - - - -/**Function************************************************************* - - Synopsis [Returns 1 if the node should be a root.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Res_WinComputeRootsCheck( Abc_Obj_t * pNode, int nLevelMax, int nFanoutLimit ) -{ - Abc_Obj_t * pFanout; - int i; - // the node is the root if one of the following is true: - // (1) the node has more than fanouts than the limit - if ( Abc_ObjFanoutNum(pNode) > nFanoutLimit ) - return 1; - // (2) the node has CO fanouts - // (3) the node has fanouts above the cutoff level - Abc_ObjForEachFanout( pNode, pFanout, i ) - if ( Abc_ObjIsCo(pFanout) || (int)pFanout->Level > nLevelMax ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Recursively collects the root candidates.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_WinComputeRoots_rec( Abc_Obj_t * pNode, int nLevelMax, int nFanoutLimit, Vec_Ptr_t * vRoots ) -{ - Abc_Obj_t * pFanout; - int i; - assert( Abc_ObjIsNode(pNode) ); - if ( Abc_NodeIsTravIdCurrent(pNode) ) - return; - Abc_NodeSetTravIdCurrent( pNode ); - // check if the node should be the root - if ( Res_WinComputeRootsCheck( pNode, nLevelMax, nFanoutLimit ) ) - Vec_PtrPush( vRoots, pNode ); - else // if not, explore its fanouts - Abc_ObjForEachFanout( pNode, pFanout, i ) - Res_WinComputeRoots_rec( pFanout, nLevelMax, nFanoutLimit, vRoots ); -} - -/**Function************************************************************* - - Synopsis [Recursively collects the root candidates.] - - Description [Returns 1 if the only root is this node.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_WinComputeRoots( Res_Win_t * p ) -{ - Vec_PtrClear( p->vRoots ); - Abc_NtkIncrementTravId( p->pNode->pNtk ); - Res_WinComputeRoots_rec( p->pNode, p->pNode->Level + p->nWinTfoMax, p->nFanoutLimit, p->vRoots ); - assert( Vec_PtrSize(p->vRoots) > 0 ); - if ( Vec_PtrSize(p->vRoots) == 1 && Vec_PtrEntry(p->vRoots, 0) == p->pNode ) - return 0; - return 1; -} - - - -/**Function************************************************************* - - Synopsis [Marks the paths from the roots to the leaves.] - - Description [Returns 1 if the the node can reach a leaf.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_WinMarkPaths_rec( Abc_Obj_t * pNode, Abc_Obj_t * pPivot, int nLevelMin ) -{ - Abc_Obj_t * pFanin; - int i, RetValue; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pNode) ) - return 1; - if ( Abc_NodeIsTravIdPrevious(pNode) ) - return 0; - // assume that the node does not have access to the leaves - Abc_NodeSetTravIdPrevious( pNode ); - // skip nodes below the given level - if ( pNode == pPivot || (int)pNode->Level <= nLevelMin ) - return 0; - assert( Abc_ObjIsNode(pNode) ); - // check if the fanins have access to the leaves - RetValue = 0; - Abc_ObjForEachFanin( pNode, pFanin, i ) - RetValue |= Res_WinMarkPaths_rec( pFanin, pPivot, nLevelMin ); - // relabel the node if it has access to the leaves - if ( RetValue ) - Abc_NodeSetTravIdCurrent( pNode ); - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Marks the paths from the roots to the leaves.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_WinMarkPaths( Res_Win_t * p ) -{ - Abc_Obj_t * pObj; - int i; - // mark the leaves - Abc_NtkIncrementTravId( p->pNode->pNtk ); - Abc_NtkIncrementTravId( p->pNode->pNtk ); - Vec_PtrForEachEntry( p->vLeaves, pObj, i ) - Abc_NodeSetTravIdCurrent( pObj ); - // traverse from the roots and mark the nodes that can reach leaves - // the nodes that do not reach leaves have previous trav ID - // the nodes that reach leaves have current trav ID - Vec_PtrForEachEntry( p->vRoots, pObj, i ) - Res_WinMarkPaths_rec( pObj, p->pNode, p->nLevTravMin ); -} - - - - -/**Function************************************************************* - - Synopsis [Recursively collects the roots.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_WinFinalizeRoots_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vRoots ) -{ - Abc_Obj_t * pFanout; - int i; - assert( Abc_ObjIsNode(pObj) ); - assert( Abc_NodeIsTravIdCurrent(pObj) ); - // check if the node has all fanouts marked - Abc_ObjForEachFanout( pObj, pFanout, i ) - if ( !Abc_NodeIsTravIdCurrent(pFanout) ) - break; - // if some of the fanouts are unmarked, add the node to the roots - if ( i < Abc_ObjFanoutNum(pObj) ) - Vec_PtrPushUnique( vRoots, pObj ); - else // otherwise, call recursively - Abc_ObjForEachFanout( pObj, pFanout, i ) - Res_WinFinalizeRoots_rec( pFanout, vRoots ); -} - -/**Function************************************************************* - - Synopsis [Finalizes the roots of the window.] - - Description [Roots of the window are the nodes that have at least - one fanout that it not in the TFO of the leaves.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_WinFinalizeRoots( Res_Win_t * p ) -{ - assert( !Abc_NodeIsTravIdCurrent(p->pNode) ); - // mark the node with the old traversal ID - Abc_NodeSetTravIdCurrent( p->pNode ); - // recollect the roots - Vec_PtrClear( p->vRoots ); - Res_WinFinalizeRoots_rec( p->pNode, p->vRoots ); - assert( Vec_PtrSize(p->vRoots) > 0 ); - if ( Vec_PtrSize(p->vRoots) == 1 && Vec_PtrEntry(p->vRoots, 0) == p->pNode ) - return 0; - return 1; -} - - -/**Function************************************************************* - - Synopsis [Recursively adds missing nodes and leaves.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_WinAddMissing_rec( Res_Win_t * p, Abc_Obj_t * pObj, int nLevTravMin ) -{ - Abc_Obj_t * pFanin; - int i; - // skip the already collected leaves, nodes, and branches - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return; - // if this is not an internal node - make it a new branch - if ( !Abc_NodeIsTravIdPrevious(pObj) ) - { - assert( Vec_PtrFind(p->vLeaves, pObj) == -1 ); - Abc_NodeSetTravIdCurrent( pObj ); - Vec_PtrPush( p->vBranches, pObj ); - return; - } - assert( Abc_ObjIsNode(pObj) ); // if this is a CI, then the window is incorrect! - Abc_NodeSetTravIdCurrent( pObj ); - // visit the fanins of the node - Abc_ObjForEachFanin( pObj, pFanin, i ) - Res_WinAddMissing_rec( p, pFanin, nLevTravMin ); - // collect the node - Vec_PtrPush( p->vNodes, pObj ); -} - -/**Function************************************************************* - - Synopsis [Adds to the window nodes and leaves in the TFI of the roots.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Res_WinAddMissing( Res_Win_t * p ) -{ - Abc_Obj_t * pObj; - int i; - // mark the leaves - Abc_NtkIncrementTravId( p->pNode->pNtk ); - Vec_PtrForEachEntry( p->vLeaves, pObj, i ) - Abc_NodeSetTravIdCurrent( pObj ); - // mark the already collected nodes - Vec_PtrForEachEntry( p->vNodes, pObj, i ) - Abc_NodeSetTravIdCurrent( pObj ); - // explore from the roots - Vec_PtrClear( p->vBranches ); - Vec_PtrForEachEntry( p->vRoots, pObj, i ) - Res_WinAddMissing_rec( p, pObj, p->nLevTravMin ); -} - - - - -/**Function************************************************************* - - Synopsis [Returns 1 if the window is trivial (without TFO).] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_WinIsTrivial( Res_Win_t * p ) -{ - return Vec_PtrSize(p->vRoots) == 1 && Vec_PtrEntry(p->vRoots, 0) == p->pNode; -} - -/**Function************************************************************* - - Synopsis [Computes the window.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Res_WinCompute( Abc_Obj_t * pNode, int nWinTfiMax, int nWinTfoMax, Res_Win_t * p ) -{ - assert( Abc_ObjIsNode(pNode) ); - assert( nWinTfiMax > 0 && nWinTfiMax < 10 ); - assert( nWinTfoMax >= 0 && nWinTfoMax < 10 ); - - // initialize the window - p->pNode = pNode; - p->nWinTfiMax = nWinTfiMax; - p->nWinTfoMax = nWinTfoMax; - - Vec_PtrClear( p->vBranches ); - Vec_PtrClear( p->vDivs ); - Vec_PtrClear( p->vRoots ); - Vec_PtrPush( p->vRoots, pNode ); - - // compute the leaves - if ( !Res_WinCollectLeavesAndNodes( p ) ) - return 0; - - // compute the candidate roots - if ( p->nWinTfoMax > 0 && Res_WinComputeRoots(p) ) - { - // mark the paths from the roots to the leaves - Res_WinMarkPaths( p ); - // refine the roots and add branches and missing nodes - if ( Res_WinFinalizeRoots( p ) ) - Res_WinAddMissing( p ); - } - - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/res/res_.c b/src/opt/res/res_.c deleted file mode 100644 index a50affd7..00000000 --- a/src/opt/res/res_.c +++ /dev/null @@ -1,50 +0,0 @@ -/**CFile**************************************************************** - - FileName [res_.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Resynthesis package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - January 15, 2007.] - - Revision [$Id: res_.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "res.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/ret/module.make b/src/opt/ret/module.make deleted file mode 100644 index 4b14365e..00000000 --- a/src/opt/ret/module.make +++ /dev/null @@ -1,8 +0,0 @@ -SRC += src/opt/ret/retArea.c \ - src/opt/ret/retCore.c \ - src/opt/ret/retDelay.c \ - src/opt/ret/retFlow.c \ - src/opt/ret/retIncrem.c \ - src/opt/ret/retInit.c \ - src/opt/ret/retLvalue.c - diff --git a/src/opt/ret/retArea.c b/src/opt/ret/retArea.c deleted file mode 100644 index 5eec8e80..00000000 --- a/src/opt/ret/retArea.c +++ /dev/null @@ -1,540 +0,0 @@ -/**CFile**************************************************************** - - FileName [retArea.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Retiming package.] - - Synopsis [Min-area retiming.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - Oct 31, 2006.] - - Revision [$Id: retArea.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "retInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Abc_Ntk_t * Abc_NtkRetimeMinAreaOne( Abc_Ntk_t * pNtk, int fForward, int fVerbose ); -static void Abc_NtkRetimeMinAreaPrepare( Abc_Ntk_t * pNtk, int fForward ); -static void Abc_NtkRetimeMinAreaInitValues( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut ); -static Abc_Ntk_t * Abc_NtkRetimeMinAreaConstructNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut ); -static void Abc_NtkRetimeMinAreaUpdateLatches( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward ); - -extern Abc_Ntk_t * Abc_NtkAttachBottom( Abc_Ntk_t * pNtkTop, Abc_Ntk_t * pNtkBottom ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs min-area retiming.] - - Description [Returns the number of latches reduced.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeMinArea( Abc_Ntk_t * pNtk, int fForwardOnly, int fBackwardOnly, int fVerbose ) -{ - Abc_Ntk_t * pNtkTotal = NULL, * pNtkBottom; - Vec_Int_t * vValuesNew = NULL, * vValues; - int nLatches = Abc_NtkLatchNum(pNtk); - int fOneFrame = 0; - assert( !fForwardOnly || !fBackwardOnly ); - // there should not be black boxes - assert( Abc_NtkIsSopLogic(pNtk) ); - assert( Abc_NtkLatchNum(pNtk) == Vec_PtrSize(pNtk->vBoxes) ); - // reorder CI/CO/latch inputs - Abc_NtkOrderCisCos( pNtk ); - // perform forward retiming - if ( !fBackwardOnly ) - { - if ( fOneFrame ) - Abc_NtkRetimeMinAreaOne( pNtk, 1, fVerbose ); - else - while ( Abc_NtkRetimeMinAreaOne( pNtk, 1, fVerbose ) ); - } - // remember initial values - vValues = Abc_NtkCollectLatchValues( pNtk ); - // perform backward retiming - if ( !fForwardOnly ) - { - if ( fOneFrame ) - pNtkTotal = Abc_NtkRetimeMinAreaOne( pNtk, 0, fVerbose ); - else - while ( pNtkBottom = Abc_NtkRetimeMinAreaOne( pNtk, 0, fVerbose ) ) - pNtkTotal = Abc_NtkAttachBottom( pNtkTotal, pNtkBottom ); - } - // compute initial values - vValuesNew = Abc_NtkRetimeInitialValues( pNtkTotal, vValues, fVerbose ); - if ( pNtkTotal ) Abc_NtkDelete( pNtkTotal ); - // insert new initial values - Abc_NtkInsertLatchValues( pNtk, vValuesNew ); - if ( vValuesNew ) Vec_IntFree( vValuesNew ); - if ( vValues ) Vec_IntFree( vValues ); - // fix the COs (this changes the circuit structure) -// Abc_NtkLogicMakeSimpleCos( pNtk, 0 ); - // check for correctness - if ( !Abc_NtkCheck( pNtk ) ) - fprintf( stdout, "Abc_NtkRetimeMinArea(): Network check has failed.\n" ); - // return the number of latches saved - return nLatches - Abc_NtkLatchNum(pNtk); -} - -/**Function************************************************************* - - Synopsis [Performs min-area retiming backward.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkRetimeMinAreaOne( Abc_Ntk_t * pNtk, int fForward, int fVerbose ) -{ - Abc_Ntk_t * pNtkNew = NULL; - Vec_Ptr_t * vMinCut; - int nLatches = Abc_NtkLatchNum(pNtk); - // mark current latches and TFI(POs) - Abc_NtkRetimeMinAreaPrepare( pNtk, fForward ); - // run the maximum forward flow - vMinCut = Abc_NtkMaxFlow( pNtk, fForward, fVerbose ); -// assert( Vec_PtrSize(vMinCut) <= Abc_NtkLatchNum(pNtk) ); - // create new latch boundary if there is improvement - if ( Vec_PtrSize(vMinCut) < Abc_NtkLatchNum(pNtk) ) - { - pNtkNew = (Abc_Ntk_t *)1; - if ( fForward ) - Abc_NtkRetimeMinAreaInitValues( pNtk, vMinCut ); - else - pNtkNew = Abc_NtkRetimeMinAreaConstructNtk( pNtk, vMinCut ); - Abc_NtkRetimeMinAreaUpdateLatches( pNtk, vMinCut, fForward ); - } - // clean up - Vec_PtrFree( vMinCut ); - Abc_NtkCleanMarkA( pNtk ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Marks the cone with MarkA.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMarkCone_rec( Abc_Obj_t * pObj, int fForward ) -{ - Abc_Obj_t * pNext; - int i; - if ( pObj->fMarkA ) - return; - pObj->fMarkA = 1; - if ( fForward ) - { - Abc_ObjForEachFanout( pObj, pNext, i ) - Abc_NtkMarkCone_rec( pNext, fForward ); - } - else - { - Abc_ObjForEachFanin( pObj, pNext, i ) - Abc_NtkMarkCone_rec( pNext, fForward ); - } -} - -/**Function************************************************************* - - Synopsis [Marks the cone with MarkA.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkUnmarkCone_rec( Abc_Obj_t * pObj, int fForward ) -{ - Abc_Obj_t * pNext; - int i; - if ( !pObj->fMarkA || Abc_ObjIsLatch(pObj) ) - return; - pObj->fMarkA = 0; - if ( fForward ) - { - Abc_ObjForEachFanout( pObj, pNext, i ) - Abc_NtkUnmarkCone_rec( pNext, fForward ); - } - else - { - Abc_ObjForEachFanin( pObj, pNext, i ) - Abc_NtkUnmarkCone_rec( pNext, fForward ); - } -} - -/**Function************************************************************* - - Synopsis [Prepares the network for running MaxFlow.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRetimeMinAreaPrepare( Abc_Ntk_t * pNtk, int fForward ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj, * pFanin; - int i, k; - if ( fForward ) - { - // mark the frontier - Abc_NtkForEachPo( pNtk, pObj, i ) - pObj->fMarkA = 1; - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pObj->fMarkA = 1; - Abc_ObjFanin0(pObj)->fMarkA = 1; - } - // mark the nodes reachable from the PIs - Abc_NtkForEachPi( pNtk, pObj, i ) - Abc_NtkMarkCone_rec( pObj, fForward ); - // collect the unmarked fanins of the marked nodes - vNodes = Vec_PtrAlloc( 100 ); - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( pObj->fMarkA ) - Abc_ObjForEachFanin( pObj, pFanin, k ) - if ( !pFanin->fMarkA ) - Vec_PtrPush( vNodes, pFanin ); - // mark these nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->fMarkA = 1; - Vec_PtrFree( vNodes ); - } - else - { - // mark the frontier - Abc_NtkForEachPi( pNtk, pObj, i ) - pObj->fMarkA = 1; - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pObj->fMarkA = 1; - Abc_ObjFanout0(pObj)->fMarkA = 1; - } - // mark the nodes reachable from the POs - Abc_NtkForEachPo( pNtk, pObj, i ) - Abc_NtkMarkCone_rec( pObj, fForward ); - } -} - -/**Function************************************************************* - - Synopsis [Compute initial values.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeMinAreaInitValues_rec( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanin; - int i; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return (int)pObj->pCopy; - Abc_NodeSetTravIdCurrent(pObj); - // consider the case of a latch output - if ( Abc_ObjIsBo(pObj) ) - { - assert( Abc_ObjIsLatch(Abc_ObjFanin0(pObj)) ); - pObj->pCopy = (void *)Abc_NtkRetimeMinAreaInitValues_rec( Abc_ObjFanin0(pObj) ); - return (int)pObj->pCopy; - } - assert( Abc_ObjIsNode(pObj) ); - // visit the fanins - Abc_ObjForEachFanin( pObj, pFanin, i ) - Abc_NtkRetimeMinAreaInitValues_rec( pFanin ); - // compute the value of the node - pObj->pCopy = (void *)Abc_ObjSopSimulate(pObj); - return (int)pObj->pCopy; -} - -/**Function************************************************************* - - Synopsis [Compute initial values.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRetimeMinAreaInitValues( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut ) -{ - Abc_Obj_t * pObj; - int i; - // transfer initial values to pCopy and mark the latches - Abc_NtkIncrementTravId(pNtk); - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pObj->pCopy = (void *)Abc_LatchIsInit1(pObj); - Abc_NodeSetTravIdCurrent( pObj ); - } - // propagate initial values - Vec_PtrForEachEntry( vMinCut, pObj, i ) - Abc_NtkRetimeMinAreaInitValues_rec( pObj ); - // unmark the latches - Abc_NtkForEachLatch( pNtk, pObj, i ) - Abc_NodeSetTravIdPrevious( pObj ); -} - -/**Function************************************************************* - - Synopsis [Performs min-area retiming backward.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_NtkRetimeMinAreaConstructNtk_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanin; - int i; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return pObj->pCopy; - Abc_NodeSetTravIdCurrent(pObj); - // consider the case of a latch output - if ( Abc_ObjIsBi(pObj) ) - { - pObj->pCopy = Abc_NtkRetimeMinAreaConstructNtk_rec( pNtkNew, Abc_ObjFanin0(pObj) ); - return pObj->pCopy; - } - assert( Abc_ObjIsNode(pObj) ); - // visit the fanins - Abc_ObjForEachFanin( pObj, pFanin, i ) - Abc_NtkRetimeMinAreaConstructNtk_rec( pNtkNew, pFanin ); - // compute the value of the node - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - Abc_ObjForEachFanin( pObj, pFanin, i ) - Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy ); - return pObj->pCopy; -} - -/**Function************************************************************* - - Synopsis [Creates the network from computing initial state.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkRetimeMinAreaConstructNtk( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj, * pObjNew; - int i; - // create new network - pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); - // map new latches into PIs of the new network - Abc_NtkIncrementTravId(pNtk); - Vec_PtrForEachEntry( vMinCut, pObj, i ) - { - pObj->pCopy = Abc_NtkCreatePi(pNtkNew); - Abc_NodeSetTravIdCurrent( pObj ); - } - // construct the network recursively - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - pObjNew = Abc_NtkRetimeMinAreaConstructNtk_rec( pNtkNew, Abc_ObjFanin0(pObj) ); - Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pObjNew ); - } - // unmark the nodes in the cut - Vec_PtrForEachEntry( vMinCut, pObj, i ) - Abc_NodeSetTravIdPrevious( pObj ); - // unmark the latches - Abc_NtkForEachLatch( pNtk, pObj, i ) - Abc_NodeSetTravIdPrevious( pObj ); - // assign dummy node names - Abc_NtkAddDummyPiNames( pNtkNew ); - Abc_NtkAddDummyPoNames( pNtkNew ); - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkRetimeMinAreaConstructNtk(): Network check has failed.\n" ); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Updates the network after backward retiming.] - - Description [Assumes that fMarkA denotes all nodes reachabe from - the latches toward the cut.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRetimeMinAreaUpdateLatches( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward ) -{ - Vec_Ptr_t * vCis, * vCos, * vBoxes, * vBoxesNew, * vNodes, * vBuffers; - Abc_Obj_t * pObj, * pLatch, * pLatchIn, * pLatchOut, * pNext, * pBuffer; - int i, k; - // create new latches - Vec_PtrShrink( pNtk->vCis, Abc_NtkCiNum(pNtk) - Abc_NtkLatchNum(pNtk) ); - Vec_PtrShrink( pNtk->vCos, Abc_NtkCoNum(pNtk) - Abc_NtkLatchNum(pNtk) ); - vCis = pNtk->vCis; pNtk->vCis = NULL; - vCos = pNtk->vCos; pNtk->vCos = NULL; - vBoxes = pNtk->vBoxes; pNtk->vBoxes = NULL; - // transfer boxes - vBoxesNew = Vec_PtrAlloc(100); - Vec_PtrForEachEntry( vBoxes, pObj, i ) - if ( !Abc_ObjIsLatch(pObj) ) - Vec_PtrPush( vBoxesNew, pObj ); - // create or reuse latches - vNodes = Vec_PtrAlloc( 100 ); - vBuffers = Vec_PtrAlloc( 100 ); - Vec_PtrForEachEntry( vMinCut, pObj, i ) - { - if ( Abc_ObjIsCi(pObj) && fForward ) - { - pLatchOut = pObj; - pLatch = Abc_ObjFanin0(pLatchOut); - pLatchIn = Abc_ObjFanin0(pLatch); - assert( Abc_ObjIsBo(pLatchOut) && Abc_ObjIsLatch(pLatch) && Abc_ObjIsBi(pLatchIn) ); - // mark the latch as reused - Abc_NodeSetTravIdCurrent( pLatch ); - - // check if there are marked fanouts - // (these are fanouts to be connected to the latch input) - Abc_ObjForEachFanout( pObj, pNext, k ) - if ( pNext->fMarkA ) - break; - if ( k < Abc_ObjFanoutNum(pObj) ) - { - // add the buffer - pBuffer = Abc_NtkCreateNodeBuf( pNtk, Abc_ObjFanin0(pLatchIn) ); - Abc_ObjPatchFanin( pLatchIn, Abc_ObjFanin0(pLatchIn), pBuffer ); - Vec_PtrPush( vBuffers, pBuffer ); - // redirect edges to the unvisited fanouts of the node - Abc_NodeCollectFanouts( pObj, vNodes ); - Vec_PtrForEachEntry( vNodes, pNext, k ) - if ( pNext->fMarkA ) - Abc_ObjPatchFanin( pNext, pObj, pBuffer ); - } - assert( Abc_ObjFanoutNum(pObj) > 0 ); -// if ( Abc_ObjFanoutNum(pObj) == 0 ) -// Abc_NtkDeleteObj_rec( pObj, 0 ); - } - else if ( Abc_ObjIsCo(pObj) && !fForward ) - { - pLatchIn = pObj; - pLatch = Abc_ObjFanout0(pLatchIn); - pLatchOut = Abc_ObjFanout0(pLatch); - assert( Abc_ObjIsBo(pLatchOut) && Abc_ObjIsLatch(pLatch) && Abc_ObjIsBi(pLatchIn) ); - // mark the latch as reused - Abc_NodeSetTravIdCurrent( pLatch ); - assert( !Abc_ObjFanin0(pLatchIn)->fMarkA ); - } - else - { - pLatchOut = Abc_NtkCreateBo(pNtk); - pLatch = Abc_NtkCreateLatch(pNtk); - pLatchIn = Abc_NtkCreateBi(pNtk); - Abc_ObjAssignName( pLatchOut, Abc_ObjName(pLatch), "_out" ); - Abc_ObjAssignName( pLatchIn, Abc_ObjName(pLatch), "_in" ); - // connect - Abc_ObjAddFanin( pLatchOut, pLatch ); - Abc_ObjAddFanin( pLatch, pLatchIn ); - if ( fForward ) - { - pLatch->pData = (void *)(pObj->pCopy? ABC_INIT_ONE : ABC_INIT_ZERO); - // redirect edges to the unvisited fanouts of the node - Abc_NodeCollectFanouts( pObj, vNodes ); - Vec_PtrForEachEntry( vNodes, pNext, k ) - if ( !pNext->fMarkA ) - Abc_ObjPatchFanin( pNext, pObj, pLatchOut ); - } - else - { - // redirect edges to the visited fanouts of the node - Abc_NodeCollectFanouts( pObj, vNodes ); - Vec_PtrForEachEntry( vNodes, pNext, k ) - if ( pNext->fMarkA ) - Abc_ObjPatchFanin( pNext, pObj, pLatchOut ); - } - // connect latch to the node - Abc_ObjAddFanin( pLatchIn, pObj ); - } - Vec_PtrPush( vCis, pLatchOut ); - Vec_PtrPush( vBoxesNew, pLatch ); - Vec_PtrPush( vCos, pLatchIn ); - } - Vec_PtrFree( vNodes ); - // remove buffers - Vec_PtrForEachEntry( vBuffers, pObj, i ) - { - Abc_ObjTransferFanout( pObj, Abc_ObjFanin0(pObj) ); - Abc_NtkDeleteObj( pObj ); - } - Vec_PtrFree( vBuffers ); - // remove useless latches - Vec_PtrForEachEntry( vBoxes, pObj, i ) - { - if ( !Abc_ObjIsLatch(pObj) ) - continue; - if ( Abc_NodeIsTravIdCurrent(pObj) ) - continue; - pLatchOut = Abc_ObjFanout0(pObj); - pLatch = pObj; - pLatchIn = Abc_ObjFanin0(pObj); - if ( Abc_ObjFanoutNum(pLatchOut) > 0 ) - Abc_ObjTransferFanout( pLatchOut, Abc_ObjFanin0(pLatchIn) ); - Abc_NtkDeleteObj( pLatchOut ); - Abc_NtkDeleteObj( pObj ); - Abc_NtkDeleteObj( pLatchIn ); - } - // set the arrays - pNtk->vCis = vCis; - pNtk->vCos = vCos; - pNtk->vBoxes = vBoxesNew; - Vec_PtrFree( vBoxes ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/ret/retCore.c b/src/opt/ret/retCore.c deleted file mode 100644 index 47b2cbbc..00000000 --- a/src/opt/ret/retCore.c +++ /dev/null @@ -1,132 +0,0 @@ -/**CFile**************************************************************** - - FileName [retCore.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Retiming package.] - - Synopsis [The core retiming procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - Oct 31, 2006.] - - Revision [$Id: retCore.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "retInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -int timeRetime = 0; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Implementation of retiming.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOnly, int fOneStep, int fVerbose ) -{ - int nLatches = Abc_NtkLatchNum(pNtk); - int nLevels = Abc_NtkLevel(pNtk); - int RetValue = 0, clkTotal = clock(); - int nNodesOld, nLatchesOld; - assert( Mode > 0 && Mode < 7 ); - assert( !fForwardOnly || !fBackwardOnly ); - - // cleanup the network - nNodesOld = Abc_NtkNodeNum(pNtk); - nLatchesOld = Abc_NtkLatchNum(pNtk); - Abc_NtkCleanupSeq(pNtk, 0, 0, 0); - if ( nNodesOld > Abc_NtkNodeNum(pNtk) || nLatchesOld > Abc_NtkLatchNum(pNtk) ) - printf( "Cleanup before retiming removed %d dangling nodes and %d dangling latches.\n", - nNodesOld - Abc_NtkNodeNum(pNtk), nLatchesOld - Abc_NtkLatchNum(pNtk) ); - - // perform retiming - switch ( Mode ) - { - case 1: // forward - RetValue = Abc_NtkRetimeIncremental( pNtk, 1, 0, 0, fVerbose ); - break; - case 2: // backward - RetValue = Abc_NtkRetimeIncremental( pNtk, 0, 0, 0, fVerbose ); - break; - case 3: // min-area - RetValue = Abc_NtkRetimeMinArea( pNtk, fForwardOnly, fBackwardOnly, fVerbose ); - break; - case 4: // min-delay - if ( !fBackwardOnly ) - RetValue += Abc_NtkRetimeIncremental( pNtk, 1, 1, fOneStep, fVerbose ); - if ( !fForwardOnly ) - RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, fOneStep, fVerbose ); - break; - case 5: // min-area + min-delay - RetValue = Abc_NtkRetimeMinArea( pNtk, fForwardOnly, fBackwardOnly, fVerbose ); - if ( !fBackwardOnly ) - RetValue += Abc_NtkRetimeIncremental( pNtk, 1, 1, 0, fVerbose ); - if ( !fForwardOnly ) - RetValue += Abc_NtkRetimeIncremental( pNtk, 0, 1, 0, fVerbose ); - break; - case 6: // Pan's algorithm - RetValue = Abc_NtkRetimeLValue( pNtk, 500, fVerbose ); - break; - default: - printf( "Unknown retiming option.\n" ); - break; - } - if ( fVerbose ) - { - printf( "Reduction in area = %3d. Reduction in delay = %3d. ", - nLatches - Abc_NtkLatchNum(pNtk), nLevels - Abc_NtkLevel(pNtk) ); - PRT( "Total runtime", clock() - clkTotal ); - } - timeRetime = clock() - clkTotal; - return RetValue; -} - -/**Function************************************************************* - - Synopsis [Used for automated debugging.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeDebug( Abc_Ntk_t * pNtk ) -{ - extern int Abc_NtkSecFraig( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nSeconds, int nFrames, int fVerbose ); - Abc_Ntk_t * pNtkRet; - assert( Abc_NtkIsLogic(pNtk) ); - Abc_NtkToSop( pNtk, 0 ); -// if ( !Abc_NtkCheck( pNtk ) ) -// fprintf( stdout, "Abc_NtkRetimeDebug(): Network check has failed.\n" ); -// Io_WriteBlifLogic( pNtk, "debug_temp.blif", 1 ); - pNtkRet = Abc_NtkDup( pNtk ); - Abc_NtkRetime( pNtkRet, 3, 0, 1, 0, 0 ); // debugging backward flow - return !Abc_NtkSecFraig( pNtk, pNtkRet, 10000, 3, 0 ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/ret/retDelay.c b/src/opt/ret/retDelay.c deleted file mode 100644 index bcfe3a2e..00000000 --- a/src/opt/ret/retDelay.c +++ /dev/null @@ -1,305 +0,0 @@ -/**CFile**************************************************************** - - FileName [retDelay.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Retiming package.] - - Synopsis [Incremental retiming for optimum delay.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - Oct 31, 2006.] - - Revision [$Id: retDelay.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "retInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int Abc_NtkRetimeMinDelayTry( Abc_Ntk_t * pNtk, int fForward, int fInitial, int nIterLimit, int * pIterBest, int fVerbose ); -static int Abc_NtkRetimeTiming( Abc_Ntk_t * pNtk, int fForward, Vec_Ptr_t * vCritical ); -static int Abc_NtkRetimeTiming_rec( Abc_Obj_t * pObj, int fForward ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Retimes incrementally for minimum delay.] - - Description [This procedure cannot be called in the application code - because it assumes that the network is preprocessed by removing LIs/LOs.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkCopy, int nIterLimit, int fForward, int fVerbose ) -{ - int IterBest, DelayBest; - int IterBest2, DelayBest2; - // try to find the best delay iteration on a copy - DelayBest = Abc_NtkRetimeMinDelayTry( pNtkCopy, fForward, 0, nIterLimit, &IterBest, fVerbose ); - if ( IterBest == 0 ) - return 1; - // perform the given number of iterations on the original network - DelayBest2 = Abc_NtkRetimeMinDelayTry( pNtk, fForward, 1, IterBest, &IterBest2, fVerbose ); - assert( DelayBest == DelayBest2 ); - assert( IterBest == IterBest2 ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns the best delay and the number of best iteration.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeMinDelayTry( Abc_Ntk_t * pNtk, int fForward, int fInitial, int nIterLimit, int * pIterBest, int fVerbose ) -{ - Abc_Ntk_t * pNtkNew = NULL; - Vec_Ptr_t * vCritical; - Vec_Int_t * vValues; - Abc_Obj_t * pObj; - int i, k, IterBest, DelayCur, DelayBest, DelayStart, LatchesBest; - // transfer intitial values - if ( fInitial ) - { - if ( fForward ) - Abc_NtkRetimeTranferToCopy( pNtk ); - else - { - // save initial value of the latches - vValues = Abc_NtkRetimeCollectLatchValues( pNtk ); - // start the network for initial value computation - pNtkNew = Abc_NtkRetimeBackwardInitialStart( pNtk ); - } - } - -if ( fVerbose && !fInitial ) - printf( "Performing analysis:\n" ); - // find the best iteration - DelayBest = ABC_INFINITY; IterBest = 0; LatchesBest = Abc_NtkLatchNum(pNtk); - vCritical = Vec_PtrAlloc( 100 ); - for ( i = 0; ; i++ ) - { - // perform moves for the timing-critical nodes - DelayCur = Abc_NtkRetimeTiming( pNtk, fForward, vCritical ); - if ( i == 0 ) - DelayStart = DelayCur; - // record this position if it has the best delay - if ( DelayBest > DelayCur ) - { -if ( fVerbose && !fInitial ) - printf( "%s Iter = %3d. Delay = %3d. Latches = %5d. Delta = %6.2f. Ratio = %4.2f %%\n", - fForward ? "Fwd": "Bwd", i, DelayCur, Abc_NtkLatchNum(pNtk), - 1.0*(Abc_NtkLatchNum(pNtk)-LatchesBest)/(DelayBest-DelayCur), - 100.0*(Abc_NtkLatchNum(pNtk)-LatchesBest)/Abc_NtkLatchNum(pNtk)/(DelayBest-DelayCur) ); - - DelayBest = DelayCur; - IterBest = i; - LatchesBest = Abc_NtkLatchNum(pNtk); - } - // quit after timing analysis - if ( i == nIterLimit ) - break; - // skip if 10 interations did not give improvement - if ( i - IterBest > 20 ) - break; - // try retiming to improve the delay - Vec_PtrForEachEntry( vCritical, pObj, k ) - if ( Abc_NtkRetimeNodeIsEnabled(pObj, fForward) ) - Abc_NtkRetimeNode( pObj, fForward, fInitial ); - // share latches - if ( !fForward ) - Abc_NtkRetimeShareLatches( pNtk, fInitial ); - } - Vec_PtrFree( vCritical ); - // transfer the initial state back to the latches - if ( fInitial ) - { - if ( fForward ) - Abc_NtkRetimeTranferFromCopy( pNtk ); - else - { - Abc_NtkRetimeBackwardInitialFinish( pNtk, pNtkNew, vValues, fVerbose ); - Abc_NtkDelete( pNtkNew ); - Vec_IntFree( vValues ); - } - } -if ( fVerbose && !fInitial ) - printf( "%s : Starting delay = %3d. Final delay = %3d. IterBest = %2d (out of %2d).\n", - fForward? "Forward " : "Backward", DelayStart, DelayBest, IterBest, nIterLimit ); - *pIterBest = (nIterLimit == 1) ? 1 : IterBest; - return DelayBest; -} - -/**Function************************************************************* - - Synopsis [Returns the set of timing-critical nodes.] - - Description [Performs static timing analysis on the network. Uses - unit-delay model.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeTiming( Abc_Ntk_t * pNtk, int fForward, Vec_Ptr_t * vCritical ) -{ - Vec_Ptr_t * vLatches; - Abc_Obj_t * pObj, * pNext; - int i, k, LevelCur, LevelMax = 0; - // mark all objects except nodes - Abc_NtkIncrementTravId(pNtk); - vLatches = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) ); - Abc_NtkForEachObj( pNtk, pObj, i ) - { - if ( Abc_ObjIsLatch(pObj) ) - Vec_PtrPush( vLatches, pObj ); - if ( Abc_ObjIsNode(pObj) ) - continue; - pObj->Level = 0; - Abc_NodeSetTravIdCurrent( pObj ); - } - // perform analysis from CIs/COs - if ( fForward ) - { - Vec_PtrForEachEntry( vLatches, pObj, i ) - { - Abc_ObjForEachFanout( pObj, pNext, k ) - { - LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward ); - if ( LevelMax < LevelCur ) - LevelMax = LevelCur; - } - } - Abc_NtkForEachPi( pNtk, pObj, i ) - { - Abc_ObjForEachFanout( pObj, pNext, k ) - { - LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward ); - if ( LevelMax < LevelCur ) - LevelMax = LevelCur; - } - } - } - else - { - Vec_PtrForEachEntry( vLatches, pObj, i ) - { - LevelCur = Abc_NtkRetimeTiming_rec( Abc_ObjFanin0(pObj), fForward ); - if ( LevelMax < LevelCur ) - LevelMax = LevelCur; - } - Abc_NtkForEachPo( pNtk, pObj, i ) - { - LevelCur = Abc_NtkRetimeTiming_rec( Abc_ObjFanin0(pObj), fForward ); - if ( LevelMax < LevelCur ) - LevelMax = LevelCur; - } - } - // collect timing critical nodes, which should be retimed forward/backward - Vec_PtrClear( vCritical ); - Abc_NtkIncrementTravId(pNtk); - if ( fForward ) - { - Vec_PtrForEachEntry( vLatches, pObj, i ) - { - Abc_ObjForEachFanout( pObj, pNext, k ) - { - if ( Abc_NodeIsTravIdCurrent(pNext) ) - continue; - if ( LevelMax != (int)pNext->Level ) - continue; - // new critical node - Vec_PtrPush( vCritical, pNext ); - Abc_NodeSetTravIdCurrent( pNext ); - } - } - } - else - { - Vec_PtrForEachEntry( vLatches, pObj, i ) - { - Abc_ObjForEachFanin( pObj, pNext, k ) - { - if ( Abc_NodeIsTravIdCurrent(pNext) ) - continue; - if ( LevelMax != (int)pNext->Level ) - continue; - // new critical node - Vec_PtrPush( vCritical, pNext ); - Abc_NodeSetTravIdCurrent( pNext ); - } - } - } - Vec_PtrFree( vLatches ); - return LevelMax; -} - -/**Function************************************************************* - - Synopsis [Recursively performs timing analysis.] - - Description [Performs static timing analysis on the network. Uses - unit-delay model.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeTiming_rec( Abc_Obj_t * pObj, int fForward ) -{ - Abc_Obj_t * pNext; - int i, LevelCur, LevelMax = 0; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return pObj->Level; - Abc_NodeSetTravIdCurrent(pObj); - // visit the next nodes - if ( fForward ) - { - Abc_ObjForEachFanout( pObj, pNext, i ) - { - LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward ); - if ( LevelMax < LevelCur ) - LevelMax = LevelCur; - } - } - else - { - Abc_ObjForEachFanin( pObj, pNext, i ) - { - LevelCur = Abc_NtkRetimeTiming_rec( pNext, fForward ); - if ( LevelMax < LevelCur ) - LevelMax = LevelCur; - } - } -// printf( "Node %3d -> Level %3d.\n", pObj->Id, LevelMax + 1 ); - pObj->Level = LevelMax + 1; - return pObj->Level; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/ret/retFlow.c b/src/opt/ret/retFlow.c deleted file mode 100644 index 47ee8516..00000000 --- a/src/opt/ret/retFlow.c +++ /dev/null @@ -1,783 +0,0 @@ -/**CFile**************************************************************** - - FileName [retFlow.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Implementation of maximum flow (min-area retiming).] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - Oct 31, 2006.] - - Revision [$Id: retFlow.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "retInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static inline int Abc_ObjSetPath( Abc_Obj_t * pObj, Abc_Obj_t * pNext ) { pObj->pCopy = pNext; return 1; } -static inline Abc_Obj_t * Abc_ObjGetPath( Abc_Obj_t * pObj ) { return pObj->pCopy; } -static inline Abc_Obj_t * Abc_ObjGetFanoutPath( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout; - int i; - assert( Abc_ObjGetPath(pObj) ); - Abc_ObjForEachFanout( pObj, pFanout, i ) - if ( Abc_ObjGetPath(pFanout) == pObj ) - return pFanout; - return NULL; -} -static inline Abc_Obj_t * Abc_ObjGetFaninPath( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanin; - int i; - assert( Abc_ObjGetPath(pObj) ); - Abc_ObjForEachFanin( pObj, pFanin, i ) - if ( Abc_ObjGetPath(pFanin) == pObj ) - return pFanin; - return NULL; -} -static inline Abc_Obj_t * Abc_ObjGetPredecessorBwd( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pNext; - int i; - Abc_ObjForEachFanout( pObj, pNext, i ) - if ( Abc_ObjGetPath(pNext) == pObj ) - return pNext; - Abc_ObjForEachFanin( pObj, pNext, i ) - if ( Abc_ObjGetPath(pNext) == pObj ) - return pNext; - return NULL; -} -static inline Abc_Obj_t * Abc_ObjGetPredecessorFwd( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pNext; - int i; - Abc_ObjForEachFanin( pObj, pNext, i ) - if ( Abc_ObjGetPath(pNext) == pObj ) - return pNext; - Abc_ObjForEachFanout( pObj, pNext, i ) - if ( Abc_ObjGetPath(pNext) == pObj ) - return pNext; - return NULL; -} - -static int Abc_NtkMaxFlowBwdPath_rec( Abc_Obj_t * pObj ); -static int Abc_NtkMaxFlowFwdPath_rec( Abc_Obj_t * pObj ); -static int Abc_NtkMaxFlowBwdPath2_rec( Abc_Obj_t * pObj ); -static int Abc_NtkMaxFlowFwdPath2_rec( Abc_Obj_t * pObj ); -//static int Abc_NtkMaxFlowBwdPath3_rec( Abc_Obj_t * pObj ); -static int Abc_NtkMaxFlowFwdPath3_rec( Abc_Obj_t * pObj, Abc_Obj_t * pPrev, int fFanin ); -static Vec_Ptr_t * Abc_NtkMaxFlowMinCut( Abc_Ntk_t * pNtk, int fForward ); -static void Abc_NtkMaxFlowMinCutUpdate( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward ); -static int Abc_NtkMaxFlowVerifyCut( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward ); -static void Abc_NtkMaxFlowPrintCut( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut ); -static void Abc_NtkMaxFlowPrintFlow( Abc_Ntk_t * pNtk, int fForward ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Test-bench for the max-flow computation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vMinCut; - Abc_Obj_t * pObj; - int i; - - // forward flow - Abc_NtkForEachPo( pNtk, pObj, i ) - pObj->fMarkA = 1; - Abc_NtkForEachLatch( pNtk, pObj, i ) - pObj->fMarkA = Abc_ObjFanin0(pObj)->fMarkA = 1; -// Abc_ObjFanin0(pObj)->fMarkA = 1; - vMinCut = Abc_NtkMaxFlow( pNtk, 1, 1 ); - Vec_PtrFree( vMinCut ); - Abc_NtkCleanMarkA( pNtk ); - - // backward flow - Abc_NtkForEachPi( pNtk, pObj, i ) - pObj->fMarkA = 1; - Abc_NtkForEachLatch( pNtk, pObj, i ) - pObj->fMarkA = Abc_ObjFanout0(pObj)->fMarkA = 1; -// Abc_ObjFanout0(pObj)->fMarkA = 1; - vMinCut = Abc_NtkMaxFlow( pNtk, 0, 1 ); - Vec_PtrFree( vMinCut ); - Abc_NtkCleanMarkA( pNtk ); - -} - -/**Function************************************************************* - - Synopsis [Implementation of max-flow/min-cut computation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkMaxFlow( Abc_Ntk_t * pNtk, int fForward, int fVerbose ) -{ - Vec_Ptr_t * vMinCut; - Abc_Obj_t * pLatch; - int Flow, FlowCur, RetValue, i; - int clk = clock(); - int fUseDirectedFlow = 1; - - // find the max-flow - Abc_NtkCleanCopy( pNtk ); - Flow = 0; - Abc_NtkIncrementTravId(pNtk); - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - if ( fForward ) - { -// assert( !Abc_ObjFanout0(pLatch)->fMarkA ); - FlowCur = Abc_NtkMaxFlowFwdPath2_rec( Abc_ObjFanout0(pLatch) ); -// FlowCur = Abc_NtkMaxFlowFwdPath3_rec( Abc_ObjFanout0(pLatch), pLatch, 1 ); - Flow += FlowCur; - } - else - { - assert( !Abc_ObjFanin0(pLatch)->fMarkA ); - FlowCur = Abc_NtkMaxFlowBwdPath2_rec( Abc_ObjFanin0(pLatch) ); - Flow += FlowCur; - } - if ( FlowCur ) - Abc_NtkIncrementTravId(pNtk); - } - - if ( !fUseDirectedFlow ) - { - Abc_NtkIncrementTravId(pNtk); - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - if ( fForward ) - { - // assert( !Abc_ObjFanout0(pLatch)->fMarkA ); - FlowCur = Abc_NtkMaxFlowFwdPath_rec( Abc_ObjFanout0(pLatch) ); - Flow += FlowCur; - } - else - { - assert( !Abc_ObjFanin0(pLatch)->fMarkA ); - FlowCur = Abc_NtkMaxFlowBwdPath_rec( Abc_ObjFanin0(pLatch) ); - Flow += FlowCur; - } - if ( FlowCur ) - Abc_NtkIncrementTravId(pNtk); - } - } -// Abc_NtkMaxFlowPrintFlow( pNtk, fForward ); - - // mark the nodes reachable from the latches - Abc_NtkIncrementTravId(pNtk); - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - if ( fForward ) - { -// assert( !Abc_ObjFanout0(pLatch)->fMarkA ); - if ( fUseDirectedFlow ) - RetValue = Abc_NtkMaxFlowFwdPath2_rec( Abc_ObjFanout0(pLatch) ); -// RetValue = Abc_NtkMaxFlowFwdPath3_rec( Abc_ObjFanout0(pLatch), pLatch, 1 ); - else - RetValue = Abc_NtkMaxFlowFwdPath_rec( Abc_ObjFanout0(pLatch) ); - } - else - { - assert( !Abc_ObjFanin0(pLatch)->fMarkA ); - if ( fUseDirectedFlow ) - RetValue = Abc_NtkMaxFlowBwdPath2_rec( Abc_ObjFanin0(pLatch) ); - else - RetValue = Abc_NtkMaxFlowBwdPath_rec( Abc_ObjFanin0(pLatch) ); - } - assert( RetValue == 0 ); - } - - // find the min-cut with the smallest volume - vMinCut = Abc_NtkMaxFlowMinCut( pNtk, fForward ); - // verify the cut - if ( !Abc_NtkMaxFlowVerifyCut(pNtk, vMinCut, fForward) ) - printf( "Abc_NtkMaxFlow() error! The computed min-cut is not a cut!\n" ); - // make the cut retimable - Abc_NtkMaxFlowMinCutUpdate( pNtk, vMinCut, fForward ); - - // report the results - if ( fVerbose ) - { - printf( "L = %6d. %s max-flow = %6d. Min-cut = %6d. ", - Abc_NtkLatchNum(pNtk), fForward? "Forward " : "Backward", Flow, Vec_PtrSize(vMinCut) ); -PRT( "Time", clock() - clk ); - } - -// Abc_NtkMaxFlowPrintCut( pNtk, vMinCut ); - return vMinCut; -} - -/**Function************************************************************* - - Synopsis [Tries to find an augmenting path originating in this node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkMaxFlowBwdPath_rec( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pNext, * pPred; - int i; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return 0; - Abc_NodeSetTravIdCurrent(pObj); - // get the predecessor - pPred = Abc_ObjGetPredecessorBwd( pObj ); - // process node without flow - if ( !Abc_ObjGetPath(pObj) ) - { - // start the path if we reached a terminal node - if ( pObj->fMarkA ) - return Abc_ObjSetPath( pObj, (void *)1 ); - // explore the fanins - Abc_ObjForEachFanin( pObj, pNext, i ) - if ( pNext != pPred && !Abc_ObjIsLatch(pNext) && Abc_NtkMaxFlowBwdPath_rec(pNext) ) - return Abc_ObjSetPath( pObj, pNext ); - Abc_ObjForEachFanout( pObj, pNext, i ) - if ( pNext != pPred && !Abc_ObjIsLatch(pNext) && Abc_NtkMaxFlowBwdPath_rec(pNext) ) - return Abc_ObjSetPath( pObj, pNext ); - return 0; - } - // pObj has flow - find the fanout with flow - if ( pPred == NULL ) - return 0; - // go through the successors of the predecessor - Abc_ObjForEachFanin( pPred, pNext, i ) - if ( !Abc_ObjIsLatch(pNext) && Abc_NtkMaxFlowBwdPath_rec( pNext ) ) - return Abc_ObjSetPath( pPred, pNext ); - Abc_ObjForEachFanout( pPred, pNext, i ) - if ( !Abc_ObjIsLatch(pNext) && Abc_NtkMaxFlowBwdPath_rec( pNext ) ) - return Abc_ObjSetPath( pPred, pNext ); - // try the fanout - if ( Abc_NtkMaxFlowBwdPath_rec( pPred ) ) - return Abc_ObjSetPath( pPred, NULL ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Tries to find an augmenting path originating in this node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkMaxFlowFwdPath_rec( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pNext, * pPred; - int i; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return 0; - Abc_NodeSetTravIdCurrent(pObj); - // get the predecessor - pPred = Abc_ObjGetPredecessorFwd( pObj ); - // process node without flow - if ( !Abc_ObjGetPath(pObj) ) - { - // start the path if we reached a terminal node - if ( pObj->fMarkA ) - return Abc_ObjSetPath( pObj, (void *)1 ); - // explore the fanins - Abc_ObjForEachFanout( pObj, pNext, i ) - if ( pNext != pPred && !Abc_ObjIsLatch(pNext) && Abc_NtkMaxFlowFwdPath_rec(pNext) ) - return Abc_ObjSetPath( pObj, pNext ); - Abc_ObjForEachFanin( pObj, pNext, i ) - if ( pNext != pPred && !Abc_ObjIsLatch(pNext) && Abc_NtkMaxFlowFwdPath_rec(pNext) ) - return Abc_ObjSetPath( pObj, pNext ); - return 0; - } - // pObj has flow - find the fanout with flow - if ( pPred == NULL ) - return 0; - // go through the successors of the predecessor - Abc_ObjForEachFanout( pPred, pNext, i ) - if ( !Abc_ObjIsLatch(pNext) && Abc_NtkMaxFlowFwdPath_rec( pNext ) ) - return Abc_ObjSetPath( pPred, pNext ); - Abc_ObjForEachFanin( pPred, pNext, i ) - if ( !Abc_ObjIsLatch(pNext) && Abc_NtkMaxFlowFwdPath_rec( pNext ) ) - return Abc_ObjSetPath( pPred, pNext ); - // try the fanout - if ( Abc_NtkMaxFlowFwdPath_rec( pPred ) ) - return Abc_ObjSetPath( pPred, NULL ); - return 0; -} - - -/**Function************************************************************* - - Synopsis [Tries to find an augmenting path originating in this edge.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkMaxFlowFwdPath3_rec( Abc_Obj_t * pObj, Abc_Obj_t * pPrev, int fFanin ) -{ - Abc_Obj_t * pFanin, * pFanout; - int i; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return 0; - Abc_NodeSetTravIdCurrent(pObj); - // skip the fanin which already has flow - if ( fFanin && Abc_ObjGetPath(pPrev) ) - return 0; - // if the node has no flow, try to push through the fanouts - if ( !Abc_ObjGetPath(pObj) ) - { - // start the path if we reached a terminal node - if ( pObj->fMarkA ) - return Abc_ObjSetPath( pObj, (void *)1 ); - // try to push flow through the fanouts - Abc_ObjForEachFanout( pObj, pFanout, i ) - if ( Abc_NtkMaxFlowFwdPath3_rec(pFanout, pObj, 1) ) - return fFanin? Abc_ObjSetPath(pPrev, pObj) : 1; - } - // try to push through the fanins - Abc_ObjForEachFanin( pObj, pFanin, i ) - if ( !Abc_ObjIsLatch(pFanin) && Abc_NtkMaxFlowFwdPath3_rec(pFanin, pObj, 0) ) - return Abc_ObjSetPath( pFanin, NULL ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Tries to find an augmenting path originating in this node.] - - Description [This procedure works for directed graphs only!] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkMaxFlowBwdPath2_rec( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout, * pFanin; - int i; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return 0; - Abc_NodeSetTravIdCurrent(pObj); - // process node without flow - if ( !Abc_ObjGetPath(pObj) ) - { - // start the path if we reached a terminal node - if ( pObj->fMarkA ) - return Abc_ObjSetPath( pObj, (void *)1 ); - // explore the fanins - Abc_ObjForEachFanin( pObj, pFanin, i ) - if ( Abc_NtkMaxFlowBwdPath2_rec(pFanin) ) - return Abc_ObjSetPath( pObj, pFanin ); - return 0; - } - // pObj has flow - find the fanout with flow - pFanout = Abc_ObjGetFanoutPath( pObj ); - if ( pFanout == NULL ) - return 0; - // go through the fanins of the fanout with flow - Abc_ObjForEachFanin( pFanout, pFanin, i ) - if ( Abc_NtkMaxFlowBwdPath2_rec( pFanin ) ) - return Abc_ObjSetPath( pFanout, pFanin ); - // try the fanout - if ( Abc_NtkMaxFlowBwdPath2_rec( pFanout ) ) - return Abc_ObjSetPath( pFanout, NULL ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Tries to find an augmenting path originating in this node.] - - Description [This procedure works for directed graphs only!] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkMaxFlowFwdPath2_rec( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout, * pFanin; - int i; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return 0; - Abc_NodeSetTravIdCurrent(pObj); - // process node without flow - if ( !Abc_ObjGetPath(pObj) ) - { - // start the path if we reached a terminal node - if ( pObj->fMarkA ) - return Abc_ObjSetPath( pObj, (void *)1 ); - // explore the fanins - Abc_ObjForEachFanout( pObj, pFanout, i ) - if ( Abc_NtkMaxFlowFwdPath2_rec(pFanout) ) - return Abc_ObjSetPath( pObj, pFanout ); - return 0; - } - // pObj has flow - find the fanout with flow - pFanin = Abc_ObjGetFaninPath( pObj ); - if ( pFanin == NULL ) - return 0; - // go through the fanins of the fanout with flow - Abc_ObjForEachFanout( pFanin, pFanout, i ) - if ( Abc_NtkMaxFlowFwdPath2_rec( pFanout ) ) - return Abc_ObjSetPath( pFanin, pFanout ); - // try the fanout - if ( Abc_NtkMaxFlowFwdPath2_rec( pFanin ) ) - return Abc_ObjSetPath( pFanin, NULL ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Find minimum-volume minumum cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_NtkMaxFlowMinCut( Abc_Ntk_t * pNtk, int fForward ) -{ - Vec_Ptr_t * vMinCut; - Abc_Obj_t * pObj; - int i; - // collect the cut nodes - vMinCut = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) ); - Abc_NtkForEachObj( pNtk, pObj, i ) - { - // node without flow is not a cut node - if ( !Abc_ObjGetPath(pObj) ) - continue; - // unvisited node is below the cut - if ( !Abc_NodeIsTravIdCurrent(pObj) ) - continue; - // add terminal with flow or node whose path is not visited - if ( pObj->fMarkA || !Abc_NodeIsTravIdCurrent( Abc_ObjGetPath(pObj) ) ) - Vec_PtrPush( vMinCut, pObj ); - } - return vMinCut; -} - -/**Function************************************************************* - - Synopsis [Marks the TFI cone with MarkA.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMaxFlowMarkCut_rec( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pNext; - int i; - if ( pObj->fMarkA ) - return; - pObj->fMarkA = 1; - Abc_ObjForEachFanin( pObj, pNext, i ) - Abc_NtkMaxFlowMarkCut_rec( pNext ); -} - -/**Function************************************************************* - - Synopsis [Visits the TFI up to marked nodes and collects marked nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMaxFlowCollectCut_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vNodes ) -{ - Abc_Obj_t * pNext; - int i; - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return; - Abc_NodeSetTravIdCurrent(pObj); - if ( pObj->fMarkA ) - { - Vec_PtrPush( vNodes, pObj ); - return; - } - Abc_ObjForEachFanin( pObj, pNext, i ) - Abc_NtkMaxFlowCollectCut_rec( pNext, vNodes ); -} - -/**Function************************************************************* - - Synopsis [Updates the minimum cut to be retimable.] - - Description [This procedure also labels the nodes reachable from - the latches to the cut with fMarkA.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMaxFlowMinCutUpdate( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward ) -{ - Abc_Obj_t * pObj, * pNext; - int i, k; - // clean marks - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->fMarkA = 0; - // set latch outputs - Abc_NtkForEachLatch( pNtk, pObj, i ) - Abc_ObjFanout0(pObj)->fMarkA = 1; - // traverse from cut nodes - Vec_PtrForEachEntry( vMinCut, pObj, i ) - Abc_NtkMaxFlowMarkCut_rec( pObj ); - if ( fForward ) - { - // change mincut to be nodes with unmarked fanouts - Vec_PtrClear( vMinCut ); - Abc_NtkForEachObj( pNtk, pObj, i ) - { - if ( !pObj->fMarkA ) - continue; - Abc_ObjForEachFanout( pObj, pNext, k ) - { - if ( pNext->fMarkA ) - continue; - Vec_PtrPush( vMinCut, pObj ); - break; - } - } - } - else - { - // change mincut to be marked fanins of the unmarked nodes - Vec_PtrClear( vMinCut ); - Abc_NtkIncrementTravId(pNtk); - Abc_NtkForEachLatch( pNtk, pObj, i ) - Abc_NtkMaxFlowCollectCut_rec( Abc_ObjFanin0(pObj), vMinCut ); - // transfer the attribute - Abc_NtkForEachObj( pNtk, pObj, i ) - pObj->fMarkA = Abc_NodeIsTravIdCurrent(pObj); - // unmark the cut nodes - Vec_PtrForEachEntry( vMinCut, pObj, i ) - pObj->fMarkA = 0; - } -} - -/**Function************************************************************* - - Synopsis [Verifies the min-cut is indeed a cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkMaxFlowVerifyCut_rec( Abc_Obj_t * pObj, int fForward ) -{ - Abc_Obj_t * pNext; - int i; - // skip visited nodes - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return 1; - Abc_NodeSetTravIdCurrent(pObj); - // visit the node - if ( fForward ) - { - if ( Abc_ObjIsCo(pObj) ) - return 0; - // explore the fanouts - Abc_ObjForEachFanout( pObj, pNext, i ) - if ( !Abc_NtkMaxFlowVerifyCut_rec(pNext, fForward) ) - return 0; - } - else - { - if ( Abc_ObjIsCi(pObj) ) - return 0; - // explore the fanins - Abc_ObjForEachFanin( pObj, pNext, i ) - if ( !Abc_NtkMaxFlowVerifyCut_rec(pNext, fForward) ) - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Verifies the min-cut is indeed a cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkMaxFlowVerifyCut( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut, int fForward ) -{ - Abc_Obj_t * pObj; - int i; - // mark the cut with the current traversal ID - Abc_NtkIncrementTravId(pNtk); - Vec_PtrForEachEntry( vMinCut, pObj, i ) - Abc_NodeSetTravIdCurrent( pObj ); - // search from the latches for a path to the COs/CIs - Abc_NtkForEachLatch( pNtk, pObj, i ) - { - if ( fForward ) - { - if ( !Abc_NtkMaxFlowVerifyCut_rec( Abc_ObjFanout0(pObj), fForward ) ) - return 0; - } - else - { - if ( !Abc_NtkMaxFlowVerifyCut_rec( Abc_ObjFanin0(pObj), fForward ) ) - return 0; - } - } -/* - { - // count the volume of the cut - int Counter = 0; - Abc_NtkForEachObj( pNtk, pObj, i ) - Counter += Abc_NodeIsTravIdCurrent( pObj ); - printf( "Volume = %d.\n", Counter ); - } -*/ - return 1; -} - -/**Function************************************************************* - - Synopsis [Prints the flows.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMaxFlowPrintFlow( Abc_Ntk_t * pNtk, int fForward ) -{ - Abc_Obj_t * pLatch, * pNext, * pPrev; - int i; - if ( fForward ) - { - Vec_PtrForEachEntry( pNtk->vBoxes, pLatch, i ) - { - assert( !Abc_ObjFanout0(pLatch)->fMarkA ); - if ( Abc_ObjGetPath(Abc_ObjFanout0(pLatch)) == NULL ) // no flow through this latch - continue; - printf( "Path = " ); - for ( pNext = Abc_ObjFanout0(pLatch); pNext != (void *)1; pNext = Abc_ObjGetPath(pNext) ) - { - printf( "%s(%d) ", Abc_ObjName(pNext), pNext->Id ); - pPrev = pNext; - } - if ( !Abc_ObjIsPo(pPrev) ) - printf( "%s(%d) ", Abc_ObjName(Abc_ObjFanout0(pPrev)), Abc_ObjFanout0(pPrev)->Id ); - printf( "\n" ); - } - } - else - { - Vec_PtrForEachEntry( pNtk->vBoxes, pLatch, i ) - { - assert( !Abc_ObjFanin0(pLatch)->fMarkA ); - if ( Abc_ObjGetPath(Abc_ObjFanin0(pLatch)) == NULL ) // no flow through this latch - continue; - printf( "Path = " ); - for ( pNext = Abc_ObjFanin0(pLatch); pNext != (void *)1; pNext = Abc_ObjGetPath(pNext) ) - { - printf( "%s(%d) ", Abc_ObjName(pNext), pNext->Id ); - pPrev = pNext; - } - if ( !Abc_ObjIsPi(pPrev) ) - printf( "%s(%d) ", Abc_ObjName(Abc_ObjFanin0(pPrev)), Abc_ObjFanin0(pPrev)->Id ); - printf( "\n" ); - } - } -} - -/**Function************************************************************* - - Synopsis [Prints the min-cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkMaxFlowPrintCut( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMinCut ) -{ - Abc_Obj_t * pObj; - int i; - printf( "Min-cut: " ); - Vec_PtrForEachEntry( vMinCut, pObj, i ) - printf( "%s(%d) ", Abc_ObjName(pObj), pObj->Id ); - printf( "\n" ); - printf( "Marked nodes: " ); - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( pObj->fMarkA ) - printf( "%s(%d) ", Abc_ObjName(pObj), pObj->Id ); - printf( "\n" ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/ret/retIncrem.c b/src/opt/ret/retIncrem.c deleted file mode 100644 index ba8104be..00000000 --- a/src/opt/ret/retIncrem.c +++ /dev/null @@ -1,464 +0,0 @@ -/**CFile**************************************************************** - - FileName [retIncrem.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Retiming package.] - - Synopsis [Incremental retiming in one direction.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - Oct 31, 2006.] - - Revision [$Id: retIncrem.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "retInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int Abc_NtkRetimeOneWay( Abc_Ntk_t * pNtk, int fForward, int fVerbose ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs retiming in one direction.] - - Description [Currently does not retime over black boxes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeIncremental( Abc_Ntk_t * pNtk, int fForward, int fMinDelay, int fOneStep, int fVerbose ) -{ - Abc_Ntk_t * pNtkCopy = NULL; - Vec_Ptr_t * vBoxes; - st_table * tLatches; - int nLatches = Abc_NtkLatchNum(pNtk); - int nIdMaxStart = Abc_NtkObjNumMax(pNtk); - int RetValue, nIterLimit; - if ( Abc_NtkNodeNum(pNtk) == 0 ) - return 0; - // reorder CI/CO/latch inputs - Abc_NtkOrderCisCos( pNtk ); - if ( fMinDelay ) - { - nIterLimit = fOneStep? 1 : 2 * Abc_NtkLevel(pNtk); - pNtkCopy = Abc_NtkDup( pNtk ); - tLatches = Abc_NtkRetimePrepareLatches( pNtkCopy ); - st_free_table( tLatches ); - } - // collect latches and remove CIs/COs - tLatches = Abc_NtkRetimePrepareLatches( pNtk ); - // share the latches - Abc_NtkRetimeShareLatches( pNtk, 0 ); - // save boxes - vBoxes = pNtk->vBoxes; pNtk->vBoxes = NULL; - // perform the retiming - if ( fMinDelay ) - Abc_NtkRetimeMinDelay( pNtk, pNtkCopy, nIterLimit, fForward, fVerbose ); - else - Abc_NtkRetimeOneWay( pNtk, fForward, fVerbose ); - if ( fMinDelay ) - Abc_NtkDelete( pNtkCopy ); - // share the latches - Abc_NtkRetimeShareLatches( pNtk, 0 ); - // restore boxes - pNtk->vBoxes = vBoxes; - // finalize the latches - RetValue = Abc_NtkRetimeFinalizeLatches( pNtk, tLatches, nIdMaxStart ); - st_free_table( tLatches ); - if ( RetValue == 0 ) - return 0; - // fix the COs -// Abc_NtkLogicMakeSimpleCos( pNtk, 0 ); - // check for correctness - if ( !Abc_NtkCheck( pNtk ) ) - fprintf( stdout, "Abc_NtkRetimeForward(): Network check has failed.\n" ); - // return the number of latches saved - return nLatches - Abc_NtkLatchNum(pNtk); -} - -/**Function************************************************************* - - Synopsis [Prepares the network for retiming.] - - Description [Hash latches into their number in the original network.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -st_table * Abc_NtkRetimePrepareLatches( Abc_Ntk_t * pNtk ) -{ - st_table * tLatches; - Abc_Obj_t * pLatch, * pLatchIn, * pLatchOut, * pFanin; - int i, nOffSet = Abc_NtkBoxNum(pNtk) - Abc_NtkLatchNum(pNtk); - // collect latches and remove CIs/COs - tLatches = st_init_table( st_ptrcmp, st_ptrhash ); - Abc_NtkForEachLatch( pNtk, pLatch, i ) - { - // map latch into its true number - st_insert( tLatches, (void *)pLatch, (void *)(i-nOffSet) ); - // disconnect LI - pLatchIn = Abc_ObjFanin0(pLatch); - pFanin = Abc_ObjFanin0(pLatchIn); - Abc_ObjTransferFanout( pLatchIn, pFanin ); - Abc_ObjDeleteFanin( pLatchIn, pFanin ); - // disconnect LO - pLatchOut = Abc_ObjFanout0(pLatch); - pFanin = Abc_ObjFanin0(pLatchOut); - if ( Abc_ObjFanoutNum(pLatchOut) > 0 ) - Abc_ObjTransferFanout( pLatchOut, pFanin ); - Abc_ObjDeleteFanin( pLatchOut, pFanin ); - } - return tLatches; -} - -/**Function************************************************************* - - Synopsis [Finalizes the latches after retiming.] - - Description [Reuses the LIs/LOs for old latches.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeFinalizeLatches( Abc_Ntk_t * pNtk, st_table * tLatches, int nIdMaxStart ) -{ - Vec_Ptr_t * vCisOld, * vCosOld, * vBoxesOld, * vCisNew, * vCosNew, * vBoxesNew; - Abc_Obj_t * pObj, * pLatch, * pLatchIn, * pLatchOut; - int i, Index; - // create new arrays - vCisOld = pNtk->vCis; pNtk->vCis = NULL; vCisNew = Vec_PtrAlloc( 100 ); - vCosOld = pNtk->vCos; pNtk->vCos = NULL; vCosNew = Vec_PtrAlloc( 100 ); - vBoxesOld = pNtk->vBoxes; pNtk->vBoxes = NULL; vBoxesNew = Vec_PtrAlloc( 100 ); - // copy boxes and their CIs/COs - Vec_PtrForEachEntryStop( vCisOld, pObj, i, Vec_PtrSize(vCisOld) - st_count(tLatches) ) - Vec_PtrPush( vCisNew, pObj ); - Vec_PtrForEachEntryStop( vCosOld, pObj, i, Vec_PtrSize(vCosOld) - st_count(tLatches) ) - Vec_PtrPush( vCosNew, pObj ); - Vec_PtrForEachEntryStop( vBoxesOld, pObj, i, Vec_PtrSize(vBoxesOld) - st_count(tLatches) ) - Vec_PtrPush( vBoxesNew, pObj ); - // go through the latches - Abc_NtkForEachObj( pNtk, pLatch, i ) - { - if ( !Abc_ObjIsLatch(pLatch) ) - continue; - if ( Abc_ObjId(pLatch) >= (unsigned)nIdMaxStart ) - { - // this is a new latch - pLatchIn = Abc_NtkCreateBi(pNtk); - pLatchOut = Abc_NtkCreateBo(pNtk); - Abc_ObjAssignName( pLatchOut, Abc_ObjName(pLatch), "_out" ); - Abc_ObjAssignName( pLatchIn, Abc_ObjName(pLatch), "_in" ); - } - else - { - // this is an old latch - // get its number in the original order - if ( !st_lookup( tLatches, (char *)pLatch, (char **)&Index ) ) - { - printf( "Abc_NtkRetimeFinalizeLatches(): Internal error.\n" ); - return 0; - } - assert( pLatch == Vec_PtrEntry(vBoxesOld, Vec_PtrSize(vBoxesOld) - st_count(tLatches) + Index) ); - // reconnect with the old LIs/LOs - pLatchIn = Vec_PtrEntry( vCosOld, Vec_PtrSize(vCosOld) - st_count(tLatches) + Index ); - pLatchOut = Vec_PtrEntry( vCisOld, Vec_PtrSize(vCisOld) - st_count(tLatches) + Index ); - } - // connect - Abc_ObjAddFanin( pLatchIn, Abc_ObjFanin0(pLatch) ); - Abc_ObjPatchFanin( pLatch, Abc_ObjFanin0(pLatch), pLatchIn ); - if ( Abc_ObjFanoutNum(pLatch) > 0 ) - Abc_ObjTransferFanout( pLatch, pLatchOut ); - Abc_ObjAddFanin( pLatchOut, pLatch ); - // add to the arrays - Vec_PtrPush( vCisNew, pLatchOut ); - Vec_PtrPush( vCosNew, pLatchIn ); - Vec_PtrPush( vBoxesNew, pLatch ); - } - // free useless Cis/Cos - Vec_PtrForEachEntry( vCisOld, pObj, i ) - if ( !Abc_ObjIsPi(pObj) && Abc_ObjFaninNum(pObj) == 0 && Abc_ObjFanoutNum(pObj) == 0 ) - Abc_NtkDeleteObj(pObj); - Vec_PtrForEachEntry( vCosOld, pObj, i ) - if ( !Abc_ObjIsPo(pObj) && Abc_ObjFaninNum(pObj) == 0 && Abc_ObjFanoutNum(pObj) == 0 ) - Abc_NtkDeleteObj(pObj); - // set the new arrays - pNtk->vCis = vCisNew; Vec_PtrFree( vCisOld ); - pNtk->vCos = vCosNew; Vec_PtrFree( vCosOld ); - pNtk->vBoxes = vBoxesNew; Vec_PtrFree( vBoxesOld ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Performs retiming one way, forward or backward.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeOneWay( Abc_Ntk_t * pNtk, int fForward, int fVerbose ) -{ - Abc_Ntk_t * pNtkNew; - Vec_Int_t * vValues; - Abc_Obj_t * pObj; - int i, fChanges, nTotalMoves = 0, nTotalMovesLimit = 10000; - if ( fForward ) - Abc_NtkRetimeTranferToCopy( pNtk ); - else - { - // save initial values of the latches - vValues = Abc_NtkRetimeCollectLatchValues( pNtk ); - // start the network for initial value computation - pNtkNew = Abc_NtkRetimeBackwardInitialStart( pNtk ); - } - // try to move latches forward whenever possible - do { - fChanges = 0; - Abc_NtkForEachObj( pNtk, pObj, i ) - { - if ( !Abc_ObjIsNode(pObj) ) - continue; - if ( Abc_NtkRetimeNodeIsEnabled( pObj, fForward ) ) - { - Abc_NtkRetimeNode( pObj, fForward, 1 ); - fChanges = 1; - nTotalMoves++; - if ( nTotalMoves >= nTotalMovesLimit ) - { - printf( "Stopped after %d latch moves.\n", nTotalMoves ); - break; - } - } - } - } while ( fChanges && nTotalMoves < nTotalMovesLimit ); - // transfer the initial state back to the latches - if ( fForward ) - Abc_NtkRetimeTranferFromCopy( pNtk ); - else - { - Abc_NtkRetimeBackwardInitialFinish( pNtk, pNtkNew, vValues, fVerbose ); - Abc_NtkDelete( pNtkNew ); - Vec_IntFree( vValues ); - } - return 0; -} - - -/**Function************************************************************* - - Synopsis [Returns 1 if retiming forward/backward is possible.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeNodeIsEnabled( Abc_Obj_t * pObj, int fForward ) -{ - Abc_Obj_t * pNext; - int i; - assert( Abc_ObjIsNode(pObj) ); - if ( fForward ) - { - Abc_ObjForEachFanin( pObj, pNext, i ) - if ( !Abc_ObjIsLatch(pNext) ) - return 0; - } - else - { - Abc_ObjForEachFanout( pObj, pNext, i ) - if ( !Abc_ObjIsLatch(pNext) ) - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Retimes the node backward or forward.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRetimeNode( Abc_Obj_t * pObj, int fForward, int fInitial ) -{ - Abc_Ntk_t * pNtkNew = NULL; - Vec_Ptr_t * vNodes; - Abc_Obj_t * pNext, * pLatch; - int i; - vNodes = Vec_PtrAlloc( 10 ); - if ( fForward ) - { - // compute the initial value - if ( fInitial ) - pObj->pCopy = (void *)Abc_ObjSopSimulate( pObj ); - // collect fanins - Abc_NodeCollectFanins( pObj, vNodes ); - // make the node point to the fanins fanins - Vec_PtrForEachEntry( vNodes, pNext, i ) - { - assert( Abc_ObjIsLatch(pNext) ); - Abc_ObjPatchFanin( pObj, pNext, Abc_ObjFanin0(pNext) ); - if ( Abc_ObjFanoutNum(pNext) == 0 ) - Abc_NtkDeleteObj(pNext); - } - // add a new latch on top - pNext = Abc_NtkCreateLatch(pObj->pNtk); - if ( Abc_ObjFanoutNum(pObj) > 0 ) - Abc_ObjTransferFanout( pObj, pNext ); - Abc_ObjAddFanin( pNext, pObj ); - // set the initial value - if ( fInitial ) - pNext->pCopy = pObj->pCopy; - } - else - { - // compute the initial value - if ( fInitial ) - { - pNtkNew = Abc_ObjFanout0(pObj)->pCopy->pNtk; - Abc_NtkDupObj( pNtkNew, pObj, 0 ); - Abc_ObjForEachFanout( pObj, pNext, i ) - { - assert( Abc_ObjFaninNum(pNext->pCopy) == 0 ); - Abc_ObjAddFanin( pNext->pCopy, pObj->pCopy ); - } - } - // collect fanouts - Abc_NodeCollectFanouts( pObj, vNodes ); - // make the fanouts fanouts point to the node - Vec_PtrForEachEntry( vNodes, pNext, i ) - { - assert( Abc_ObjIsLatch(pNext) ); - Abc_ObjTransferFanout( pNext, pObj ); - Abc_NtkDeleteObj( pNext ); - } - // add new latches to the fanins - Abc_ObjForEachFanin( pObj, pNext, i ) - { - pLatch = Abc_NtkCreateLatch(pObj->pNtk); - Abc_ObjPatchFanin( pObj, pNext, pLatch ); - Abc_ObjAddFanin( pLatch, pNext ); - // create buffer isomorphic to this latch - if ( fInitial ) - { - pLatch->pCopy = Abc_NtkCreateNodeBuf( pNtkNew, NULL ); - Abc_ObjAddFanin( pObj->pCopy, pLatch->pCopy ); - } - } - } - Vec_PtrFree( vNodes ); -} - -/**Function************************************************************* - - Synopsis [Returns the number of compatible fanout latches.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeCheckCompatibleLatchFanouts( Abc_Obj_t * pObj ) -{ - Abc_Obj_t * pFanout; - int i, nLatches = 0, Init = -1; - Abc_ObjForEachFanout( pObj, pFanout, i ) - { - if ( !Abc_ObjIsLatch(pFanout) ) - continue; - if ( Init == -1 ) - { - Init = (int)pObj->pData; - nLatches++; - } - else if ( Init == (int)pObj->pData ) - nLatches++; - } - return nLatches; -} - -/**Function************************************************************* - - Synopsis [Retimes the node backward or forward.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRetimeShareLatches( Abc_Ntk_t * pNtk, int fInitial ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pFanin, * pLatchTop, * pLatchCur; - int i, k; - vNodes = Vec_PtrAlloc( 10 ); - // consider latch fanins - Abc_NtkForEachObj( pNtk, pFanin, i ) - { - if ( Abc_NtkRetimeCheckCompatibleLatchFanouts(pFanin) <= 1 ) - continue; - // get the first latch - pLatchTop = NULL; - Abc_ObjForEachFanout( pFanin, pLatchTop, k ) - if ( Abc_ObjIsLatch(pLatchTop) ) - break; - assert( pLatchTop && Abc_ObjIsLatch(pLatchTop) ); - // redirect compatible fanout latches to the first latch - Abc_NodeCollectFanouts( pFanin, vNodes ); - Vec_PtrForEachEntry( vNodes, pLatchCur, k ) - { - if ( !Abc_ObjIsLatch(pLatchCur) ) - continue; - if ( pLatchCur == pLatchTop ) - continue; - if ( pLatchCur->pData != pLatchTop->pData ) - continue; - // connect the initial state - if ( fInitial ) - Abc_ObjAddFanin( pLatchCur->pCopy, pLatchTop->pCopy ); - // redirect the fanouts - Abc_ObjTransferFanout( pLatchCur, pLatchTop ); - Abc_NtkDeleteObj(pLatchCur); - } - } - Vec_PtrFree( vNodes ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/ret/retInit.c b/src/opt/ret/retInit.c deleted file mode 100644 index dcb71c60..00000000 --- a/src/opt/ret/retInit.c +++ /dev/null @@ -1,349 +0,0 @@ -/**CFile**************************************************************** - - FileName [retInit.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Retiming package.] - - Synopsis [Initial state computation for backward retiming.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - Oct 31, 2006.] - - Revision [$Id: retInit.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "retInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int Abc_NtkRetimeVerifyModel( Abc_Ntk_t * pNtkCone, Vec_Int_t * vValues, int * pModel ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes initial values of the new latches.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Abc_NtkRetimeInitialValues( Abc_Ntk_t * pNtkCone, Vec_Int_t * vValues, int fVerbose ) -{ - Vec_Int_t * vSolution; - Abc_Ntk_t * pNtkMiter, * pNtkLogic; - int RetValue, clk; - if ( pNtkCone == NULL ) - return Vec_IntDup( vValues ); - // convert the target network to AIG - pNtkLogic = Abc_NtkDup( pNtkCone ); - Abc_NtkToAig( pNtkLogic ); - // get the miter - pNtkMiter = Abc_NtkCreateTarget( pNtkLogic, pNtkLogic->vCos, vValues ); - if ( fVerbose ) - printf( "The miter for initial state computation has %d AIG nodes. ", Abc_NtkNodeNum(pNtkMiter) ); - // solve the miter - clk = clock(); - RetValue = Abc_NtkMiterSat( pNtkMiter, (sint64)500000, (sint64)50000000, 0, NULL, NULL ); - if ( fVerbose ) - { PRT( "SAT solving time", clock() - clk ); } - // analyze the result - if ( RetValue == 1 ) - printf( "Abc_NtkRetimeInitialValues(): The problem is unsatisfiable. DC latch values are used.\n" ); - else if ( RetValue == -1 ) - printf( "Abc_NtkRetimeInitialValues(): The SAT problem timed out. DC latch values are used.\n" ); - else if ( !Abc_NtkRetimeVerifyModel( pNtkCone, vValues, pNtkMiter->pModel ) ) - printf( "Abc_NtkRetimeInitialValues(): The computed counter-example is incorrect.\n" ); - // set the values of the latches - vSolution = RetValue? NULL : Vec_IntAllocArray( pNtkMiter->pModel, Abc_NtkPiNum(pNtkLogic) ); - pNtkMiter->pModel = NULL; - Abc_NtkDelete( pNtkMiter ); - Abc_NtkDelete( pNtkLogic ); - return vSolution; -} - -/**Function************************************************************* - - Synopsis [Computes the results of simulating one node.] - - Description [Assumes that fanins have pCopy set to the input values.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_ObjSopSimulate( Abc_Obj_t * pObj ) -{ - char * pCube, * pSop = pObj->pData; - int nVars, Value, v, ResOr, ResAnd, ResVar; - assert( pSop && !Abc_SopIsExorType(pSop) ); - // simulate the SOP of the node - ResOr = 0; - nVars = Abc_SopGetVarNum(pSop); - Abc_SopForEachCube( pSop, nVars, pCube ) - { - ResAnd = 1; - Abc_CubeForEachVar( pCube, Value, v ) - { - if ( Value == '0' ) - ResVar = 1 ^ ((int)Abc_ObjFanin(pObj, v)->pCopy); - else if ( Value == '1' ) - ResVar = (int)Abc_ObjFanin(pObj, v)->pCopy; - else - continue; - ResAnd &= ResVar; - } - ResOr |= ResAnd; - } - // complement the result if necessary - if ( !Abc_SopGetPhase(pSop) ) - ResOr ^= 1; - return ResOr; -} - -/**Function************************************************************* - - Synopsis [Verifies the counter-example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeVerifyModel( Abc_Ntk_t * pNtkCone, Vec_Int_t * vValues, int * pModel ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj; - int i, Counter = 0; - assert( Abc_NtkIsSopLogic(pNtkCone) ); - // set the PIs - Abc_NtkForEachPi( pNtkCone, pObj, i ) - pObj->pCopy = (void *)pModel[i]; - // simulate the internal nodes - vNodes = Abc_NtkDfs( pNtkCone, 0 ); - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = (void *)Abc_ObjSopSimulate( pObj ); - Vec_PtrFree( vNodes ); - // compare the outputs - Abc_NtkForEachPo( pNtkCone, pObj, i ) - pObj->pCopy = Abc_ObjFanin0(pObj)->pCopy; - Abc_NtkForEachPo( pNtkCone, pObj, i ) - Counter += (Vec_IntEntry(vValues, i) != (int)pObj->pCopy); - if ( Counter > 0 ) - printf( "%d outputs (out of %d) have a value mismatch.\n", Counter, Abc_NtkPoNum(pNtkCone) ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Transfer latch initial values to pCopy.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRetimeTranferToCopy( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i; - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( Abc_ObjIsLatch(pObj) ) - pObj->pCopy = (void *)Abc_LatchIsInit1(pObj); -} - -/**Function************************************************************* - - Synopsis [Transfer latch initial values from pCopy.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRetimeTranferFromCopy( Abc_Ntk_t * pNtk ) -{ - Abc_Obj_t * pObj; - int i; - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( Abc_ObjIsLatch(pObj) ) - pObj->pData = (void *)(pObj->pCopy? ABC_INIT_ONE : ABC_INIT_ZERO); -} - -/**Function************************************************************* - - Synopsis [Transfer latch initial values to pCopy.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Abc_NtkRetimeCollectLatchValues( Abc_Ntk_t * pNtk ) -{ - Vec_Int_t * vValues; - Abc_Obj_t * pObj; - int i; - vValues = Vec_IntAlloc( Abc_NtkLatchNum(pNtk) ); - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( Abc_ObjIsLatch(pObj) ) - Vec_IntPush( vValues, Abc_LatchIsInit1(pObj) ); - return vValues; -} - -/**Function************************************************************* - - Synopsis [Transfer latch initial values from pCopy.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRetimeInsertLatchValues( Abc_Ntk_t * pNtk, Vec_Int_t * vValues ) -{ - Abc_Obj_t * pObj; - int i, Counter = 0; - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( Abc_ObjIsLatch(pObj) ) - pObj->pCopy = (void *)Counter++; - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( Abc_ObjIsLatch(pObj) ) - pObj->pData = (void *)(vValues? (Vec_IntEntry(vValues,(int)pObj->pCopy)? ABC_INIT_ONE : ABC_INIT_ZERO) : ABC_INIT_DC); -} - -/**Function************************************************************* - - Synopsis [Transfer latch initial values to pCopy.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Ntk_t * Abc_NtkRetimeBackwardInitialStart( Abc_Ntk_t * pNtk ) -{ - Abc_Ntk_t * pNtkNew; - Abc_Obj_t * pObj; - int i; - // create the network used for the initial state computation - pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); - // create POs corresponding to the initial values - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( Abc_ObjIsLatch(pObj) ) - pObj->pCopy = Abc_NtkCreatePo(pNtkNew); - return pNtkNew; -} - -/**Function************************************************************* - - Synopsis [Transfer latch initial values to pCopy.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkRetimeBackwardInitialFinish( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, Vec_Int_t * vValuesOld, int fVerbose ) -{ - Vec_Int_t * vValuesNew; - Abc_Obj_t * pObj; - int i; - // create PIs corresponding to the initial values - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( Abc_ObjIsLatch(pObj) ) - Abc_ObjAddFanin( pObj->pCopy, Abc_NtkCreatePi(pNtkNew) ); - // assign dummy node names - Abc_NtkAddDummyPiNames( pNtkNew ); - Abc_NtkAddDummyPoNames( pNtkNew ); - // check the network - if ( !Abc_NtkCheck( pNtkNew ) ) - fprintf( stdout, "Abc_NtkRetimeBackwardInitialFinish(): Network check has failed.\n" ); - // derive new initial values - vValuesNew = Abc_NtkRetimeInitialValues( pNtkNew, vValuesOld, fVerbose ); - // insert new initial values - Abc_NtkRetimeInsertLatchValues( pNtk, vValuesNew ); - if ( vValuesNew ) Vec_IntFree( vValuesNew ); -} - - -/**Function************************************************************* - - Synopsis [Cycles the circuit to create a new initial state.] - - Description [Simulates the circuit with random input for the given - number of timeframes to get a better initial state.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_NtkCycleInitStateSop( Abc_Ntk_t * pNtk, int nFrames, int fVerbose ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pObj; - int i, f; - assert( Abc_NtkIsSopLogic(pNtk) ); - srand( 0x12341234 ); - // initialize the values - Abc_NtkForEachPi( pNtk, pObj, i ) - pObj->pCopy = (void *)(rand() & 1); - Abc_NtkForEachLatch( pNtk, pObj, i ) - pObj->pCopy = (void *)Abc_LatchIsInit1(pObj); - // simulate for the given number of timeframes - vNodes = Abc_NtkDfs( pNtk, 0 ); - for ( f = 0; f < nFrames; f++ ) - { - // simulate internal nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->pCopy = (void *)Abc_ObjSopSimulate( pObj ); - // bring the results to the COs - Abc_NtkForEachCo( pNtk, pObj, i ) - pObj->pCopy = Abc_ObjFanin0(pObj)->pCopy; - // assign PI values - Abc_NtkForEachPi( pNtk, pObj, i ) - pObj->pCopy = (void *)(rand() & 1); - // transfer the latch values - Abc_NtkForEachLatch( pNtk, pObj, i ) - Abc_ObjFanout0(pObj)->pCopy = Abc_ObjFanin0(pObj)->pCopy; - } - Vec_PtrFree( vNodes ); - // set the final values - Abc_NtkForEachLatch( pNtk, pObj, i ) - pObj->pData = (void *)(Abc_ObjFanout0(pObj)->pCopy ? ABC_INIT_ONE : ABC_INIT_ZERO); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/ret/retInt.h b/src/opt/ret/retInt.h deleted file mode 100644 index 51428bce..00000000 --- a/src/opt/ret/retInt.h +++ /dev/null @@ -1,80 +0,0 @@ -/**CFile**************************************************************** - - FileName [retInt.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Retiming package.] - - Synopsis [Internal declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - Oct 31, 2006.] - - Revision [$Id: retInt.h,v 1.00 2006/10/31 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __RET_INT_H__ -#define __RET_INT_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include "abc.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// STRUCTURE DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== retArea.c ========================================================*/ -extern int Abc_NtkRetimeMinArea( Abc_Ntk_t * pNtk, int fForwardOnly, int fBackwardOnly, int fVerbose ); -/*=== retCore.c ========================================================*/ -extern int Abc_NtkRetime( Abc_Ntk_t * pNtk, int Mode, int fForwardOnly, int fBackwardOnly, int fOneStep, int fVerbose ); -/*=== retDelay.c ========================================================*/ -extern int Abc_NtkRetimeMinDelay( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkCopy, int nIterLimit, int fForward, int fVerbose ); -/*=== retDirect.c ========================================================*/ -extern int Abc_NtkRetimeIncremental( Abc_Ntk_t * pNtk, int fForward, int fMinDelay, int fOneStep, int fVerbose ); -extern void Abc_NtkRetimeShareLatches( Abc_Ntk_t * pNtk, int fInitial ); -extern int Abc_NtkRetimeNodeIsEnabled( Abc_Obj_t * pObj, int fForward ); -extern void Abc_NtkRetimeNode( Abc_Obj_t * pObj, int fForward, int fInitial ); -extern st_table * Abc_NtkRetimePrepareLatches( Abc_Ntk_t * pNtk ); -extern int Abc_NtkRetimeFinalizeLatches( Abc_Ntk_t * pNtk, st_table * tLatches, int nIdMaxStart ); -/*=== retFlow.c ========================================================*/ -extern void Abc_NtkMaxFlowTest( Abc_Ntk_t * pNtk ); -extern Vec_Ptr_t * Abc_NtkMaxFlow( Abc_Ntk_t * pNtk, int fForward, int fVerbose ); -/*=== retInit.c ========================================================*/ -extern Vec_Int_t * Abc_NtkRetimeInitialValues( Abc_Ntk_t * pNtkSat, Vec_Int_t * vValues, int fVerbose ); -extern int Abc_ObjSopSimulate( Abc_Obj_t * pObj ); -extern void Abc_NtkRetimeTranferToCopy( Abc_Ntk_t * pNtk ); -extern void Abc_NtkRetimeTranferFromCopy( Abc_Ntk_t * pNtk ); -extern Vec_Int_t * Abc_NtkRetimeCollectLatchValues( Abc_Ntk_t * pNtk ); -extern void Abc_NtkRetimeInsertLatchValues( Abc_Ntk_t * pNtk, Vec_Int_t * vValues ); -extern Abc_Ntk_t * Abc_NtkRetimeBackwardInitialStart( Abc_Ntk_t * pNtk ); -extern void Abc_NtkRetimeBackwardInitialFinish( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, Vec_Int_t * vValuesOld, int fVerbose ); -/*=== retLvalue.c ========================================================*/ -extern int Abc_NtkRetimeLValue( Abc_Ntk_t * pNtk, int nIterLimit, int fVerbose ); - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/ret/retLvalue.c b/src/opt/ret/retLvalue.c deleted file mode 100644 index b4d9e946..00000000 --- a/src/opt/ret/retLvalue.c +++ /dev/null @@ -1,395 +0,0 @@ -/**CFile**************************************************************** - - FileName [retLvalue.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Retiming package.] - - Synopsis [Implementation of Pan's retiming algorithm.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - Oct 31, 2006.] - - Revision [$Id: retLvalue.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "retInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// node status after updating its arrival time -enum { ABC_RET_UPDATE_FAIL, ABC_RET_UPDATE_NO, ABC_RET_UPDATE_YES }; - -// the internal procedures -static Vec_Int_t * Abc_NtkRetimeGetLags( Abc_Ntk_t * pNtk, int nIterLimit, int fVerbose ); -static int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int FiMin, int FiMax, int nMaxIters, int fVerbose ); -static int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int Fi, int nMaxIters, int fVerbose ); -static int Abc_NtkRetimeUpdateLValue( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int Fi ); -static int Abc_NtkRetimePosOverLimit( Abc_Ntk_t * pNtk, int Fi ); -static Vec_Ptr_t * Abc_ManCollectLatches( Abc_Ntk_t * pNtk ); -static int Abc_NtkRetimeUsingLags( Abc_Ntk_t * pNtk, Vec_Int_t * vLags, int fVerbose ); - -static inline int Abc_NodeComputeLag( int LValue, int Fi ) { return (LValue + (1<<16)*Fi)/Fi - (1<<16) - (int)(LValue % Fi == 0); } -static inline int Abc_NodeGetLValue( Abc_Obj_t * pNode ) { return (int)pNode->pCopy; } -static inline void Abc_NodeSetLValue( Abc_Obj_t * pNode, int Value ) { pNode->pCopy = (void *)Value; } - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Implements Pan's retiming algorithm.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeLValue( Abc_Ntk_t * pNtk, int nIterLimit, int fVerbose ) -{ - Vec_Int_t * vLags; - int nLatches = Abc_NtkLatchNum(pNtk); - assert( Abc_NtkIsLogic( pNtk ) ); - // get the lags - vLags = Abc_NtkRetimeGetLags( pNtk, nIterLimit, fVerbose ); - // compute the retiming -// Abc_NtkRetimeUsingLags( pNtk, vLags, fVerbose ); - Vec_IntFree( vLags ); - // fix the COs -// Abc_NtkLogicMakeSimpleCos( pNtk, 0 ); - // check for correctness - if ( !Abc_NtkCheck( pNtk ) ) - fprintf( stdout, "Abc_NtkRetimeLValue(): Network check has failed.\n" ); - // return the number of latches saved - return nLatches - Abc_NtkLatchNum(pNtk); -} - -/**Function************************************************************* - - Synopsis [Computes the retiming lags.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Abc_NtkRetimeGetLags( Abc_Ntk_t * pNtk, int nIterLimit, int fVerbose ) -{ - Vec_Int_t * vLags; - Vec_Ptr_t * vNodes, * vLatches; - Abc_Obj_t * pNode; - int i, FiMax, FiBest, RetValue, clk, clkIter; - char NodeLag; - - // get the upper bound on the clock period - FiMax = Abc_NtkLevel(pNtk); - - // make sure this clock period is feasible - vNodes = Abc_NtkDfs( pNtk, 0 ); - vLatches = Abc_ManCollectLatches( pNtk ); - if ( !Abc_NtkRetimeForPeriod( pNtk, vNodes, vLatches, FiMax, nIterLimit, fVerbose ) ) - { - Vec_PtrFree( vNodes ); - printf( "Abc_NtkRetimeGetLags() error: The upper bound on the clock period cannot be computed.\n" ); - return Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 ); - } - - // search for the optimal clock period between 0 and nLevelMax -clk = clock(); - FiBest = Abc_NtkRetimeSearch_rec( pNtk, vNodes, vLatches, 0, FiMax, nIterLimit, fVerbose ); -clkIter = clock() - clk; - - // recompute the best l-values - RetValue = Abc_NtkRetimeForPeriod( pNtk, vNodes, vLatches, FiBest, nIterLimit, fVerbose ); - assert( RetValue ); - - // fix the problem with non-converged delays - Abc_NtkForEachNode( pNtk, pNode, i ) - if ( Abc_NodeGetLValue(pNode) < -ABC_INFINITY/2 ) - Abc_NodeSetLValue( pNode, 0 ); - - // write the retiming lags - vLags = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 ); - Abc_NtkForEachNode( pNtk, pNode, i ) - { - NodeLag = Abc_NodeComputeLag( Abc_NodeGetLValue(pNode), FiBest ); - Vec_IntWriteEntry( vLags, pNode->Id, NodeLag ); - } -/* - Abc_NtkForEachPo( pNtk, pNode, i ) - printf( "%d ", Abc_NodeGetLValue(Abc_ObjFanin0(pNode)) ); - printf( "\n" ); - Abc_NtkForEachLatch( pNtk, pNode, i ) - printf( "%d/%d ", Abc_NodeGetLValue(Abc_ObjFanout0(pNode)), Abc_NodeGetLValue(Abc_ObjFanout0(pNode)) + FiBest ); - printf( "\n" ); -*/ - - // print the result -// if ( fVerbose ) - printf( "The best clock period is %3d. (Currently, network is not modified.)\n", FiBest ); -/* - { - FILE * pTable; - pTable = fopen( "iscas/seqmap__stats2.txt", "a+" ); - fprintf( pTable, "%d ", FiBest ); - fprintf( pTable, "\n" ); - fclose( pTable ); - } -*/ - Vec_PtrFree( vNodes ); - Vec_PtrFree( vLatches ); - return vLags; -} - -/**Function************************************************************* - - Synopsis [Performs binary search for the optimal clock period.] - - Description [Assumes that FiMin is infeasible while FiMax is feasible.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeSearch_rec( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int FiMin, int FiMax, int nMaxIters, int fVerbose ) -{ - int Median; - assert( FiMin < FiMax ); - if ( FiMin + 1 == FiMax ) - return FiMax; - Median = FiMin + (FiMax - FiMin)/2; - if ( Abc_NtkRetimeForPeriod( pNtk, vNodes, vLatches, Median, nMaxIters, fVerbose ) ) - return Abc_NtkRetimeSearch_rec( pNtk, vNodes, vLatches, FiMin, Median, nMaxIters, fVerbose ); // Median is feasible - else - return Abc_NtkRetimeSearch_rec( pNtk, vNodes, vLatches, Median, FiMax, nMaxIters, fVerbose ); // Median is infeasible -} - -/**Function************************************************************* - - Synopsis [Returns 1 if retiming with this clock period is feasible.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeForPeriod( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int Fi, int nMaxIters, int fVerbose ) -{ - Abc_Obj_t * pObj; - int c, i, fConverged; - // set l-values of all nodes to be minus infinity, except PIs and constants - Abc_NtkForEachObj( pNtk, pObj, i ) - if ( Abc_ObjFaninNum(pObj) == 0 ) - Abc_NodeSetLValue( pObj, 0 ); - else - Abc_NodeSetLValue( pObj, -ABC_INFINITY ); - // update all values iteratively - fConverged = 0; - for ( c = 1; c <= nMaxIters; c++ ) - { - if ( !Abc_NtkRetimeUpdateLValue( pNtk, vNodes, vLatches, Fi ) ) - { - fConverged = 1; - break; - } - if ( Abc_NtkRetimePosOverLimit(pNtk, Fi) ) - break; - } - // report the results - if ( fVerbose ) - { - if ( !fConverged ) - printf( "Period = %3d. Iterations = %3d. Infeasible %s\n", Fi, c, (c > nMaxIters)? "(timeout)" : "" ); - else - printf( "Period = %3d. Iterations = %3d. Feasible\n", Fi, c ); - } -/* - // check if any AND gates have infinite delay - Counter = 0; - Abc_NtkForEachNode( pNtk, pObj, i ) - Counter += (Abc_NodeGetLValue(pObj) < -ABC_INFINITY/2); - if ( Counter > 0 ) - printf( "Warning: %d internal nodes have wrong l-values!\n", Counter ); -*/ - return fConverged; -} - -/**Function************************************************************* - - Synopsis [Performs one iteration of l-value computation for the nodes.] - - Description [Experimentally it was found that checking POs changes - is not enough to detect the convergence of l-values in the network.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeUpdateLValue( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, Vec_Ptr_t * vLatches, int Fi ) -{ - Abc_Obj_t * pObj, * pFanin; - int i, k, lValueNew, fChange; - // go through the nodes and detect change - fChange = 0; - Vec_PtrForEachEntry( vNodes, pObj, i ) - { - assert( Abc_ObjIsNode(pObj) ); - lValueNew = -ABC_INFINITY; - Abc_ObjForEachFanin( pObj, pFanin, k ) - { - if ( lValueNew < Abc_NodeGetLValue(pFanin) ) - lValueNew = Abc_NodeGetLValue(pFanin); - } - lValueNew++; - if ( Abc_NodeGetLValue(pObj) < lValueNew ) - { - Abc_NodeSetLValue( pObj, lValueNew ); - fChange = 1; - } - } - // propagate values through the latches - Vec_PtrForEachEntry( vLatches, pObj, i ) - Abc_NodeSetLValue( Abc_ObjFanout0(pObj), Abc_NodeGetLValue(Abc_ObjFanin0(Abc_ObjFanin0(pObj))) - Fi ); - return fChange; -} - -/**Function************************************************************* - - Synopsis [Detects the case when l-values exceeded the limit.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimePosOverLimit( Abc_Ntk_t * pNtk, int Fi ) -{ - Abc_Obj_t * pObj; - int i; - Abc_NtkForEachPo( pNtk, pObj, i ) - if ( Abc_NodeGetLValue(Abc_ObjFanin0(pObj)) > Fi ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [Collects latches in the topological order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_ManCollectLatches_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLatches ) -{ - Abc_Obj_t * pDriver; - if ( !Abc_ObjIsLatch(pObj) ) - return; - // skip already collected latches - if ( Abc_NodeIsTravIdCurrent(pObj) ) - return; - Abc_NodeSetTravIdCurrent(pObj); - // get the driver node feeding into the latch - pDriver = Abc_ObjFanin0(Abc_ObjFanin0(pObj)); - // call recursively if the driver looks like a latch output - if ( Abc_ObjIsBo(pDriver) ) - Abc_ManCollectLatches_rec( Abc_ObjFanin0(pDriver), vLatches ); - // collect the latch - Vec_PtrPush( vLatches, pObj ); -} - -/**Function************************************************************* - - Synopsis [Collects latches in the topological order.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Abc_ManCollectLatches( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vLatches; - Abc_Obj_t * pObj; - int i; - vLatches = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) ); - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkForEachLatch( pNtk, pObj, i ) - Abc_ManCollectLatches_rec( pObj, vLatches ); - assert( Vec_PtrSize(vLatches) == Abc_NtkLatchNum(pNtk) ); - return vLatches; -} - -/**Function************************************************************* - - Synopsis [Implements the retiming given as the array of retiming lags.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Abc_NtkRetimeUsingLags( Abc_Ntk_t * pNtk, Vec_Int_t * vLags, int fVerbose ) -{ - Abc_Obj_t * pObj; - int fChanges, fForward, nTotalMoves, Lag, Counter, i; - // iterate over the nodes - nTotalMoves = 0; - do { - fChanges = 0; - Abc_NtkForEachNode( pNtk, pObj, i ) - { - Lag = Vec_IntEntry( vLags, pObj->Id ); - if ( !Lag ) - continue; - fForward = (Lag < 0); - if ( Abc_NtkRetimeNodeIsEnabled( pObj, fForward ) ) - { - Abc_NtkRetimeNode( pObj, fForward, 0 ); - fChanges = 1; - nTotalMoves++; - Vec_IntAddToEntry( vLags, pObj->Id, fForward? 1 : -1 ); - } - } - } while ( fChanges ); - if ( fVerbose ) - printf( "Total latch moves = %d.\n", nTotalMoves ); - // check if there are remaining lags - Counter = 0; - Abc_NtkForEachNode( pNtk, pObj, i ) - Counter += (Vec_IntEntry( vLags, pObj->Id ) != 0); - if ( Counter ) - printf( "Warning! The number of nodes with unrealized lag = %d.\n", Counter ); - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/ret/ret_.c b/src/opt/ret/ret_.c deleted file mode 100644 index 89625e17..00000000 --- a/src/opt/ret/ret_.c +++ /dev/null @@ -1,48 +0,0 @@ -/**CFile**************************************************************** - - FileName [ret_.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Retiming package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - Oct 31, 2006.] - - Revision [$Id: ret_.c,v 1.00 2006/10/31 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "retInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/rwr/rwr.h b/src/opt/rwr/rwr.h index f24f9535..6d1a6c06 100644 --- a/src/opt/rwr/rwr.h +++ b/src/opt/rwr/rwr.h @@ -21,10 +21,6 @@ #ifndef __RWR_H__ #define __RWR_H__ -#ifdef __cplusplus -extern "C" { -#endif - //////////////////////////////////////////////////////////////////////// /// INCLUDES /// //////////////////////////////////////////////////////////////////////// @@ -53,7 +49,6 @@ struct Rwr_Man_t_ char * pPhases; // canonical phases char * pPerms; // canonical permutations unsigned char * pMap; // mapping of functions into class numbers - unsigned short * pMapInv; // mapping of classes into functions char * pPractical; // practical NPN classes char ** pPerms4; // four-var permutations // node space @@ -68,17 +63,14 @@ struct Rwr_Man_t_ int nClasses; // the number of NN classes // the result of resynthesis int fCompl; // indicates if the output of FF should be complemented - void * pGraph; // the decomposition tree (temporary) + void * pGraph; // the decomposition tree (temporary) Vec_Ptr_t * vFanins; // the fanins array (temporary) Vec_Ptr_t * vFaninsCur; // the fanins array (temporary) Vec_Int_t * vLevNums; // the array of levels (temporary) - Vec_Ptr_t * vNodesTemp; // the nodes in MFFC (temporary) // node statistics int nNodesConsidered; int nNodesRewritten; int nNodesGained; - int nNodesBeg; - int nNodesEnd; int nScores[222]; int nCutsGood; int nCutsBad; @@ -88,8 +80,6 @@ struct Rwr_Man_t_ int timeCut; int timeRes; int timeEval; - int timeMffc; - int timeUpdate; int timeTotal; }; @@ -97,9 +87,6 @@ struct Rwr_Node_t_ // 24 bytes { int Id; // ID int TravId; // traversal ID - short nScore; - short nGain; - short nAdded; unsigned uTruth : 16; // truth table unsigned Volume : 8; // volume unsigned Level : 6; // level @@ -111,13 +98,13 @@ struct Rwr_Node_t_ // 24 bytes }; // manipulation of complemented attributes -static inline bool Rwr_IsComplement( Rwr_Node_t * p ) { return (bool)(((unsigned long)p) & 01); } -static inline Rwr_Node_t * Rwr_Regular( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned long)(p) & ~01); } -static inline Rwr_Node_t * Rwr_Not( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned long)(p) ^ 01); } -static inline Rwr_Node_t * Rwr_NotCond( Rwr_Node_t * p, int c ) { return (Rwr_Node_t *)((unsigned long)(p) ^ (c)); } +static inline bool Rwr_IsComplement( Rwr_Node_t * p ) { return (bool)(((unsigned)p) & 01); } +static inline Rwr_Node_t * Rwr_Regular( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned)(p) & ~01); } +static inline Rwr_Node_t * Rwr_Not( Rwr_Node_t * p ) { return (Rwr_Node_t *)((unsigned)(p) ^ 01); } +static inline Rwr_Node_t * Rwr_NotCond( Rwr_Node_t * p, int c ) { return (Rwr_Node_t *)((unsigned)(p) ^ (c)); } //////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// +/// MACRO DEFITIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// @@ -127,9 +114,7 @@ static inline Rwr_Node_t * Rwr_NotCond( Rwr_Node_t * p, int c ) { return (Rwr_N /*=== rwrDec.c ========================================================*/ extern void Rwr_ManPreprocess( Rwr_Man_t * p ); /*=== rwrEva.c ========================================================*/ -extern int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUpdateLevel, int fUseZeros, int fPlaceEnable ); -extern void Rwr_ScoresClean( Rwr_Man_t * p ); -extern void Rwr_ScoresReport( Rwr_Man_t * p ); +extern int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUseZeros ); /*=== rwrLib.c ========================================================*/ extern void Rwr_ManPrecompute( Rwr_Man_t * p ); extern Rwr_Node_t * Rwr_ManAddVar( Rwr_Man_t * p, unsigned uTruth, int fPrecompute ); @@ -140,12 +125,9 @@ extern void Rwr_ManIncTravId( Rwr_Man_t * p ); extern Rwr_Man_t * Rwr_ManStart( bool fPrecompute ); extern void Rwr_ManStop( Rwr_Man_t * p ); extern void Rwr_ManPrintStats( Rwr_Man_t * p ); -extern void Rwr_ManPrintStatsFile( Rwr_Man_t * p ); extern void * Rwr_ManReadDecs( Rwr_Man_t * p ); -extern Vec_Ptr_t * Rwr_ManReadLeaves( Rwr_Man_t * p ); extern int Rwr_ManReadCompl( Rwr_Man_t * p ); extern void Rwr_ManAddTimeCuts( Rwr_Man_t * p, int Time ); -extern void Rwr_ManAddTimeUpdate( Rwr_Man_t * p, int Time ); extern void Rwr_ManAddTimeTotal( Rwr_Man_t * p, int Time ); /*=== rwrPrint.c ========================================================*/ extern void Rwr_ManPrint( Rwr_Man_t * p ); @@ -157,13 +139,9 @@ extern void Rwr_ManLoadFromFile( Rwr_Man_t * p, char * pFileName ); extern void Rwr_ListAddToTail( Rwr_Node_t ** ppList, Rwr_Node_t * pNode ); extern char * Rwr_ManGetPractical( Rwr_Man_t * p ); -#ifdef __cplusplus -} -#endif - -#endif - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +#endif + diff --git a/src/opt/rwr/rwrDec.c b/src/opt/rwr/rwrDec.c index ef7af34f..d072879d 100644 --- a/src/opt/rwr/rwrDec.c +++ b/src/opt/rwr/rwrDec.c @@ -29,7 +29,7 @@ static Dec_Graph_t * Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode ); static Dec_Edge_t Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Dec_Graph_t * pGraph ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -49,8 +49,6 @@ void Rwr_ManPreprocess( Rwr_Man_t * p ) Rwr_Node_t * pNode; int i, k; // put the nodes into the structure - p->pMapInv = ALLOC( unsigned short, 222 ); - memset( p->pMapInv, 0, sizeof(unsigned short) * 222 ); p->vClasses = Vec_VecStart( 222 ); for ( i = 0; i < p->nFuncs; i++ ) { @@ -62,7 +60,6 @@ void Rwr_ManPreprocess( Rwr_Man_t * p ) assert( pNode->uTruth == p->pTable[i]->uTruth ); assert( p->pMap[pNode->uTruth] >= 0 && p->pMap[pNode->uTruth] < 222 ); Vec_VecPush( p->vClasses, p->pMap[pNode->uTruth], pNode ); - p->pMapInv[ p->pMap[pNode->uTruth] ] = p->puCanons[pNode->uTruth]; } } // compute decomposition forms for each node and verify them @@ -135,7 +132,7 @@ Dec_Edge_t Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Dec_Graph_t * eNode1.fCompl = !eNode1.fCompl; // create the decomposition node(s) if ( pNode->fExor ) - eNode = Dec_GraphAddNodeXor( pGraph, eNode0, eNode1, 0 ); + eNode = Dec_GraphAddNodeXor( pGraph, eNode0, eNode1 ); else eNode = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 ); // save the result diff --git a/src/opt/rwr/rwrEva.c b/src/opt/rwr/rwrEva.c index 396a659c..c934dfd8 100644 --- a/src/opt/rwr/rwrEva.c +++ b/src/opt/rwr/rwrEva.c @@ -25,13 +25,10 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, int fPlaceEnable ); -static int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves ); -static int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut ); -static int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves ); +static Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -52,35 +49,27 @@ static int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves ); SeeAlso [] ***********************************************************************/ -int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUpdateLevel, int fUseZeros, int fPlaceEnable ) +int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUseZeros ) { int fVeryVerbose = 0; Dec_Graph_t * pGraph; - Cut_Cut_t * pCut;//, * pTemp; + Cut_Cut_t * pCut; Abc_Obj_t * pFanin; - unsigned uPhase, uTruthBest, uTruth; + unsigned uPhase, uTruthBest; char * pPerm; - int Required, nNodesSaved, nNodesSaveCur; + int Required, nNodesSaved; int i, GainCur, GainBest = -1; - int clk, clk2;//, Counter; + int clk, clk2; p->nNodesConsidered++; // get the required times - Required = fUpdateLevel? Abc_ObjRequiredLevel(pNode) : ABC_INFINITY; - + Required = Abc_NodeReadRequiredLevel( pNode ); // get the node's cuts clk = clock(); - pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0, 0 ); + pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode ); assert( pCut != NULL ); p->timeCut += clock() - clk; -//printf( " %d", Rwr_CutCountNumNodes(pNode, pCut) ); -/* - Counter = 0; - for ( pTemp = pCut->pNext; pTemp; pTemp = pTemp->pNext ) - Counter++; - printf( "%d ", Counter ); -*/ // go through the cuts clk = clock(); for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext ) @@ -88,12 +77,9 @@ clk = clock(); // consider only 4-input cuts if ( pCut->nLeaves < 4 ) continue; -// Cut_CutPrint( pCut, 0 ), printf( "\n" ); - // get the fanin permutation - uTruth = 0xFFFF & *Cut_CutReadTruth(pCut); - pPerm = p->pPerms4[ p->pPerms[uTruth] ]; - uPhase = p->pPhases[uTruth]; + pPerm = p->pPerms4[ p->pPerms[pCut->uTruth] ]; + uPhase = p->pPhases[pCut->uTruth]; // collect fanins with the corresponding permutation/phase Vec_PtrClear( p->vFaninsCur ); Vec_PtrFill( p->vFaninsCur, (int)pCut->nLeaves, 0 ); @@ -112,48 +98,29 @@ clk = clock(); } p->nCutsGood++; - { - int Counter = 0; - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) - if ( Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) == 1 ) - Counter++; - if ( Counter > 2 ) - continue; - } - -clk2 = clock(); -/* - printf( "Considering: (" ); - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) - printf( "%d ", Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) ); - printf( ")\n" ); -*/ // mark the fanin boundary Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) Abc_ObjRegular(pFanin)->vFanouts.nSize++; - // label MFFC with current ID Abc_NtkIncrementTravId( pNode->pNtk ); - nNodesSaved = Abc_NodeMffcLabelAig( pNode ); + nNodesSaved = Abc_NodeMffcLabel( pNode ); // unmark the fanin boundary Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) Abc_ObjRegular(pFanin)->vFanouts.nSize--; -p->timeMffc += clock() - clk2; // evaluate the cut clk2 = clock(); - pGraph = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, fPlaceEnable ); + pGraph = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur ); p->timeEval += clock() - clk2; // check if the cut is better than the current best one if ( pGraph != NULL && GainBest < GainCur ) { // save this form - nNodesSaveCur = nNodesSaved; GainBest = GainCur; p->pGraph = pGraph; p->fCompl = ((uPhase & (1<<4)) > 0); - uTruthBest = 0xFFFF & *Cut_CutReadTruth(pCut); + uTruthBest = pCut->uTruth; // collect fanins in the Vec_PtrClear( p->vFanins ); Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) @@ -164,69 +131,22 @@ p->timeRes += clock() - clk; if ( GainBest == -1 ) return -1; -/* - if ( GainBest > 0 ) - { - printf( "Class %d ", p->pMap[uTruthBest] ); - printf( "Gain = %d. Node %d : ", GainBest, pNode->Id ); - Vec_PtrForEachEntry( p->vFanins, pFanin, i ) - printf( "%d ", Abc_ObjRegular(pFanin)->Id ); - Dec_GraphPrint( stdout, p->pGraph, NULL, NULL ); - printf( "\n" ); - } -*/ - -// printf( "%d", nNodesSaveCur - GainBest ); -/* - if ( GainBest > 0 ) - { - if ( Rwr_CutIsBoolean( pNode, p->vFanins ) ) - printf( "b" ); - else - { - printf( "Node %d : ", pNode->Id ); - Vec_PtrForEachEntry( p->vFanins, pFanin, i ) - printf( "%d ", Abc_ObjRegular(pFanin)->Id ); - printf( "a" ); - } - } -*/ -/* - if ( GainBest > 0 ) - if ( p->fCompl ) - printf( "c" ); - else - printf( "." ); -*/ // copy the leaves Vec_PtrForEachEntry( p->vFanins, pFanin, i ) Dec_GraphNode(p->pGraph, i)->pFunc = pFanin; -/* - printf( "(" ); - Vec_PtrForEachEntry( p->vFanins, pFanin, i ) - printf( " %d", Abc_ObjRegular(pFanin)->vFanouts.nSize - 1 ); - printf( " ) " ); -*/ -// printf( "%d ", Rwr_NodeGetDepth_rec( pNode, p->vFanins ) ); p->nScores[p->pMap[uTruthBest]]++; + p->nNodesRewritten++; p->nNodesGained += GainBest; - if ( fUseZeros || GainBest > 0 ) - { - p->nNodesRewritten++; - } // report the progress - if ( fVeryVerbose && GainBest > 0 ) + if ( fVeryVerbose ) { printf( "Node %6s : ", Abc_ObjName(pNode) ); printf( "Fanins = %d. ", p->vFanins->nSize ); - printf( "Save = %d. ", nNodesSaveCur ); - printf( "Add = %d. ", nNodesSaveCur-GainBest ); - printf( "GAIN = %d. ", GainBest ); - printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 ); - printf( "Class = %d. ", p->pMap[uTruthBest] ); + printf( "Cone = %2d. ", Dec_GraphNodeNum(p->pGraph) ); + printf( "GAIN = %2d. ", GainBest ); printf( "\n" ); } return GainBest; @@ -243,22 +163,17 @@ p->timeRes += clock() - clk; SeeAlso [] ***********************************************************************/ -Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, int fPlaceEnable ) +Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest ) { - extern int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ); Vec_Ptr_t * vSubgraphs; Dec_Graph_t * pGraphBest, * pGraphCur; Rwr_Node_t * pNode, * pFanin; int nNodesAdded, GainBest, i, k; - unsigned uTruth; - float CostBest;//, CostCur; // find the matching class of subgraphs - uTruth = 0xFFFF & *Cut_CutReadTruth(pCut); - vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] ); + vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[pCut->uTruth] ); p->nSubgraphs += vSubgraphs->nSize; // determine the best subgraph GainBest = -1; - CostBest = ABC_INFINITY; Vec_PtrForEachEntry( vSubgraphs, pNode, i ) { // get the current graph @@ -271,58 +186,11 @@ Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCu if ( nNodesAdded == -1 ) continue; assert( nNodesSaved >= nNodesAdded ); -/* - // evaluate the cut - if ( fPlaceEnable ) - { - extern float Abc_PlaceEvaluateCut( Abc_Obj_t * pRoot, Vec_Ptr_t * vFanins ); - - float Alpha = 0.5; // ??? - float PlaceCost; - - // get the placement cost of the cut - PlaceCost = Abc_PlaceEvaluateCut( pRoot, vFaninsCur ); - - // get the weigted cost of the cut - CostCur = nNodesSaved - nNodesAdded + Alpha * PlaceCost; - - // do not allow uphill moves - if ( nNodesSaved - nNodesAdded < 0 ) - continue; - - // decide what cut to use - if ( CostBest > CostCur ) - { - GainBest = nNodesSaved - nNodesAdded; // pure node cost - CostBest = CostCur; // cost with placement - pGraphBest = pGraphCur; // subgraph to be used for rewriting - - // score the graph - if ( nNodesSaved - nNodesAdded > 0 ) - { - pNode->nScore++; - pNode->nGain += GainBest; - pNode->nAdded += nNodesAdded; - } - } - } - else -*/ + // count the gain at this node + if ( GainBest < nNodesSaved - nNodesAdded ) { - // count the gain at this node - if ( GainBest < nNodesSaved - nNodesAdded ) - { - GainBest = nNodesSaved - nNodesAdded; - pGraphBest = pGraphCur; - - // score the graph - if ( nNodesSaved - nNodesAdded > 0 ) - { - pNode->nScore++; - pNode->nGain += GainBest; - pNode->nAdded += nNodesAdded; - } - } + GainBest = nNodesSaved - nNodesAdded; + pGraphBest = pGraphCur; } } if ( GainBest == -1 ) @@ -331,257 +199,6 @@ Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCu return pGraphBest; } -/**Function************************************************************* - - Synopsis [Checks the type of the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_CutIsBoolean_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves, int fMarkA ) -{ - if ( Vec_PtrFind(vLeaves, pObj) >= 0 || Vec_PtrFind(vLeaves, Abc_ObjNot(pObj)) >= 0 ) - { - if ( fMarkA ) - pObj->fMarkA = 1; - else - pObj->fMarkB = 1; - return; - } - assert( !Abc_ObjIsCi(pObj) ); - Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, fMarkA ); - Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, fMarkA ); -} - -/**Function************************************************************* - - Synopsis [Checks the type of the cut.] - - Description [Returns 1(0) if the cut is Boolean (algebraic).] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves ) -{ - Abc_Obj_t * pTemp; - int i, RetValue; - Vec_PtrForEachEntry( vLeaves, pTemp, i ) - { - pTemp = Abc_ObjRegular(pTemp); - assert( !pTemp->fMarkA && !pTemp->fMarkB ); - } - Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, 1 ); - Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, 0 ); - RetValue = 0; - Vec_PtrForEachEntry( vLeaves, pTemp, i ) - { - pTemp = Abc_ObjRegular(pTemp); - RetValue |= pTemp->fMarkA && pTemp->fMarkB; - pTemp->fMarkA = pTemp->fMarkB = 0; - } - return RetValue; -} - - -/**Function************************************************************* - - Synopsis [Count the nodes in the cut space of a node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_CutCountNumNodes_rec( Abc_Obj_t * pObj, Cut_Cut_t * pCut, Vec_Ptr_t * vNodes ) -{ - int i; - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - if ( pCut->pLeaves[i] == pObj->Id ) - { - // check if the node is collected - if ( pObj->fMarkC == 0 ) - { - pObj->fMarkC = 1; - Vec_PtrPush( vNodes, pObj ); - } - return; - } - assert( Abc_ObjIsNode(pObj) ); - // check if the node is collected - if ( pObj->fMarkC == 0 ) - { - pObj->fMarkC = 1; - Vec_PtrPush( vNodes, pObj ); - } - // traverse the fanins - Rwr_CutCountNumNodes_rec( Abc_ObjFanin0(pObj), pCut, vNodes ); - Rwr_CutCountNumNodes_rec( Abc_ObjFanin1(pObj), pCut, vNodes ); -} - -/**Function************************************************************* - - Synopsis [Count the nodes in the cut space of a node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut ) -{ - Vec_Ptr_t * vNodes; - int i, Counter; - // collect all nodes - vNodes = Vec_PtrAlloc( 100 ); - for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext ) - Rwr_CutCountNumNodes_rec( pObj, pCut, vNodes ); - // clean all nodes - Vec_PtrForEachEntry( vNodes, pObj, i ) - pObj->fMarkC = 0; - // delete and return - Counter = Vec_PtrSize(vNodes); - Vec_PtrFree( vNodes ); - return Counter; -} - - -/**Function************************************************************* - - Synopsis [Returns depth of the cut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves ) -{ - Abc_Obj_t * pLeaf; - int i, Depth0, Depth1; - if ( Abc_ObjIsCi(pObj) ) - return 0; - Vec_PtrForEachEntry( vLeaves, pLeaf, i ) - if ( pObj == Abc_ObjRegular(pLeaf) ) - return 0; - Depth0 = Rwr_NodeGetDepth_rec( Abc_ObjFanin0(pObj), vLeaves ); - Depth1 = Rwr_NodeGetDepth_rec( Abc_ObjFanin1(pObj), vLeaves ); - return 1 + ABC_MAX( Depth0, Depth1 ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ScoresClean( Rwr_Man_t * p ) -{ - Vec_Ptr_t * vSubgraphs; - Rwr_Node_t * pNode; - int i, k; - for ( i = 0; i < p->vClasses->nSize; i++ ) - { - vSubgraphs = Vec_VecEntry( p->vClasses, i ); - Vec_PtrForEachEntry( vSubgraphs, pNode, k ) - pNode->nScore = pNode->nGain = pNode->nAdded = 0; - } -} - -static int Gains[222]; - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rwr_ScoresCompare( int * pNum1, int * pNum2 ) -{ - if ( Gains[*pNum1] > Gains[*pNum2] ) - return -1; - if ( Gains[*pNum1] < Gains[*pNum2] ) - return 1; - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ScoresReport( Rwr_Man_t * p ) -{ - extern void Ivy_TruthDsdComputePrint( unsigned uTruth ); - int Perm[222]; - Vec_Ptr_t * vSubgraphs; - Rwr_Node_t * pNode; - int i, iNew, k; - unsigned uTruth; - // collect total gains - assert( p->vClasses->nSize == 222 ); - for ( i = 0; i < p->vClasses->nSize; i++ ) - { - Perm[i] = i; - Gains[i] = 0; - vSubgraphs = Vec_VecEntry( p->vClasses, i ); - Vec_PtrForEachEntry( vSubgraphs, pNode, k ) - Gains[i] += pNode->nGain; - } - // sort the gains - qsort( Perm, 222, sizeof(int), (int (*)(const void *, const void *))Rwr_ScoresCompare ); - - // print classes - for ( i = 0; i < p->vClasses->nSize; i++ ) - { - iNew = Perm[i]; - if ( Gains[iNew] == 0 ) - break; - vSubgraphs = Vec_VecEntry( p->vClasses, iNew ); - printf( "CLASS %3d: Subgr = %3d. Total gain = %6d. ", iNew, Vec_PtrSize(vSubgraphs), Gains[iNew] ); - uTruth = (unsigned)p->pMapInv[iNew]; - Extra_PrintBinary( stdout, &uTruth, 16 ); - printf( " " ); - Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[iNew] | ((unsigned)p->pMapInv[iNew] << 16) ); - Vec_PtrForEachEntry( vSubgraphs, pNode, k ) - { - if ( pNode->nScore == 0 ) - continue; - printf( " %2d: S=%5d. A=%5d. G=%6d. ", k, pNode->nScore, pNode->nAdded, pNode->nGain ); - Dec_GraphPrint( stdout, (Dec_Graph_t *)pNode->pNext, NULL, NULL ); - } - } -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/opt/rwr/rwrExp.c b/src/opt/rwr/rwrExp.c index 2d00bb1c..e93a2611 100644 --- a/src/opt/rwr/rwrExp.c +++ b/src/opt/rwr/rwrExp.c @@ -47,7 +47,7 @@ static Rwr_Man4_t * s_pManRwrExp4 = NULL; static Rwr_Man5_t * s_pManRwrExp5 = NULL; //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/rwr/rwrLib.c b/src/opt/rwr/rwrLib.c index 1cdf350e..fbcb8916 100644 --- a/src/opt/rwr/rwrLib.c +++ b/src/opt/rwr/rwrLib.c @@ -28,7 +28,7 @@ static Rwr_Node_t * Rwr_ManTryNode( Rwr_Man_t * p, Rwr_Node_t * p0, Rwr_N static void Rwr_MarkUsed_rec( Rwr_Man_t * p, Rwr_Node_t * pNode ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/rwr/rwrMan.c b/src/opt/rwr/rwrMan.c index 87a080c7..a21dd520 100644 --- a/src/opt/rwr/rwrMan.c +++ b/src/opt/rwr/rwrMan.c @@ -27,7 +27,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -50,7 +50,7 @@ clk = clock(); p = ALLOC( Rwr_Man_t, 1 ); memset( p, 0, sizeof(Rwr_Man_t) ); p->nFuncs = (1<<16); - pManDec = Abc_FrameReadManDec(); + pManDec = Abc_FrameReadManDec(Abc_FrameGetGlobalFrame()); p->puCanons = pManDec->puCanons; p->pPhases = pManDec->pPhases; p->pPerms = pManDec->pPerms; @@ -75,7 +75,6 @@ clk = clock(); p->vLevNums = Vec_IntAlloc( 50 ); p->vFanins = Vec_PtrAlloc( 50 ); p->vFaninsCur = Vec_PtrAlloc( 50 ); - p->vNodesTemp = Vec_PtrAlloc( 50 ); if ( fPrecompute ) { // precompute subgraphs Rwr_ManPrecompute( p ); @@ -113,13 +112,11 @@ void Rwr_ManStop( Rwr_Man_t * p ) Dec_GraphFree( (Dec_Graph_t *)pNode->pNext ); } if ( p->vClasses ) Vec_VecFree( p->vClasses ); - Vec_PtrFree( p->vNodesTemp ); Vec_PtrFree( p->vForest ); Vec_IntFree( p->vLevNums ); Vec_PtrFree( p->vFanins ); Vec_PtrFree( p->vFaninsCur ); - Extra_MmFixedStop( p->pMmNode ); - FREE( p->pMapInv ); + Extra_MmFixedStop( p->pMmNode, 0 ); free( p->pTable ); free( p->pPractical ); free( p->pPerms4 ); @@ -150,50 +147,20 @@ void Rwr_ManPrintStats( Rwr_Man_t * p ) printf( "Used NPN classes = %8d.\n", Counter ); printf( "Nodes considered = %8d.\n", p->nNodesConsidered ); printf( "Nodes rewritten = %8d.\n", p->nNodesRewritten ); - printf( "Gain = %8d. (%6.2f %%).\n", p->nNodesBeg-p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/p->nNodesBeg ); + printf( "Calculated gain = %8d.\n", p->nNodesGained ); PRT( "Start ", p->timeStart ); PRT( "Cuts ", p->timeCut ); PRT( "Resynthesis ", p->timeRes ); - PRT( " Mffc ", p->timeMffc ); PRT( " Eval ", p->timeEval ); - PRT( "Update ", p->timeUpdate ); PRT( "TOTAL ", p->timeTotal ); /* - printf( "The scores are:\n" ); + printf( "The scores are : " ); for ( i = 0; i < 222; i++ ) if ( p->nScores[i] > 0 ) - { - extern void Ivy_TruthDsdComputePrint( unsigned uTruth ); - printf( "%3d = %8d canon = %5d ", i, p->nScores[i], p->pMapInv[i] ); - Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[i] | ((unsigned)p->pMapInv[i] << 16) ); - } -*/ + printf( "%d=%d ", i, p->nScores[i] ); printf( "\n" ); - -} - -/**Function************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManPrintStatsFile( Rwr_Man_t * p ) -{ - FILE * pTable; - pTable = fopen( "stats.txt", "a+" ); - fprintf( pTable, "%d ", p->nCutsGood ); - fprintf( pTable, "%d ", p->nSubgraphs ); - fprintf( pTable, "%d ", p->nNodesRewritten ); - fprintf( pTable, "%d", p->nNodesGained ); - fprintf( pTable, "\n" ); - fclose( pTable ); +*/ } /**Function************************************************************* @@ -223,22 +190,6 @@ void * Rwr_ManReadDecs( Rwr_Man_t * p ) SeeAlso [] ***********************************************************************/ -Vec_Ptr_t * Rwr_ManReadLeaves( Rwr_Man_t * p ) -{ - return p->vFanins; -} - -/**Function************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ int Rwr_ManReadCompl( Rwr_Man_t * p ) { return p->fCompl; @@ -271,22 +222,6 @@ void Rwr_ManAddTimeCuts( Rwr_Man_t * p, int Time ) SeeAlso [] ***********************************************************************/ -void Rwr_ManAddTimeUpdate( Rwr_Man_t * p, int Time ) -{ - p->timeUpdate += Time; -} - -/**Function************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ void Rwr_ManAddTimeTotal( Rwr_Man_t * p, int Time ) { p->timeTotal += Time; diff --git a/src/opt/rwr/rwrPrint.c b/src/opt/rwr/rwrPrint.c index 82ad2a90..30c99f00 100644 --- a/src/opt/rwr/rwrPrint.c +++ b/src/opt/rwr/rwrPrint.c @@ -25,7 +25,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -79,33 +79,6 @@ void Rwr_GetBushVolume( Rwr_Man_t * p, int Entry, int * pVolume, int * pnFuncs ) /**Function************************************************************* - Synopsis [Adds the node to the end of the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rwr_GetBushSumOfVolumes( Rwr_Man_t * p, int Entry ) -{ - Rwr_Node_t * pNode; - int Volume, VolumeTotal = 0; - for ( pNode = p->pTable[Entry]; pNode; pNode = pNode->pNext ) - { - if ( pNode->uTruth != p->puCanons[pNode->uTruth] ) - continue; - Volume = 0; - Rwr_ManIncTravId( p ); - Rwr_Trav2_rec( p, pNode, &Volume ); - VolumeTotal += Volume; - } - return VolumeTotal; -} - -/**Function************************************************************* - Synopsis [Prints one rwr node.] Description [] @@ -246,9 +219,9 @@ void Rwr_ManPrint( Rwr_Man_t * p ) continue; if ( i != p->puCanons[i] ) continue; - fprintf( pFile, "\nClass %3d. Func %6d. ", p->pMap[i], Counter++ ); + fprintf( pFile, "\nClass %3d. Func %6d. ", p->pMap[i], Counter++ ); Rwr_GetBushVolume( p, i, &Volume, &nFuncs ); - fprintf( pFile, "Roots = %3d. Vol = %3d. Sum = %3d. ", nFuncs, Volume, Rwr_GetBushSumOfVolumes(p, i) ); + fprintf( pFile, "Functions = %2d. Volume = %2d. ", nFuncs, Volume ); uTruth = i; Extra_PrintBinary( pFile, &uTruth, 16 ); fprintf( pFile, "\n" ); diff --git a/src/opt/rwr/rwrTemp.c b/src/opt/rwr/rwrTemp.c deleted file mode 100644 index 3ffbd408..00000000 --- a/src/opt/rwr/rwrTemp.c +++ /dev/null @@ -1,121 +0,0 @@ -/**CFile**************************************************************** - - FileName [rwrCut.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [DAG-aware AIG rewriting package.] - - Synopsis [Cut computation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: rwrCut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "rwr.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int pTruths[13719]; -static int pFreqs[13719]; -static int pPerm[13719]; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rwr_TempCompare( int * pNum1, int * pNum2 ) -{ - int Freq1 = pFreqs[*pNum1]; - int Freq2 = pFreqs[*pNum2]; - if ( Freq1 < Freq2 ) - return 1; - if ( Freq1 > Freq2 ) - return -1; - return 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_Temp() -{ - char Buffer[32]; - int nFuncs = 13719; - int nEntries = 100; - unsigned uTruth; - int i, k; - FILE * pFile; - - pFile = fopen( "nnclass_stats5.txt", "r" ); - for ( i = 0; i < 13719; i++ ) - { - fscanf( pFile, "%s%d", Buffer, &pFreqs[i] ); - Extra_ReadHexadecimal( &uTruth, Buffer+2, 5 ); - pTruths[i] = uTruth; - } - fclose( pFile ); - - for ( i = 0; i < 13719; i++ ) - pPerm[i] = i; - - qsort( (void *)pPerm, 13719, sizeof(int), - (int (*)(const void *, const void *)) Rwr_TempCompare ); - - - pFile = fopen( "5npn_100.blif", "w" ); - fprintf( pFile, "# Most frequent NPN classes of 5 vars.\n" ); - fprintf( pFile, ".model 5npn\n" ); - fprintf( pFile, ".inputs a b c d e\n" ); - fprintf( pFile, ".outputs" ); - for ( i = 0; i < nEntries; i++ ) - fprintf( pFile, " %02d", i ); - fprintf( pFile, "\n" ); - - for ( i = 0; i < nEntries; i++ ) - { - fprintf( pFile, ".names a b c d e %02d\n", i ); - uTruth = pTruths[pPerm[i]]; - for ( k = 0; k < 32; k++ ) - if ( uTruth & (1 << k) ) - { - Extra_PrintBinary( pFile, &k, 5 ); - fprintf( pFile, " 1\n" ); - } - } - fprintf( pFile, ".end\n" ); - fclose( pFile ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/rwr/rwrUtil.c b/src/opt/rwr/rwrUtil.c index b2add2bf..65b2bd6f 100644 --- a/src/opt/rwr/rwrUtil.c +++ b/src/opt/rwr/rwrUtil.c @@ -34,7 +34,7 @@ static unsigned short s_RwtAigSubgraphs[]; #endif //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/sim/module.make b/src/opt/sim/module.make index 54058402..43d0a125 100644 --- a/src/opt/sim/module.make +++ b/src/opt/sim/module.make @@ -1,6 +1,5 @@ SRC += src/opt/sim/simMan.c \ src/opt/sim/simSat.c \ - src/opt/sim/simSeq.c \ src/opt/sim/simSupp.c \ src/opt/sim/simSwitch.c \ src/opt/sim/simSym.c \ diff --git a/src/opt/sim/sim.h b/src/opt/sim/sim.h index 7fcf5ae6..afed7190 100644 --- a/src/opt/sim/sim.h +++ b/src/opt/sim/sim.h @@ -17,14 +17,10 @@ Revision [$Id: sim.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ - + #ifndef __SIM_H__ #define __SIM_H__ -#ifdef __cplusplus -extern "C" { -#endif - /* The ideas realized in this package are described in the paper: "Detecting Symmetries in Boolean Functions using Circuit Representation, @@ -102,7 +98,6 @@ struct Sim_Man_t_ Abc_Ntk_t * pNtk; int nInputs; int nOutputs; - int fLightweight; // internal simulation information int nSimBits; // the number of bits in simulation info int nSimWords; // the number of words in simulation info @@ -140,11 +135,11 @@ struct Sim_Pat_t_ }; //////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// +/// MACRO DEFITIONS /// //////////////////////////////////////////////////////////////////////// -#define SIM_NUM_WORDS(n) (((n)>>5) + (((n)&31) > 0)) -#define SIM_LAST_BITS(n) ((((n)&31) > 0)? (n)&31 : 32) +#define SIM_NUM_WORDS(n) ((n)/32 + (((n)%32) > 0)) +#define SIM_LAST_BITS(n) ((((n)%32) > 0)? (n)%32 : 32) #define SIM_MASK_FULL (0xFFFFFFFF) #define SIM_MASK_BEG(n) (SIM_MASK_FULL >> (32-n)) @@ -167,7 +162,6 @@ struct Sim_Pat_t_ #define Sim_SuppFunHasVar(vSupps,Output,v) Sim_HasBit((unsigned*)(vSupps)->pArray[Output],(v)) #define Sim_SimInfoSetVar(vSupps,pNode,v) Sim_SetBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v)) #define Sim_SimInfoHasVar(vSupps,pNode,v) Sim_HasBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v)) -#define Sim_SimInfoGet(vInfo,pNode) ((unsigned *)((vInfo)->pArray[(pNode)->Id])) //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// @@ -177,14 +171,11 @@ struct Sim_Pat_t_ extern Sym_Man_t * Sym_ManStart( Abc_Ntk_t * pNtk, int fVerbose ); extern void Sym_ManStop( Sym_Man_t * p ); extern void Sym_ManPrintStats( Sym_Man_t * p ); -extern Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk, int fLightweight ); +extern Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk ); extern void Sim_ManStop( Sim_Man_t * p ); extern void Sim_ManPrintStats( Sim_Man_t * p ); extern Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p ); extern void Sim_ManPatFree( Sim_Man_t * p, Sim_Pat_t * pPat ); -/*=== simSeq.c ==========================================================*/ -extern Vec_Ptr_t * Sim_SimulateSeqRandom( Abc_Ntk_t * pNtk, int nFrames, int nWords ); -extern Vec_Ptr_t * Sim_SimulateSeqModel( Abc_Ntk_t * pNtk, int nFrames, int * pModel ); /*=== simSupp.c ==========================================================*/ extern Vec_Ptr_t * Sim_ComputeStrSupp( Abc_Ntk_t * pNtk ); extern Vec_Ptr_t * Sim_ComputeFunSupp( Abc_Ntk_t * pNtk, int fVerbose ); @@ -206,28 +197,17 @@ extern void Sim_UtilInfoFlip( Sim_Man_t * p, Abc_Obj_t * pNode ); extern bool Sim_UtilInfoCompare( Sim_Man_t * p, Abc_Obj_t * pNode ); extern void Sim_UtilSimulate( Sim_Man_t * p, bool fFirst ); extern void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fType1, bool fType2 ); -extern void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords, int nOffset ); -extern void Sim_UtilTransferNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords, int nOffset, int fShift ); +extern void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ); extern int Sim_UtilCountSuppSizes( Sim_Man_t * p, int fStruct ); extern int Sim_UtilCountOnes( unsigned * pSimInfo, int nSimWords ); -extern Vec_Int_t * Sim_UtilCountOnesArray( Vec_Ptr_t * vInfo, int nSimWords ); -extern void Sim_UtilSetRandom( unsigned * pPatRand, int nSimWords ); -extern void Sim_UtilSetCompl( unsigned * pPatRand, int nSimWords ); -extern void Sim_UtilSetConst( unsigned * pPatRand, int nSimWords, int fConst1 ); -extern int Sim_UtilInfoIsEqual( unsigned * pPats1, unsigned * pPats2, int nSimWords ); -extern int Sim_UtilInfoIsImp( unsigned * pPats1, unsigned * pPats2, int nSimWords ); -extern int Sim_UtilInfoIsClause( unsigned * pPats1, unsigned * pPats2, int nSimWords ); +extern void Sim_UtilGetRandom( unsigned * pPatRand, int nSimWords ); extern int Sim_UtilCountAllPairs( Vec_Ptr_t * vSuppFun, int nSimWords, Vec_Int_t * vCounters ); extern void Sim_UtilCountPairsAll( Sym_Man_t * p ); extern int Sim_UtilMatrsAreDisjoint( Sym_Man_t * p ); -#ifdef __cplusplus -} -#endif - -#endif - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// +#endif + diff --git a/src/opt/sim/simMan.c b/src/opt/sim/simMan.c index 3b50ad84..780ecfd8 100644 --- a/src/opt/sim/simMan.c +++ b/src/opt/sim/simMan.c @@ -26,12 +26,12 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Starts the simulation manager.] + Synopsis [Starts the simulatin manager.] Description [] @@ -83,7 +83,7 @@ Sym_Man_t * Sym_ManStart( Abc_Ntk_t * pNtk, int fVerbose ) /**Function************************************************************* - Synopsis [Stops the simulation manager.] + Synopsis [Stops the simulatin manager.] Description [] @@ -149,9 +149,11 @@ void Sym_ManPrintStats( Sym_Man_t * p ) } + + /**Function************************************************************* - Synopsis [Starts the simulation manager.] + Synopsis [Starts the simulatin manager.] Description [] @@ -160,7 +162,7 @@ void Sym_ManPrintStats( Sym_Man_t * p ) SeeAlso [] ***********************************************************************/ -Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk, int fLightweight ) +Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk ) { Sim_Man_t * p; // start the manager @@ -173,27 +175,24 @@ Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk, int fLightweight ) p->nSimBits = 2048; p->nSimWords = SIM_NUM_WORDS(p->nSimBits); p->vSim0 = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 ); - p->fLightweight = fLightweight; - if (!p->fLightweight) { - p->vSim1 = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 ); - // support information - p->nSuppBits = Abc_NtkCiNum(pNtk); - p->nSuppWords = SIM_NUM_WORDS(p->nSuppBits); - p->vSuppStr = Sim_ComputeStrSupp( pNtk ); - p->vSuppFun = Sim_UtilInfoAlloc( Abc_NtkCoNum(p->pNtk), p->nSuppWords, 1 ); - // other data - p->pMmPat = Extra_MmFixedStart( sizeof(Sim_Pat_t) + p->nSuppWords * sizeof(unsigned) ); - p->vFifo = Vec_PtrAlloc( 100 ); - p->vDiffs = Vec_IntAlloc( 100 ); - // allocate support targets (array of unresolved outputs for each input) - p->vSuppTargs = Vec_VecStart( p->nInputs ); - } + p->vSim1 = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 ); + // support information + p->nSuppBits = Abc_NtkCiNum(pNtk); + p->nSuppWords = SIM_NUM_WORDS(p->nSuppBits); + p->vSuppStr = Sim_ComputeStrSupp( pNtk ); + p->vSuppFun = Sim_UtilInfoAlloc( Abc_NtkCoNum(p->pNtk), p->nSuppWords, 1 ); + // other data + p->pMmPat = Extra_MmFixedStart( sizeof(Sim_Pat_t) + p->nSuppWords * sizeof(unsigned) ); + p->vFifo = Vec_PtrAlloc( 100 ); + p->vDiffs = Vec_IntAlloc( 100 ); + // allocate support targets (array of unresolved outputs for each input) + p->vSuppTargs = Vec_VecStart( p->nInputs ); return p; } /**Function************************************************************* - Synopsis [Stops the simulation manager.] + Synopsis [Stops the simulatin manager.] Description [] @@ -210,7 +209,7 @@ void Sim_ManStop( Sim_Man_t * p ) if ( p->vSuppStr ) Sim_UtilInfoFree( p->vSuppStr ); // if ( p->vSuppFun ) Sim_UtilInfoFree( p->vSuppFun ); if ( p->vSuppTargs ) Vec_VecFree( p->vSuppTargs ); - if ( p->pMmPat ) Extra_MmFixedStop( p->pMmPat ); + if ( p->pMmPat ) Extra_MmFixedStop( p->pMmPat, 0 ); if ( p->vFifo ) Vec_PtrFree( p->vFifo ); if ( p->vDiffs ) Vec_IntFree( p->vDiffs ); free( p ); diff --git a/src/opt/sim/simSat.c b/src/opt/sim/simSat.c index d514f7f2..b4e080fe 100644 --- a/src/opt/sim/simSat.c +++ b/src/opt/sim/simSat.c @@ -26,7 +26,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* diff --git a/src/opt/sim/simSeq.c b/src/opt/sim/simSeq.c deleted file mode 100644 index 49fb939f..00000000 --- a/src/opt/sim/simSeq.c +++ /dev/null @@ -1,171 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSeq.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation for sequential circuits.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simUtils.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Sim_SimulateSeqFrame( Vec_Ptr_t * vInfo, Abc_Ntk_t * pNtk, int iFrames, int nWords, int fTransfer ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Simulates sequential circuit.] - - Description [Takes sequential circuit (pNtk). Simulates the given number - (nFrames) of the circuit with the given number of machine words (nWords) - of random simulation data, starting from the initial state. If the initial - state of some latches is a don't-care, uses random input for that latch.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Sim_SimulateSeqRandom( Abc_Ntk_t * pNtk, int nFrames, int nWords ) -{ - Vec_Ptr_t * vInfo; - Abc_Obj_t * pNode; - int i; - assert( Abc_NtkIsStrash(pNtk) ); - vInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nWords * nFrames, 0 ); - // set the constant data - pNode = Abc_AigConst1(pNtk); - Sim_UtilSetConst( Sim_SimInfoGet(vInfo,pNode), nWords * nFrames, 1 ); - // set the random PI data - Abc_NtkForEachPi( pNtk, pNode, i ) - Sim_UtilSetRandom( Sim_SimInfoGet(vInfo,pNode), nWords * nFrames ); - // set the initial state data - Abc_NtkForEachLatch( pNtk, pNode, i ) - if ( Abc_LatchIsInit0(pNode) ) - Sim_UtilSetConst( Sim_SimInfoGet(vInfo,pNode), nWords, 0 ); - else if ( Abc_LatchIsInit1(pNode) ) - Sim_UtilSetConst( Sim_SimInfoGet(vInfo,pNode), nWords, 1 ); - else - Sim_UtilSetRandom( Sim_SimInfoGet(vInfo,pNode), nWords ); - // simulate the nodes for the given number of timeframes - for ( i = 0; i < nFrames; i++ ) - Sim_SimulateSeqFrame( vInfo, pNtk, i, nWords, (int)(i < nFrames-1) ); - return vInfo; -} - -/**Function************************************************************* - - Synopsis [Simulates sequential circuit.] - - Description [Takes sequential circuit (pNtk). Simulates the given number - (nFrames) of the circuit with the given model. The model is assumed to - contain values of PIs for each frame. The latches are initialized to - the initial state. One word of data is simulated.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Sim_SimulateSeqModel( Abc_Ntk_t * pNtk, int nFrames, int * pModel ) -{ - Vec_Ptr_t * vInfo; - Abc_Obj_t * pNode; - unsigned * pUnsigned; - int i, k; - vInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nFrames, 0 ); - // set the constant data - pNode = Abc_AigConst1(pNtk); - Sim_UtilSetConst( Sim_SimInfoGet(vInfo,pNode), nFrames, 1 ); - // set the random PI data - Abc_NtkForEachPi( pNtk, pNode, i ) - { - pUnsigned = Sim_SimInfoGet(vInfo,pNode); - for ( k = 0; k < nFrames; k++ ) - pUnsigned[k] = pModel[k * Abc_NtkPiNum(pNtk) + i] ? ~((unsigned)0) : 0; - } - // set the initial state data - Abc_NtkForEachLatch( pNtk, pNode, i ) - { - pUnsigned = Sim_SimInfoGet(vInfo,pNode); - if ( Abc_LatchIsInit0(pNode) ) - pUnsigned[0] = 0; - else if ( Abc_LatchIsInit1(pNode) ) - pUnsigned[0] = ~((unsigned)0); - else - pUnsigned[0] = SIM_RANDOM_UNSIGNED; - } - // simulate the nodes for the given number of timeframes - for ( i = 0; i < nFrames; i++ ) - Sim_SimulateSeqFrame( vInfo, pNtk, i, 1, (int)(i < nFrames-1) ); -/* - // print the simulated values - for ( i = 0; i < nFrames; i++ ) - { - printf( "Frame %d : ", i+1 ); - Abc_NtkForEachPi( pNtk, pNode, k ) - printf( "%d", Sim_SimInfoGet(vInfo,pNode)[i] > 0 ); - printf( " " ); - Abc_NtkForEachLatch( pNtk, pNode, k ) - printf( "%d", Sim_SimInfoGet(vInfo,pNode)[i] > 0 ); - printf( " " ); - Abc_NtkForEachPo( pNtk, pNode, k ) - printf( "%d", Sim_SimInfoGet(vInfo,pNode)[i] > 0 ); - printf( "\n" ); - } - printf( "\n" ); -*/ - return vInfo; -} - -/**Function************************************************************* - - Synopsis [Simulates one frame of sequential circuit.] - - Description [Assumes that the latches and POs are already initialized. - In the end transfers the data to the latches of the next frame.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SimulateSeqFrame( Vec_Ptr_t * vInfo, Abc_Ntk_t * pNtk, int iFrames, int nWords, int fTransfer ) -{ - Abc_Obj_t * pNode; - int i; - Abc_NtkForEachNode( pNtk, pNode, i ) - Sim_UtilSimulateNodeOne( pNode, vInfo, nWords, iFrames * nWords ); - Abc_NtkForEachPo( pNtk, pNode, i ) - Sim_UtilTransferNodeOne( pNode, vInfo, nWords, iFrames * nWords, 0 ); - if ( !fTransfer ) - return; - Abc_NtkForEachLatch( pNtk, pNode, i ) - Sim_UtilTransferNodeOne( pNode, vInfo, nWords, iFrames * nWords, 1 ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/sim/simSupp.c b/src/opt/sim/simSupp.c index f7048f4a..576e19cc 100644 --- a/src/opt/sim/simSupp.c +++ b/src/opt/sim/simSupp.c @@ -35,8 +35,10 @@ static void Sim_UtilAssignFromFifo( Sim_Man_t * p ); static void Sim_SolveTargetsUsingSat( Sim_Man_t * p, int nCounters ); static int Sim_SolveSuppModelVerify( Abc_Ntk_t * pNtk, int * pModel, int Input, int Output ); +extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes ); + //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -66,8 +68,8 @@ Vec_Ptr_t * Sim_ComputeStrSupp( Abc_Ntk_t * pNtk ) // derive the structural supports of the internal nodes Abc_NtkForEachNode( pNtk, pNode, i ) { -// if ( Abc_NodeIsConst(pNode) ) -// continue; + if ( Abc_NodeIsConst(pNode) ) + continue; pSimmNode = vSuppStr->pArray[ pNode->Id ]; pSimmNode1 = vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ]; pSimmNode2 = vSuppStr->pArray[ Abc_ObjFaninId1(pNode) ]; @@ -106,7 +108,7 @@ Vec_Ptr_t * Sim_ComputeFunSupp( Abc_Ntk_t * pNtk, int fVerbose ) srand( 0xABC ); // start the simulation manager - p = Sim_ManStart( pNtk, 0 ); + p = Sim_ManStart( pNtk ); // compute functional support using one round of random simulation Sim_UtilAssignRandom( p ); @@ -467,10 +469,9 @@ void Sim_SolveTargetsUsingSat( Sim_Man_t * p, int Limit ) // transform the miter into a fraig Fraig_ParamsSetDefault( &Params ); - Params.nSeconds = ABC_INFINITY; Params.fInternal = 1; clk = clock(); - pMan = Abc_NtkToFraig( pMiter, &Params, 0, 0 ); + pMan = Abc_NtkToFraig( pMiter, &Params, 0 ); p->timeFraig += clock() - clk; clk = clock(); Fraig_ManProveMiter( pMan ); @@ -586,6 +587,10 @@ int Sim_SolveSuppModelVerify( Abc_Ntk_t * pNtk, int * pModel, int Input, int Out } // perform the traversal RetValue = 3 & Sim_NtkSimTwoPats_rec( Abc_ObjFanin0( Abc_NtkCo(pNtk,Output) ) ); + if ( RetValue == 0 || RetValue == 3 ) + { + int x = 0; + } // assert( RetValue == 1 || RetValue == 2 ); return RetValue == 1 || RetValue == 2; } diff --git a/src/opt/sim/simSwitch.c b/src/opt/sim/simSwitch.c index 218d4d59..b43597f3 100644 --- a/src/opt/sim/simSwitch.c +++ b/src/opt/sim/simSwitch.c @@ -29,7 +29,7 @@ static void Sim_NodeSimulate( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimW static float Sim_ComputeSwitching( unsigned * pSimInfo, int nSimWords ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -65,7 +65,7 @@ Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns ) Abc_NtkForEachCi( pNtk, pNode, i ) { pSimInfo = Vec_PtrEntry(vSimInfo, pNode->Id); - Sim_UtilSetRandom( pSimInfo, nSimWords ); + Sim_UtilGetRandom( pSimInfo, nSimWords ); pSwitching[pNode->Id] = Sim_ComputeSwitching( pSimInfo, nSimWords ); } // simulate the internal nodes @@ -73,7 +73,7 @@ Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns ) Vec_PtrForEachEntry( vNodes, pNode, i ) { pSimInfo = Vec_PtrEntry(vSimInfo, pNode->Id); - Sim_UtilSimulateNodeOne( pNode, vSimInfo, nSimWords, 0 ); + Sim_UtilSimulateNodeOne( pNode, vSimInfo, nSimWords ); pSwitching[pNode->Id] = Sim_ComputeSwitching( pSimInfo, nSimWords ); } Vec_PtrFree( vNodes ); diff --git a/src/opt/sim/simSym.c b/src/opt/sim/simSym.c index 71de5b05..c452bb1b 100644 --- a/src/opt/sim/simSym.c +++ b/src/opt/sim/simSym.c @@ -26,7 +26,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -71,7 +71,7 @@ p->timeStruct = clock() - clk; for ( i = 1; i <= 1000; i++ ) { // simulate this pattern - Sim_UtilSetRandom( p->uPatRand, p->nSimWords ); + Sim_UtilGetRandom( p->uPatRand, p->nSimWords ); Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms ); if ( i % 50 != 0 ) continue; @@ -125,7 +125,6 @@ p->timeStruct = clock() - clk; if ( fVerbose ) printf( "Total = %8d. Sym = %8d. NonSym = %8d. Remaining = %8d.\n", p->nPairsTotal, p->nPairsSymm, p->nPairsNonSymm, p->nPairsRem ); -// Sim_UtilCountPairsAllPrint( p ); Result = p->nPairsSymm; vResult = p->vMatrSymms; diff --git a/src/opt/sim/simSymSat.c b/src/opt/sim/simSymSat.c index 7690a891..db9917b3 100644 --- a/src/opt/sim/simSymSat.c +++ b/src/opt/sim/simSymSat.c @@ -26,10 +26,11 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * pPattern ); +extern int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * pPattern ); +extern Fraig_Man_t * Abc_NtkToFraig( Abc_Ntk_t * pNtk, Fraig_Params_t * pParams, int fAllNodes ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -144,10 +145,9 @@ int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * Params.fInternal = 1; Params.nPatsRand = 512; Params.nPatsDyna = 512; - Params.nSeconds = ABC_INFINITY; clk = clock(); - pMan = Abc_NtkToFraig( pMiter, &Params, 0, 0 ); + pMan = Abc_NtkToFraig( pMiter, &Params, 0 ); p->timeFraig += clock() - clk; clk = clock(); Fraig_ManProveMiter( pMan ); diff --git a/src/opt/sim/simSymSim.c b/src/opt/sim/simSymSim.c index 2282825b..94028c47 100644 --- a/src/opt/sim/simSymSim.c +++ b/src/opt/sim/simSymSim.c @@ -29,7 +29,7 @@ static void Sim_SymmsCreateSquare( Sym_Man_t * p, unsigned * pPat ); static void Sim_SymmsDeriveInfo( Sym_Man_t * p, unsigned * pPat, Abc_Obj_t * pNode, Vec_Ptr_t * vMatrsNonSym, int Output ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -55,9 +55,9 @@ void Sim_SymmsSimulate( Sym_Man_t * p, unsigned * pPat, Vec_Ptr_t * vMatrsNonSym clk = clock(); Vec_PtrForEachEntry( p->vNodes, pNode, i ) { -// if ( Abc_NodeIsConst(pNode) ) -// continue; - Sim_UtilSimulateNodeOne( pNode, p->vSim, p->nSimWords, 0 ); + if ( Abc_NodeIsConst(pNode) ) + continue; + Sim_UtilSimulateNodeOne( pNode, p->vSim, p->nSimWords ); } p->timeSim += clock() - clk; // collect info into the CO matrices @@ -65,8 +65,8 @@ clk = clock(); Abc_NtkForEachCo( p->pNtk, pNode, i ) { pNode = Abc_ObjFanin0(pNode); -// if ( Abc_ObjIsCi(pNode) || Abc_AigNodeIsConst(pNode) ) -// continue; + if ( Abc_ObjIsCi(pNode) || Abc_NodeIsConst(pNode) ) + continue; nPairsTotal = Vec_IntEntry(p->vPairsTotal, i); nPairsSym = Vec_IntEntry(p->vPairsSym, i); nPairsNonSym = Vec_IntEntry(p->vPairsNonSym,i); diff --git a/src/opt/sim/simSymStr.c b/src/opt/sim/simSymStr.c index d52c4328..ed7e93bf 100644 --- a/src/opt/sim/simSymStr.c +++ b/src/opt/sim/simSymStr.c @@ -41,7 +41,7 @@ static void Sim_SymmsTransferToMatrix( Extra_BitMat_t * pMatSymm, Vec_Int_t * v static int * Sim_SymmsCreateMap( Abc_Ntk_t * pNtk ); //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -74,16 +74,15 @@ void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * v vNodes = Abc_NtkDfs( pNtk, 0 ); Vec_PtrForEachEntry( vNodes, pTemp, i ) { -// if ( Abc_NodeIsConst(pTemp) ) -// continue; + if ( Abc_NodeIsConst(pTemp) ) + continue; Sim_SymmsStructComputeOne( pNtk, pTemp, pMap ); } // collect the results for the COs; Abc_NtkForEachCo( pNtk, pTemp, i ) { -//printf( "Output %d:\n", i ); pTemp = Abc_ObjFanin0(pTemp); - if ( Abc_ObjIsCi(pTemp) || Abc_AigNodeIsConst(pTemp) ) + if ( Abc_ObjIsCi(pTemp) || Abc_NodeIsConst(pTemp) ) continue; Sim_SymmsTransferToMatrix( Vec_PtrEntry(vMatrs, i), SIM_READ_SYMMS(pTemp), Vec_PtrEntry(vSuppFun, i) ); } @@ -93,7 +92,7 @@ void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * v Abc_NtkForEachCi( pNtk, pTemp, i ) Vec_IntFree( SIM_READ_SYMMS(pTemp) ); Vec_PtrForEachEntry( vNodes, pTemp, i ) -// if ( !Abc_NodeIsConst(pTemp) ) + if ( !Abc_NodeIsConst(pTemp) ) Vec_IntFree( SIM_READ_SYMMS(pTemp) ); Vec_PtrFree( vNodes ); free( pMap ); @@ -445,7 +444,6 @@ void Sim_SymmsTransferToMatrix( Extra_BitMat_t * pMatSymm, Vec_Int_t * vSymms, u uSymm = (unsigned)vSymms->pArray[i]; Ind1 = (uSymm & 0xffff); Ind2 = (uSymm >> 16); -//printf( "%d,%d ", Ind1, Ind2 ); // skip variables that are not in the true support assert( Sim_HasBit(pSupport, Ind1) == Sim_HasBit(pSupport, Ind2) ); if ( !Sim_HasBit(pSupport, Ind1) || !Sim_HasBit(pSupport, Ind2) ) diff --git a/src/opt/sim/simUtils.c b/src/opt/sim/simUtils.c index b0660001..4b89c650 100644 --- a/src/opt/sim/simUtils.c +++ b/src/opt/sim/simUtils.c @@ -37,7 +37,7 @@ static int bit_count[256] = { }; //////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// +/// FUNCTION DEFITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* @@ -232,6 +232,9 @@ void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fT // simulate the internal nodes if ( Abc_ObjIsNode(pNode) ) { + if ( Abc_NodeIsConst(pNode) ) + return; + if ( fType ) pSimmNode = p->vSim1->pArray[ pNode->Id ]; else @@ -296,18 +299,17 @@ void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fT SeeAlso [] ***********************************************************************/ -void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords, int nOffset ) +void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ) { unsigned * pSimmNode, * pSimmNode1, * pSimmNode2; int k, fComp1, fComp2; // simulate the internal nodes assert( Abc_ObjIsNode(pNode) ); + if ( Abc_NodeIsConst(pNode) ) + return; pSimmNode = Vec_PtrEntry(vSimInfo, pNode->Id); pSimmNode1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode)); pSimmNode2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode)); - pSimmNode += nOffset; - pSimmNode1 += nOffset; - pSimmNode2 += nOffset; fComp1 = Abc_ObjFaninC0(pNode); fComp2 = Abc_ObjFaninC1(pNode); if ( fComp1 && fComp2 ) @@ -326,36 +328,6 @@ void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimW /**Function************************************************************* - Synopsis [Simulates one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilTransferNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords, int nOffset, int fShift ) -{ - unsigned * pSimmNode, * pSimmNode1; - int k, fComp1; - // simulate the internal nodes - assert( Abc_ObjIsCo(pNode) ); - pSimmNode = Vec_PtrEntry(vSimInfo, pNode->Id); - pSimmNode1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode)); - pSimmNode += nOffset + (fShift > 0)*nSimWords; - pSimmNode1 += nOffset; - fComp1 = Abc_ObjFaninC0(pNode); - if ( fComp1 ) - for ( k = 0; k < nSimWords; k++ ) - pSimmNode[k] = ~pSimmNode1[k]; - else - for ( k = 0; k < nSimWords; k++ ) - pSimmNode[k] = pSimmNode1[k]; -} - -/**Function************************************************************* - Synopsis [Returns 1 if the simulation infos are equal.] Description [] @@ -408,31 +380,10 @@ int Sim_UtilCountOnes( unsigned * pSimInfo, int nSimWords ) return nOnes; } -/**Function************************************************************* - - Synopsis [Counts the number of 1's in the bitstring.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Sim_UtilCountOnesArray( Vec_Ptr_t * vInfo, int nSimWords ) -{ - Vec_Int_t * vCounters; - unsigned * pSimInfo; - int i; - vCounters = Vec_IntStart( Vec_PtrSize(vInfo) ); - Vec_PtrForEachEntry( vInfo, pSimInfo, i ) - Vec_IntWriteEntry( vCounters, i, Sim_UtilCountOnes(pSimInfo, nSimWords) ); - return vCounters; -} /**Function************************************************************* - Synopsis [Returns random patterns.] + Synopsis [Returns the random pattern.] Description [] @@ -441,7 +392,7 @@ Vec_Int_t * Sim_UtilCountOnesArray( Vec_Ptr_t * vInfo, int nSimWords ) SeeAlso [] ***********************************************************************/ -void Sim_UtilSetRandom( unsigned * pPatRand, int nSimWords ) +void Sim_UtilGetRandom( unsigned * pPatRand, int nSimWords ) { int k; for ( k = 0; k < nSimWords; k++ ) @@ -450,104 +401,6 @@ void Sim_UtilSetRandom( unsigned * pPatRand, int nSimWords ) /**Function************************************************************* - Synopsis [Returns complemented patterns.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilSetCompl( unsigned * pPatRand, int nSimWords ) -{ - int k; - for ( k = 0; k < nSimWords; k++ ) - pPatRand[k] = ~pPatRand[k]; -} - -/**Function************************************************************* - - Synopsis [Returns constant patterns.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilSetConst( unsigned * pPatRand, int nSimWords, int fConst1 ) -{ - int k; - for ( k = 0; k < nSimWords; k++ ) - pPatRand[k] = 0; - if ( fConst1 ) - Sim_UtilSetCompl( pPatRand, nSimWords ); -} - -/**Function************************************************************* - - Synopsis [Returns 1 if equal.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_UtilInfoIsEqual( unsigned * pPats1, unsigned * pPats2, int nSimWords ) -{ - int k; - for ( k = 0; k < nSimWords; k++ ) - if ( pPats1[k] != pPats2[k] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if Node1 implies Node2.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_UtilInfoIsImp( unsigned * pPats1, unsigned * pPats2, int nSimWords ) -{ - int k; - for ( k = 0; k < nSimWords; k++ ) - if ( pPats1[k] & ~pPats2[k] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if Node1 v Node2 is always true.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_UtilInfoIsClause( unsigned * pPats1, unsigned * pPats2, int nSimWords ) -{ - int k; - for ( k = 0; k < nSimWords; k++ ) - if ( ~pPats1[k] & ~pPats2[k] ) - return 0; - return 1; -} - -/**Function************************************************************* - Synopsis [Counts the total number of pairs.] Description [] @@ -607,51 +460,6 @@ int Sim_UtilCountPairsOne( Extra_BitMat_t * pMat, Vec_Int_t * vSupport ) SeeAlso [] ***********************************************************************/ -int Sim_UtilCountPairsOnePrint( Extra_BitMat_t * pMat, Vec_Int_t * vSupport ) -{ - int i, k, Index1, Index2; - Vec_IntForEachEntry( vSupport, i, Index1 ) - Vec_IntForEachEntryStart( vSupport, k, Index2, Index1+1 ) - if ( Extra_BitMatrixLookup1( pMat, i, k ) ) - printf( "(%d,%d) ", i, k ); - return 0; -} - -/**Function************************************************************* - - Synopsis [Counts the number of entries in the array of matrices.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilCountPairsAllPrint( Sym_Man_t * p ) -{ - int i, clk; -clk = clock(); - for ( i = 0; i < p->nOutputs; i++ ) - { - printf( "Output %2d :", i ); - Sim_UtilCountPairsOnePrint( Vec_PtrEntry(p->vMatrSymms, i), Vec_VecEntry(p->vSupports, i) ); - printf( "\n" ); - } -p->timeCount += clock() - clk; -} - -/**Function************************************************************* - - Synopsis [Counts the number of entries in the array of matrices.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ void Sim_UtilCountPairsAll( Sym_Man_t * p ) { int nPairsTotal, nPairsSym, nPairsNonSym, i, clk; |