diff options
Diffstat (limited to 'src/opt')
96 files changed, 0 insertions, 30875 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 deleted file mode 100644 index dee05dfc..00000000 --- a/src/opt/cut/cut.h +++ /dev/null @@ -1,165 +0,0 @@ -/**CFile**************************************************************** - - FileName [cut.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [K-feasible cut computation package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: .h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __CUT_H__ -#define __CUT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// 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 -}; - -struct Cut_CutStruct_t_ -{ - unsigned Num0 : 11; // temporary number - unsigned Num1 : 11; // temporary number - 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 - Cut_Cut_t * pNext; // the next cut in the list - int pLeaves[0]; // the array of leaves -}; - -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_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]; -} - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// 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 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 - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - 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 deleted file mode 100644 index 17f268c7..00000000 --- a/src/opt/cut/cutInt.h +++ /dev/null @@ -1,157 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutInt.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [K-feasible cut computation package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __CUT_INT_H__ -#define __CUT_INT_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include <stdio.h> -#include "extra.h" -#include "vec.h" -#include "cut.h" -#include "cutList.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -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 - // 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; - // statistics - int nCutsCur; - int nCutsAlloc; - int nCutsDealloc; - int nCutsPeak; - int nCutsTriv; - int nCutsFilter; - int nCutsLimit; - 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 /// -//////////////////////////////////////////////////////////////////////// - -// 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 ); -/*=== cutTable.c ==========================================================*/ -extern Cut_HashTable_t * Cut_TableStart( int Size ); -extern void Cut_TableStop( Cut_HashTable_t * pTable ); -extern int Cut_TableLookup( Cut_HashTable_t * pTable, Cut_Cut_t * pCut, int fStore ); -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 - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/cut/cutList.h b/src/opt/cut/cutList.h deleted file mode 100644 index a03ec9d5..00000000 --- a/src/opt/cut/cutList.h +++ /dev/null @@ -1,207 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutList.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Implementation of layered listed list of cuts.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutList.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __CUT_LIST_H__ -#define __CUT_LIST_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -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]; -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Start the cut list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Cut_ListStart( Cut_List_t * p ) -{ - int i; - for ( i = 1; i <= CUT_SIZE_MAX; i++ ) - { - p->pHead[i] = 0; - p->ppTail[i] = &p->pHead[i]; - } -} - -/**Function************************************************************* - - Synopsis [Adds one cut to the cut list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Cut_ListAdd( Cut_List_t * p, Cut_Cut_t * pCut ) -{ - assert( pCut->nLeaves > 0 && pCut->nLeaves <= CUT_SIZE_MAX ); - *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.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -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; -} - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/cut/cutMan.c b/src/opt/cut/cutMan.c deleted file mode 100644 index 8593ef93..00000000 --- a/src/opt/cut/cutMan.c +++ /dev/null @@ -1,326 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [K-feasible cut computation package.] - - Synopsis [Cut manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "cutInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -extern void Npn_StartTruth8( uint8 uTruths[][32] ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts the cut manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -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 ); - 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 ( 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" ); - } - } - // 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 ); - } - // memory for cuts - p->pMmCuts = Extra_MmFixedStart( p->EntrySize ); - p->vTemp = Vec_PtrAlloc( 100 ); - return p; -} - -/**Function************************************************************* - - Synopsis [Stops the cut manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -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 ) - 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 ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -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( "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************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -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 deleted file mode 100644 index d8a9989c..00000000 --- a/src/opt/cut/cutMerge.c +++ /dev/null @@ -1,657 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutMerge.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [K-feasible cut computation package.] - - Synopsis [Procedure to merge two cuts.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutMerge.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "cutInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Merges two cuts.] - - Description [This procedure works.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutMergeTwo2( 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; - int * pRow; - int nLeaves0, nLeaves1, Limit; - int i, k, Count, nNodes; - - assert( pCut0->nLeaves >= pCut1->nLeaves ); - - // the case of the largest cut sizes - Limit = p->pParams->nVarsMax; - nLeaves0 = pCut0->nLeaves; - nLeaves1 = pCut1->nLeaves; - if ( nLeaves0 == Limit && nLeaves1 == Limit ) - { - for ( i = 0; i < nLeaves0; i++ ) - if ( pCut0->pLeaves[i] != pCut1->pLeaves[i] ) - return NULL; - pRes = Cut_CutAlloc( p ); - for ( i = 0; i < nLeaves0; i++ ) - pRes->pLeaves[i] = pCut0->pLeaves[i]; - pRes->nLeaves = nLeaves0; - return pRes; - } - // the case when one of the cuts is the largest - if ( nLeaves0 == Limit ) - { - for ( i = 0; i < nLeaves1; i++ ) - { - for ( k = nLeaves0 - 1; k >= 0; k-- ) - if ( pCut0->pLeaves[k] == pCut1->pLeaves[i] ) - break; - if ( k == -1 ) // did not find - return NULL; - } - pRes = Cut_CutAlloc( p ); - for ( i = 0; i < nLeaves0; i++ ) - pRes->pLeaves[i] = pCut0->pLeaves[i]; - pRes->nLeaves = nLeaves0; - return pRes; - } - // other cases - nNodes = nLeaves0; - for ( i = 0; i < nLeaves1; i++ ) - { - for ( k = nLeaves0 - 1; k >= 0; k-- ) - { - if ( pCut0->pLeaves[k] > pCut1->pLeaves[i] ) - continue; - if ( pCut0->pLeaves[k] < pCut1->pLeaves[i] ) - { - pRow = M[k+1]; - if ( pRow[0] == 0 ) - pRow[0] = pCut1->pLeaves[i], pRow[1] = 0; - else if ( pRow[1] == 0 ) - pRow[1] = pCut1->pLeaves[i], pRow[2] = 0; - else if ( pRow[2] == 0 ) - pRow[2] = pCut1->pLeaves[i]; - else - assert( 0 ); - if ( ++nNodes > Limit ) - { - for ( i = 0; i <= nLeaves0; i++ ) - M[i][0] = 0; - return NULL; - } - } - break; - } - if ( k == -1 ) - { - pRow = M[0]; - if ( pRow[0] == 0 ) - pRow[0] = pCut1->pLeaves[i], pRow[1] = 0; - else if ( pRow[1] == 0 ) - pRow[1] = pCut1->pLeaves[i], pRow[2] = 0; - else if ( pRow[2] == 0 ) - pRow[2] = pCut1->pLeaves[i]; - else - assert( 0 ); - if ( ++nNodes > Limit ) - { - for ( i = 0; i <= nLeaves0; i++ ) - M[i][0] = 0; - return NULL; - } - continue; - } - } - - pRes = Cut_CutAlloc( p ); - for ( Count = 0, i = 0; i <= nLeaves0; i++ ) - { - if ( i > 0 ) - pRes->pLeaves[Count++] = pCut0->pLeaves[i-1]; - pRow = M[i]; - if ( pRow[0] ) - { - pRes->pLeaves[Count++] = pRow[0]; - if ( pRow[1] ) - { - pRes->pLeaves[Count++] = pRow[1]; - if ( pRow[2] ) - pRes->pLeaves[Count++] = pRow[2]; - } - pRow[0] = 0; - } - } - assert( Count == nNodes ); - pRes->nLeaves = nNodes; - return pRes; -} - -/**Function************************************************************* - - Synopsis [Merges two cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutMergeTwo( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) -{ - Cut_Cut_t * pRes; - int * pLeaves; - int Limit, nLeaves0, nLeaves1; - int i, k, c; - - assert( pCut0->nLeaves >= pCut1->nLeaves ); - - // consider two cuts - nLeaves0 = pCut0->nLeaves; - nLeaves1 = pCut1->nLeaves; - - // the case of the largest cut sizes - Limit = p->pParams->nVarsMax; - if ( nLeaves0 == Limit && nLeaves1 == Limit ) - { - for ( i = 0; i < nLeaves0; i++ ) - if ( pCut0->pLeaves[i] != pCut1->pLeaves[i] ) - return NULL; - pRes = Cut_CutAlloc( p ); - for ( i = 0; i < nLeaves0; i++ ) - pRes->pLeaves[i] = pCut0->pLeaves[i]; - pRes->nLeaves = pCut0->nLeaves; - return pRes; - } - // the case when one of the cuts is the largest - if ( nLeaves0 == Limit ) - { - for ( i = 0; i < nLeaves1; i++ ) - { - for ( k = nLeaves0 - 1; k >= 0; k-- ) - if ( pCut0->pLeaves[k] == pCut1->pLeaves[i] ) - break; - if ( k == -1 ) // did not find - return NULL; - } - pRes = Cut_CutAlloc( p ); - for ( i = 0; i < nLeaves0; i++ ) - pRes->pLeaves[i] = pCut0->pLeaves[i]; - pRes->nLeaves = pCut0->nLeaves; - return pRes; - } - - // prepare the cut - if ( p->pReady == NULL ) - p->pReady = Cut_CutAlloc( p ); - pLeaves = p->pReady->pLeaves; - - // compare two cuts with different numbers - i = k = 0; - for ( c = 0; c < Limit; c++ ) - { - if ( k == nLeaves1 ) - { - if ( i == nLeaves0 ) - { - p->pReady->nLeaves = c; - pRes = p->pReady; p->pReady = NULL; - return pRes; - } - pLeaves[c] = pCut0->pLeaves[i++]; - continue; - } - if ( i == nLeaves0 ) - { - if ( k == nLeaves1 ) - { - p->pReady->nLeaves = c; - pRes = p->pReady; p->pReady = NULL; - return pRes; - } - pLeaves[c] = pCut1->pLeaves[k++]; - continue; - } - if ( pCut0->pLeaves[i] < pCut1->pLeaves[k] ) - { - pLeaves[c] = pCut0->pLeaves[i++]; - continue; - } - if ( pCut0->pLeaves[i] > pCut1->pLeaves[k] ) - { - pLeaves[c] = pCut1->pLeaves[k++]; - continue; - } - pLeaves[c] = pCut0->pLeaves[i++]; - k++; - } - if ( i < nLeaves0 || k < nLeaves1 ) - return NULL; - p->pReady->nLeaves = c; - pRes = p->pReady; p->pReady = NULL; - return pRes; -} - - -/**Function************************************************************* - - Synopsis [Merges two cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutMergeTwo3( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) -{ - Cut_Cut_t * pRes; - int * pLeaves; - int Limit, nLeaves0, nLeaves1; - int i, k, c; - - assert( pCut0->nLeaves >= pCut1->nLeaves ); - - // prepare the cut - if ( p->pReady == NULL ) - p->pReady = Cut_CutAlloc( p ); - pLeaves = p->pReady->pLeaves; - - // consider two cuts - Limit = p->pParams->nVarsMax; - nLeaves0 = pCut0->nLeaves; - nLeaves1 = pCut1->nLeaves; - if ( nLeaves0 == Limit ) - { // the case when one of the cuts is the largest - if ( nLeaves1 == Limit ) - { // the case when both cuts are the largest - for ( i = 0; i < nLeaves0; i++ ) - { - pLeaves[i] = pCut0->pLeaves[i]; - if ( pLeaves[i] != pCut1->pLeaves[i] ) - return NULL; - } - } - else - { - for ( i = k = 0; i < nLeaves0; i++ ) - { - pLeaves[i] = pCut0->pLeaves[i]; - if ( k == (int)nLeaves1 ) - continue; - if ( pLeaves[i] < pCut1->pLeaves[k] ) - continue; - if ( pLeaves[i] == pCut1->pLeaves[k++] ) - continue; - return NULL; - } - if ( k < nLeaves1 ) - return NULL; - } - p->pReady->nLeaves = nLeaves0; - pRes = p->pReady; p->pReady = NULL; - return pRes; - } - - // compare two cuts with different numbers - i = k = 0; - for ( c = 0; c < Limit; c++ ) - { - if ( k == nLeaves1 ) - { - if ( i == nLeaves0 ) - { - p->pReady->nLeaves = c; - pRes = p->pReady; p->pReady = NULL; - return pRes; - } - pLeaves[c] = pCut0->pLeaves[i++]; - continue; - } - if ( i == nLeaves0 ) - { - if ( k == nLeaves1 ) - { - p->pReady->nLeaves = c; - pRes = p->pReady; p->pReady = NULL; - return pRes; - } - pLeaves[c] = pCut1->pLeaves[k++]; - continue; - } - if ( pCut0->pLeaves[i] < pCut1->pLeaves[k] ) - { - pLeaves[c] = pCut0->pLeaves[i++]; - continue; - } - if ( pCut0->pLeaves[i] > pCut1->pLeaves[k] ) - { - pLeaves[c] = pCut1->pLeaves[k++]; - continue; - } - pLeaves[c] = pCut0->pLeaves[i++]; - k++; - } - if ( i < nLeaves0 || k < nLeaves1 ) - return NULL; - p->pReady->nLeaves = c; - pRes = p->pReady; p->pReady = NULL; - return pRes; -} - -/**Function************************************************************* - - Synopsis [Merges two cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutMergeTwo4( Cut_Man_t * p, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1 ) -{ - Cut_Cut_t * pRes; - int * pLeaves; - int i, k, min, NodeTemp, Limit, nTotal; - - assert( pCut0->nLeaves >= pCut1->nLeaves ); - - // prepare the cut - if ( p->pReady == NULL ) - p->pReady = Cut_CutAlloc( p ); - pLeaves = p->pReady->pLeaves; - - // consider two cuts - Limit = p->pParams->nVarsMax; - if ( pCut0->nLeaves == (unsigned)Limit ) - { // the case when one of the cuts is the largest - if ( pCut1->nLeaves == (unsigned)Limit ) - { // the case when both cuts are the largest - for ( i = 0; i < (int)pCut0->nLeaves; i++ ) - { - pLeaves[i] = pCut0->pLeaves[i]; - if ( pLeaves[i] != pCut1->pLeaves[i] ) - return NULL; - } - } - else - { - for ( i = k = 0; i < (int)pCut0->nLeaves; i++ ) - { - pLeaves[i] = pCut0->pLeaves[i]; - if ( k == (int)pCut1->nLeaves ) - continue; - if ( pLeaves[i] < pCut1->pLeaves[k] ) - continue; - if ( pLeaves[i] == pCut1->pLeaves[k++] ) - continue; - return NULL; - } - if ( k < (int)pCut1->nLeaves ) - return NULL; - } - p->pReady->nLeaves = pCut0->nLeaves; - pRes = p->pReady; p->pReady = NULL; - return pRes; - } - - // count the number of unique entries in pCut1 - nTotal = pCut0->nLeaves; - for ( i = 0; i < (int)pCut1->nLeaves; i++ ) - { - // try to find this entry among the leaves of pCut0 - for ( k = 0; k < (int)pCut0->nLeaves; k++ ) - if ( pCut1->pLeaves[i] == pCut0->pLeaves[k] ) - break; - if ( k < (int)pCut0->nLeaves ) // found - continue; - // we found a new entry to add - if ( nTotal == Limit ) - return NULL; - pLeaves[nTotal++] = pCut1->pLeaves[i]; - } - // we know that the feasible cut exists - - // add the starting entries - for ( k = 0; k < (int)pCut0->nLeaves; k++ ) - pLeaves[k] = pCut0->pLeaves[k]; - - // selection-sort the entries - for ( i = 0; i < nTotal - 1; i++ ) - { - min = i; - for ( k = i+1; k < nTotal; k++ ) - if ( pLeaves[k] < pLeaves[min] ) - min = k; - NodeTemp = pLeaves[i]; - pLeaves[i] = pLeaves[min]; - pLeaves[min] = NodeTemp; - } - p->pReady->nLeaves = nTotal; - pRes = p->pReady; p->pReady = NULL; - return pRes; -} - -/**Function************************************************************* - - Synopsis [Merges two cuts.] - - Description [This procedure works.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_CutMergeTwo5( 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; - int * pRow; - unsigned uSign0, uSign1; - int i, k, nNodes, Count; - unsigned Limit = p->pParams->nVarsMax; - - assert( pCut0->nLeaves >= pCut1->nLeaves ); - - // the case of the largest cut sizes - if ( pCut0->nLeaves == Limit && pCut1->nLeaves == Limit ) - { - for ( i = 0; i < (int)pCut0->nLeaves; i++ ) - if ( pCut0->pLeaves[i] != pCut1->pLeaves[i] ) - return NULL; - pRes = Cut_CutAlloc( p ); - for ( i = 0; i < (int)pCut0->nLeaves; i++ ) - pRes->pLeaves[i] = pCut0->pLeaves[i]; - pRes->nLeaves = pCut0->nLeaves; - return pRes; - } - // the case when one of the cuts is the largest - if ( pCut0->nLeaves == Limit ) - { - if ( !p->pParams->fTruth ) - { - for ( i = 0; i < (int)pCut1->nLeaves; i++ ) - { - for ( k = pCut0->nLeaves - 1; k >= 0; k-- ) - if ( pCut0->pLeaves[k] == pCut1->pLeaves[i] ) - break; - if ( k == -1 ) // did not find - return NULL; - } - pRes = Cut_CutAlloc( p ); - } - else - { - uSign1 = 0; - for ( i = 0; i < (int)pCut1->nLeaves; i++ ) - { - for ( k = pCut0->nLeaves - 1; k >= 0; k-- ) - if ( pCut0->pLeaves[k] == pCut1->pLeaves[i] ) - { - uSign1 |= (1 << i); - break; - } - if ( k == -1 ) // did not find - return NULL; - } - pRes = Cut_CutAlloc( p ); - pRes->Num1 = uSign1; - } - for ( i = 0; i < (int)pCut0->nLeaves; i++ ) - pRes->pLeaves[i] = pCut0->pLeaves[i]; - pRes->nLeaves = pCut0->nLeaves; - return pRes; - } - // other cases - nNodes = pCut0->nLeaves; - for ( i = 0; i < (int)pCut1->nLeaves; i++ ) - { - for ( k = pCut0->nLeaves - 1; k >= 0; k-- ) - { - if ( pCut0->pLeaves[k] > pCut1->pLeaves[i] ) - continue; - if ( pCut0->pLeaves[k] < pCut1->pLeaves[i] ) - { - pRow = M[k+1]; - if ( pRow[0] == 0 ) - pRow[0] = pCut1->pLeaves[i], pRow[1] = 0; - else if ( pRow[1] == 0 ) - pRow[1] = pCut1->pLeaves[i], pRow[2] = 0; - else if ( pRow[2] == 0 ) - pRow[2] = pCut1->pLeaves[i]; - else - assert( 0 ); - if ( ++nNodes > (int)Limit ) - { - for ( i = 0; i <= (int)pCut0->nLeaves; i++ ) - M[i][0] = 0; - return NULL; - } - } - break; - } - if ( k == -1 ) - { - pRow = M[0]; - if ( pRow[0] == 0 ) - pRow[0] = pCut1->pLeaves[i], pRow[1] = 0; - else if ( pRow[1] == 0 ) - pRow[1] = pCut1->pLeaves[i], pRow[2] = 0; - else if ( pRow[2] == 0 ) - pRow[2] = pCut1->pLeaves[i]; - else - assert( 0 ); - if ( ++nNodes > (int)Limit ) - { - for ( i = 0; i <= (int)pCut0->nLeaves; i++ ) - M[i][0] = 0; - return NULL; - } - continue; - } - } - - pRes = Cut_CutAlloc( p ); - if ( !p->pParams->fTruth ) - { - for ( Count = 0, i = 0; i <= (int)pCut0->nLeaves; i++ ) - { - if ( i > 0 ) - pRes->pLeaves[Count++] = pCut0->pLeaves[i-1]; - pRow = M[i]; - if ( pRow[0] ) - { - pRes->pLeaves[Count++] = pRow[0]; - if ( pRow[1] ) - { - pRes->pLeaves[Count++] = pRow[1]; - if ( pRow[2] ) - pRes->pLeaves[Count++] = pRow[2]; - } - pRow[0] = 0; - } - } - assert( Count == nNodes ); - pRes->nLeaves = nNodes; -/* - // make sure that the cut is correct - { - for ( i = 1; i < (int)pRes->nLeaves; i++ ) - if ( pRes->pLeaves[i-1] >= pRes->pLeaves[i] ) - { - int v = 0; - } - } -*/ - return pRes; - } - - uSign0 = uSign1 = 0; - for ( Count = 0, i = 0; i <= (int)pCut0->nLeaves; i++ ) - { - if ( i > 0 ) - { - uSign0 |= (1 << Count); - pRes->pLeaves[Count++] = pCut1->pLeaves[i-1]; - } - pRow = M[i]; - if ( pRow[0] ) - { - uSign1 |= (1 << Count); - pRes->pLeaves[Count++] = pRow[0]; - if ( pRow[1] ) - { - uSign1 |= (1 << Count); - pRes->pLeaves[Count++] = pRow[1]; - if ( pRow[2] ) - { - uSign1 |= (1 << Count); - pRes->pLeaves[Count++] = pRow[2]; - } - } - pRow[0] = 0; - } - } - assert( Count == nNodes ); - pRes->nLeaves = nNodes; - pRes->Num1 = uSign1; - pRes->Num0 = uSign0; - return pRes; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/cut/cutNode.c b/src/opt/cut/cutNode.c deleted file mode 100644 index 1f93b14b..00000000 --- a/src/opt/cut/cutNode.c +++ /dev/null @@ -1,992 +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 /// -//////////////////////////////////////////////////////////////////////// - -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 ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Returns 1 if pDom is contained in pCut.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Cut_CutCheckDominance( Cut_Cut_t * pDom, Cut_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 [Filters cuts using dominance.] - - Description [] - - SideEffects [] - - 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 ) -{ - 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; -} - -/**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.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_NodeComputeCuts( Cut_Man_t * p, int Node, int Node0, int Node1, int fCompl0, int fCompl1, int fTriv, int TreeCode ) -{ - 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; -} - -/**Function************************************************************* - - Synopsis [Returns optimum delay mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_NodeMapping2( Cut_Man_t * p, Cut_Cut_t * pCuts, int Node, int Node0, int Node1 ) -{ - 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; -} - -/**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.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_ManMappingArea_rec( 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.] - - Description [] - - SideEffects [] - - 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 * 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++; - } - // 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; - // 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 ) - break; - Cut_ListForEachCut( pList1, pStop1 ) - if ( pStop1->nLeaves == (unsigned)Limit ) - break; - - // 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 ) - 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 ) - Cut_ListForEachCut( pStop0, pTemp0 ) - { - if ( (pTemp0->uSign & pTemp1->uSign) != pTemp1->uSign ) - continue; - if ( Cut_CutProcessTwo( p, pTemp0, pTemp1, pSuper ) ) - goto Quits; - } - // 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; -} - -/**Function************************************************************* - - Synopsis [Computes the cuts by unioning cuts at a choice node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_NodeUnionCuts( Cut_Man_t * p, Vec_Int_t * vNodes ) -{ - 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(); - - // start the new list - Cut_ListStart( pSuper ); - - // remember the root node to save the resulting cuts - Root = Vec_IntEntry( vNodes, 0 ); - p->nNodeCuts = 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 ); - 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; - else - Cut_CutRecycle( p, pList ); - // 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; - // 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; - // 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 - assert( Cut_NodeReadCutsNew(p, Root) == NULL ); - pList = Cut_ListFinish( pSuper ); - Cut_NodeWriteCutsNew( p, Root, pList ); -p->timeUnion += clock() - clk; - // filter the cuts -//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.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Cut_Cut_t * Cut_NodeUnionCutsSeq( Cut_Man_t * p, Vec_Int_t * vNodes, int CutSetNum, int fFirst ) -{ - 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(); - - // start the new list - Cut_ListStart( pSuper ); - - // remember the root node to save the resulting cuts - Root = Vec_IntEntry( vNodes, 0 ); - p->nNodeCuts = 1; - - // store the original lists for comparison - p->pCompareOld = Cut_NodeReadCutsOld( p, Root ); - p->pCompareNew = (CutSetNum >= 0)? Cut_NodeReadCutsNew( p, Root ) : NULL; - - // get the topmost cut - pTop = NULL; - if ( (pTop = Cut_NodeReadCutsOld( p, Root )) == NULL ) - pTop = Cut_NodeReadCutsNew( p, Root ); - assert( pTop != NULL ); - - // 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; - - // 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; - - // 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; - } - } - - // 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; - } - } - - // 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 ); - - // 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 ); - } - -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 [Verifies that the list contains only non-dominated cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Cut_CutListVerify( Cut_Cut_t * pList ) -{ - Cut_Cut_t * pCut, * pDom; - Cut_ListForEachCut( pList, pCut ) - { - Cut_ListForEachCutStop( pList, pDom, pCut ) - { - if ( Cut_CutCheckDominance( pDom, pCut ) ) - { - int x = 0; - printf( "******************* These are contained cuts:\n" ); - Cut_CutPrint( pDom, 1 ); - Cut_CutPrint( pDom, 1 ); - - return 0; - } - } - } - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// 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 deleted file mode 100644 index d36f94f7..00000000 --- a/src/opt/cut/cutSeq.c +++ /dev/null @@ -1,227 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutSeq.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [K-feasible cut computation package.] - - Synopsis [Sequential cut computation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutSeq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "cutInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Shifts all cut leaves of the node by the given number of latches.] - - Description [] - - SideEffects [] - - 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/cutTruth.c b/src/opt/cut/cutTruth.c deleted file mode 100644 index c3514ad7..00000000 --- a/src/opt/cut/cutTruth.c +++ /dev/null @@ -1,226 +0,0 @@ -/**CFile**************************************************************** - - FileName [cutTruth.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [K-feasible cut computation package.] - - Synopsis [Incremental truth table computation.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: cutTruth.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#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; - -//////////////////////////////////////////////////////////////////////// -/// 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 [Performs truth table computation.] - - Description [This procedure cannot be used while recording oracle - because it will overwrite Num0 and Num1.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_TruthNCanonicize( Cut_Cut_t * pCut ) -{ - 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]; -} - -/**Function************************************************************* - - Synopsis [Performs truth table computation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_TruthComputeOld( Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 ) -{ - static unsigned uTruth0[8], uTruth1[8]; - int nTruthWords = Cut_TruthWords( pCut->nVarsMax ); - unsigned * pTruthRes; - int i, 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]; - } - - // 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]; - } - - // write the resulting table - pTruthRes = Cut_CutReadTruth(pCut); - - 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]; - } -} - -/**Function************************************************************* - - Synopsis [Performs truth table computation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Cut_TruthCompute( Cut_Man_t * p, Cut_Cut_t * pCut, Cut_Cut_t * pCut0, Cut_Cut_t * pCut1, int fCompl0, int fCompl1 ) -{ - // 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 - 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 ); - -// Ivy_TruthTestOne( *Cut_CutReadTruth(pCut) ); - - // quit if no fancy computation is needed - if ( !p->pParams->fFancy ) - return; - - if ( pCut->nLeaves != 7 ) - return; - - // count the total number of truth tables computed - nTotal++; - - // 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++; - - // 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 ); -} - - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/cut/module.make b/src/opt/cut/module.make deleted file mode 100644 index 132e730b..00000000 --- a/src/opt/cut/module.make +++ /dev/null @@ -1,9 +0,0 @@ -SRC += src/opt/cut/cutApi.c \ - src/opt/cut/cutCut.c \ - 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/cutTruth.c diff --git a/src/opt/dec/dec.h b/src/opt/dec/dec.h deleted file mode 100644 index 41d22649..00000000 --- a/src/opt/dec/dec.h +++ /dev/null @@ -1,719 +0,0 @@ -/**CFile**************************************************************** - - FileName [dec.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [A simple decomposition tree/node data structure and its APIs.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: dec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __DEC_H__ -#define __DEC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Dec_Edge_t_ Dec_Edge_t; -struct Dec_Edge_t_ -{ - unsigned fCompl : 1; // the complemented bit - unsigned Node : 30; // the decomposition node pointed by the edge -}; - -typedef struct Dec_Node_t_ Dec_Node_t; -struct Dec_Node_t_ -{ - Dec_Edge_t eEdge0; // the left child of the node - 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 - // 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; -struct Dec_Graph_t_ -{ - int fConst; // marks the constant 1 graph - int nLeaves; // the number of leaves - int nSize; // the number of nodes (including the leaves) - int nCap; // the number of allocated nodes - Dec_Node_t * pNodes; // the array of leaves and internal nodes - Dec_Edge_t eRoot; // the pointer to the topmost node -}; - -typedef struct Dec_Man_t_ Dec_Man_t; -struct Dec_Man_t_ -{ - void * pMvcMem; // memory manager for MVC cover (used for factoring) - Vec_Int_t * vCubes; // storage for cubes - Vec_Int_t * vLits; // storage for literals - // precomputation information about 4-variable functions - unsigned short * puCanons; // canonical forms - char * pPhases; // canonical phases - char * pPerms; // canonical permutations - unsigned char * pMap; // mapping of functions into class numbers -}; - - -//////////////////////////////////////////////////////////////////////// -/// ITERATORS /// -//////////////////////////////////////////////////////////////////////// - -// interator throught the leaves -#define Dec_GraphForEachLeaf( pGraph, pLeaf, i ) \ - for ( i = 0; (i < (pGraph)->nLeaves) && (((pLeaf) = Dec_GraphNode(pGraph, i)), 1); i++ ) -// interator throught the internal nodes -#define Dec_GraphForEachNode( pGraph, pAnd, i ) \ - for ( i = (pGraph)->nLeaves; (i < (pGraph)->nSize) && (((pAnd) = Dec_GraphNode(pGraph, i)), 1); i++ ) - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== decAbc.c ========================================================*/ -extern Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph ); -extern Abc_Obj_t * Dec_GraphToNetworkNoStrash( Abc_Ntk_t * pNtk, 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, bool fUpdateLevel, int nGain ); -/*=== decFactor.c ========================================================*/ -extern Dec_Graph_t * Dec_Factor( char * pSop ); -/*=== decMan.c ========================================================*/ -extern Dec_Man_t * Dec_ManStart(); -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************************************************************* - - Synopsis [Creates an edge pointing to the node in the given polarity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Edge_t Dec_EdgeCreate( int Node, int fCompl ) -{ - Dec_Edge_t eEdge = { fCompl, Node }; - return eEdge; -} - -/**Function************************************************************* - - Synopsis [Converts the edge into unsigned integer.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline unsigned Dec_EdgeToInt( Dec_Edge_t eEdge ) -{ - return (eEdge.Node << 1) | eEdge.fCompl; -} - -/**Function************************************************************* - - Synopsis [Converts unsigned integer into the edge.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Edge_t Dec_IntToEdge( unsigned Edge ) -{ - return Dec_EdgeCreate( Edge >> 1, Edge & 1 ); -} - -/**Function************************************************************* - - Synopsis [Converts the edge into unsigned integer.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline unsigned Dec_EdgeToInt_( Dec_Edge_t eEdge ) -{ - return *(unsigned *)&eEdge; -} - -/**Function************************************************************* - - Synopsis [Converts unsigned integer into the edge.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Edge_t Dec_IntToEdge_( unsigned Edge ) -{ - return *(Dec_Edge_t *)&Edge; -} - -/**Function************************************************************* - - Synopsis [Creates a graph with the given number of leaves.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Graph_t * Dec_GraphCreate( int nLeaves ) -{ - Dec_Graph_t * pGraph; - pGraph = ALLOC( Dec_Graph_t, 1 ); - memset( pGraph, 0, sizeof(Dec_Graph_t) ); - pGraph->nLeaves = nLeaves; - pGraph->nSize = nLeaves; - pGraph->nCap = 2 * nLeaves + 50; - pGraph->pNodes = ALLOC( Dec_Node_t, pGraph->nCap ); - memset( pGraph->pNodes, 0, sizeof(Dec_Node_t) * pGraph->nSize ); - return pGraph; -} - -/**Function************************************************************* - - Synopsis [Creates constant 0 graph.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Graph_t * Dec_GraphCreateConst0() -{ - Dec_Graph_t * pGraph; - pGraph = ALLOC( Dec_Graph_t, 1 ); - memset( pGraph, 0, sizeof(Dec_Graph_t) ); - pGraph->fConst = 1; - pGraph->eRoot.fCompl = 1; - return pGraph; -} - -/**Function************************************************************* - - Synopsis [Creates constant 1 graph.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Graph_t * Dec_GraphCreateConst1() -{ - Dec_Graph_t * pGraph; - pGraph = ALLOC( Dec_Graph_t, 1 ); - memset( pGraph, 0, sizeof(Dec_Graph_t) ); - pGraph->fConst = 1; - return pGraph; -} - -/**Function************************************************************* - - Synopsis [Creates the literal graph.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Graph_t * Dec_GraphCreateLeaf( int iLeaf, int nLeaves, int fCompl ) -{ - Dec_Graph_t * pGraph; - assert( 0 <= iLeaf && iLeaf < nLeaves ); - pGraph = Dec_GraphCreate( nLeaves ); - pGraph->eRoot.Node = iLeaf; - pGraph->eRoot.fCompl = fCompl; - return pGraph; -} - -/**Function************************************************************* - - Synopsis [Creates a graph with the given number of leaves.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Dec_GraphFree( Dec_Graph_t * pGraph ) -{ - FREE( pGraph->pNodes ); - free( pGraph ); -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the graph is a constant.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline bool Dec_GraphIsConst( Dec_Graph_t * pGraph ) -{ - return pGraph->fConst; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the graph is constant 0.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline bool Dec_GraphIsConst0( Dec_Graph_t * pGraph ) -{ - return pGraph->fConst && pGraph->eRoot.fCompl; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the graph is constant 1.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline bool Dec_GraphIsConst1( Dec_Graph_t * pGraph ) -{ - return pGraph->fConst && !pGraph->eRoot.fCompl; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the graph is complemented.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline bool Dec_GraphIsComplement( Dec_Graph_t * pGraph ) -{ - return pGraph->eRoot.fCompl; -} - -/**Function************************************************************* - - Synopsis [Checks if the graph is complemented.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Dec_GraphComplement( Dec_Graph_t * pGraph ) -{ - pGraph->eRoot.fCompl ^= 1; -} - - -/**Function************************************************************* - - Synopsis [Returns the number of leaves.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Dec_GraphLeaveNum( Dec_Graph_t * pGraph ) -{ - return pGraph->nLeaves; -} - -/**Function************************************************************* - - Synopsis [Returns the number of internal nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Dec_GraphNodeNum( Dec_Graph_t * pGraph ) -{ - return pGraph->nSize - pGraph->nLeaves; -} - -/**Function************************************************************* - - Synopsis [Returns the pointer to the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Node_t * Dec_GraphNode( Dec_Graph_t * pGraph, int i ) -{ - return pGraph->pNodes + i; -} - -/**Function************************************************************* - - Synopsis [Returns the pointer to the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Node_t * Dec_GraphNodeLast( Dec_Graph_t * pGraph ) -{ - return pGraph->pNodes + pGraph->nSize - 1; -} - -/**Function************************************************************* - - Synopsis [Returns the number of the given node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Dec_GraphNodeInt( Dec_Graph_t * pGraph, Dec_Node_t * pNode ) -{ - return pNode - pGraph->pNodes; -} - -/**Function************************************************************* - - Synopsis [Check if the graph represents elementary variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline bool Dec_GraphIsVar( Dec_Graph_t * pGraph ) -{ - return pGraph->eRoot.Node < (unsigned)pGraph->nLeaves; -} - -/**Function************************************************************* - - Synopsis [Check if the graph represents elementary variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline bool Dec_GraphNodeIsVar( Dec_Graph_t * pGraph, Dec_Node_t * pNode ) -{ - return Dec_GraphNodeInt(pGraph,pNode) < pGraph->nLeaves; -} - -/**Function************************************************************* - - Synopsis [Returns the elementary variable elementary variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Node_t * Dec_GraphVar( Dec_Graph_t * pGraph ) -{ - assert( Dec_GraphIsVar( pGraph ) ); - return Dec_GraphNode( pGraph, pGraph->eRoot.Node ); -} - -/**Function************************************************************* - - Synopsis [Returns the number of the elementary variable.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int Dec_GraphVarInt( Dec_Graph_t * pGraph ) -{ - assert( Dec_GraphIsVar( pGraph ) ); - return Dec_GraphNodeInt( pGraph, Dec_GraphVar(pGraph) ); -} - -/**Function************************************************************* - - Synopsis [Sets the root of the graph.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Dec_GraphSetRoot( Dec_Graph_t * pGraph, Dec_Edge_t eRoot ) -{ - pGraph->eRoot = eRoot; -} - -/**Function************************************************************* - - Synopsis [Appends a new node to the graph.] - - Description [This procedure is meant for internal use.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Node_t * Dec_GraphAppendNode( Dec_Graph_t * pGraph ) -{ - Dec_Node_t * pNode; - if ( pGraph->nSize == pGraph->nCap ) - { - pGraph->pNodes = REALLOC( Dec_Node_t, pGraph->pNodes, 2 * pGraph->nCap ); - pGraph->nCap = 2 * pGraph->nCap; - } - pNode = pGraph->pNodes + pGraph->nSize++; - memset( pNode, 0, sizeof(Dec_Node_t) ); - return pNode; -} - -/**Function************************************************************* - - Synopsis [Creates an AND node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Edge_t Dec_GraphAddNodeAnd( Dec_Graph_t * pGraph, Dec_Edge_t eEdge0, Dec_Edge_t eEdge1 ) -{ - Dec_Node_t * pNode; - // get the new node - pNode = Dec_GraphAppendNode( pGraph ); - // set the inputs and other info - pNode->eEdge0 = eEdge0; - pNode->eEdge1 = eEdge1; - pNode->fCompl0 = eEdge0.fCompl; - pNode->fCompl1 = eEdge1.fCompl; - return Dec_EdgeCreate( pGraph->nSize - 1, 0 ); -} - -/**Function************************************************************* - - Synopsis [Creates an OR node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline Dec_Edge_t Dec_GraphAddNodeOr( Dec_Graph_t * pGraph, Dec_Edge_t eEdge0, Dec_Edge_t eEdge1 ) -{ - Dec_Node_t * pNode; - // get the new node - pNode = Dec_GraphAppendNode( pGraph ); - // set the inputs and other info - pNode->eEdge0 = eEdge0; - pNode->eEdge1 = eEdge1; - pNode->fCompl0 = eEdge0.fCompl; - pNode->fCompl1 = eEdge1.fCompl; - // make adjustments for the OR gate - pNode->fNodeOr = 1; - pNode->eEdge0.fCompl = !pNode->eEdge0.fCompl; - pNode->eEdge1.fCompl = !pNode->eEdge1.fCompl; - return Dec_EdgeCreate( pGraph->nSize - 1, 1 ); -} - -/**Function************************************************************* - - Synopsis [Creates an XOR node.] - - Description [] - - SideEffects [] - - 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 -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/dec/decAbc.c b/src/opt/dec/decAbc.c deleted file mode 100644 index bd960c14..00000000 --- a/src/opt/dec/decAbc.c +++ /dev/null @@ -1,305 +0,0 @@ -/**CFile**************************************************************** - - FileName [decAbc.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Interface between the decomposition package and ABC network.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: decAbc.c,v 1.1 2003/05/22 19:20:05 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "dec.h" -#include "ivy.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**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_GraphToNetwork( Abc_Ntk_t * pNtk, 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) ); - // 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 ); - } - // 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; - } - // complement the result if necessary - return Abc_ObjNotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); -} - -/**Function************************************************************* - - Synopsis [Counts the number of new nodes added when using this graph.] - - Description [AIG nodes for the fanins should be assigned to pNode->pFunc - of the leaves of the graph before calling this procedure. - Returns -1 if the number of nodes and levels exceeded the given limit or - the number of levels exceeded the maximum allowed level.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ) -{ - Abc_Aig_t * pMan = pRoot->pNtk->pManFunc; - Dec_Node_t * pNode, * pNode0, * pNode1; - Abc_Obj_t * pAnd, * pAnd0, * pAnd1; - int i, Counter, LevelNew, LevelOld; - // check for constant function or a literal - if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) ) - return 0; - // set the levels of the leaves - Dec_GraphForEachLeaf( pGraph, pNode, i ) - pNode->Level = Abc_ObjRegular(pNode->pFunc)->Level; - // compute the AIG size after adding the internal nodes - Counter = 0; - Dec_GraphForEachNode( pGraph, pNode, i ) - { - // get the children of this node - pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); - pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); - // get the AIG nodes corresponding to the children - pAnd0 = pNode0->pFunc; - pAnd1 = pNode1->pFunc; - if ( pAnd0 && pAnd1 ) - { - // if they are both present, find the resulting node - pAnd0 = Abc_ObjNotCond( pAnd0, pNode->eEdge0.fCompl ); - pAnd1 = Abc_ObjNotCond( pAnd1, pNode->eEdge1.fCompl ); - pAnd = Abc_AigAndLookup( pMan, pAnd0, pAnd1 ); - // return -1 if the node is the same as the original root - if ( Abc_ObjRegular(pAnd) == pRoot ) - return -1; - } - else - pAnd = NULL; - // count the number of added nodes - if ( pAnd == NULL || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pAnd)) ) - { - if ( ++Counter > NodeMax ) - return -1; - } - // count the number of new levels - LevelNew = 1 + ABC_MAX( pNode0->Level, pNode1->Level ); - if ( pAnd ) - { - if ( Abc_ObjRegular(pAnd) == Abc_AigConst1(pRoot->pNtk) ) - 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 ); - } - if ( LevelNew > LevelMax ) - return -1; - pNode->pFunc = pAnd; - pNode->Level = LevelNew; - } - return Counter; -} - - -/**Function************************************************************* - - Synopsis [Replaces MFFC of the node by the new factored form.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, bool fUpdateLevel, int nGain ) -{ - 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 ); - // remove the old nodes - Abc_AigReplace( pNtk->pManFunc, pRoot, pRootNew, fUpdateLevel ); - // 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 deleted file mode 100644 index dca422ea..00000000 --- a/src/opt/dec/decFactor.c +++ /dev/null @@ -1,392 +0,0 @@ -/**CFile**************************************************************** - - FileName [ftFactor.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Procedures for algebraic factoring.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: ftFactor.c,v 1.3 2003/09/01 04:56:43 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "main.h" -#include "mvc.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Dec_Edge_t Dec_Factor_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover ); -static Dec_Edge_t Dec_FactorLF_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cover_t * pSimple ); -static Dec_Edge_t Dec_FactorTrivial( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover ); -static Dec_Edge_t Dec_FactorTrivialCube( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cube_t * pCube, Vec_Int_t * vEdgeLits ); -static Dec_Edge_t Dec_FactorTrivialTree_rec( Dec_Graph_t * pFForm, Dec_Edge_t * peNodes, int nNodes, int fNodeOr ); -static int Dec_FactorVerify( char * pSop, Dec_Graph_t * pFForm ); -static Mvc_Cover_t * Dec_ConvertSopToMvc( char * pSop ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Factors the cover.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Graph_t * Dec_Factor( char * pSop ) -{ - Mvc_Cover_t * pCover; - Dec_Graph_t * pFForm; - Dec_Edge_t eRoot; - - // derive the cover from the SOP representation - pCover = Dec_ConvertSopToMvc( pSop ); - - // make sure the cover is CCS free (should be done before CST) - Mvc_CoverContain( pCover ); - // check for trivial functions - if ( Mvc_CoverIsEmpty(pCover) ) - { - Mvc_CoverFree( pCover ); - return Dec_GraphCreateConst0(); - } - if ( Mvc_CoverIsTautology(pCover) ) - { - Mvc_CoverFree( pCover ); - return Dec_GraphCreateConst1(); - } - - // perform CST - Mvc_CoverInverse( pCover ); // CST - // start the factored form - pFForm = Dec_GraphCreate( Abc_SopGetVarNum(pSop) ); - // factor the cover - eRoot = Dec_Factor_rec( pFForm, pCover ); - // finalize the factored form - Dec_GraphSetRoot( pFForm, eRoot ); - // complement the factored form if SOP is complemented - if ( Abc_SopIsComplement(pSop) ) - Dec_GraphComplement( pFForm ); - // verify the factored form -// if ( !Dec_FactorVerify( pSop, pFForm ) ) -// printf( "Verification has failed.\n" ); -// Mvc_CoverInverse( pCover ); // undo CST - Mvc_CoverFree( pCover ); - return pFForm; -} - -/**Function************************************************************* - - Synopsis [Internal recursive factoring procedure.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Edge_t Dec_Factor_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover ) -{ - Mvc_Cover_t * pDiv, * pQuo, * pRem, * pCom; - Dec_Edge_t eNodeDiv, eNodeQuo, eNodeRem; - Dec_Edge_t eNodeAnd, eNode; - - // make sure the cover contains some cubes - assert( Mvc_CoverReadCubeNum(pCover) ); - - // get the divisor - pDiv = Mvc_CoverDivisor( pCover ); - if ( pDiv == NULL ) - return Dec_FactorTrivial( pFForm, pCover ); - - // divide the cover by the divisor - Mvc_CoverDivideInternal( pCover, pDiv, &pQuo, &pRem ); - assert( Mvc_CoverReadCubeNum(pQuo) ); - - Mvc_CoverFree( pDiv ); - Mvc_CoverFree( pRem ); - - // check the trivial case - if ( Mvc_CoverReadCubeNum(pQuo) == 1 ) - { - eNode = Dec_FactorLF_rec( pFForm, pCover, pQuo ); - Mvc_CoverFree( pQuo ); - return eNode; - } - - // make the quotient cube free - Mvc_CoverMakeCubeFree( pQuo ); - - // divide the cover by the quotient - Mvc_CoverDivideInternal( pCover, pQuo, &pDiv, &pRem ); - - // check the trivial case - if ( Mvc_CoverIsCubeFree( pDiv ) ) - { - eNodeDiv = Dec_Factor_rec( pFForm, pDiv ); - eNodeQuo = Dec_Factor_rec( pFForm, pQuo ); - Mvc_CoverFree( pDiv ); - Mvc_CoverFree( pQuo ); - eNodeAnd = Dec_GraphAddNodeAnd( pFForm, eNodeDiv, eNodeQuo ); - if ( Mvc_CoverReadCubeNum(pRem) == 0 ) - { - Mvc_CoverFree( pRem ); - return eNodeAnd; - } - else - { - eNodeRem = Dec_Factor_rec( pFForm, pRem ); - Mvc_CoverFree( pRem ); - return Dec_GraphAddNodeOr( pFForm, eNodeAnd, eNodeRem ); - } - } - - // get the common cube - pCom = Mvc_CoverCommonCubeCover( pDiv ); - Mvc_CoverFree( pDiv ); - Mvc_CoverFree( pQuo ); - Mvc_CoverFree( pRem ); - - // solve the simple problem - eNode = Dec_FactorLF_rec( pFForm, pCover, pCom ); - Mvc_CoverFree( pCom ); - return eNode; -} - - -/**Function************************************************************* - - Synopsis [Internal recursive factoring procedure for the leaf case.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Edge_t Dec_FactorLF_rec( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover, Mvc_Cover_t * pSimple ) -{ - Dec_Man_t * pManDec = Abc_FrameReadManDec(); - Vec_Int_t * vEdgeLits = pManDec->vLits; - Mvc_Cover_t * pDiv, * pQuo, * pRem; - Dec_Edge_t eNodeDiv, eNodeQuo, eNodeRem; - Dec_Edge_t eNodeAnd; - - // get the most often occurring literal - pDiv = Mvc_CoverBestLiteralCover( pCover, pSimple ); - // divide the cover by the literal - Mvc_CoverDivideByLiteral( pCover, pDiv, &pQuo, &pRem ); - // get the node pointer for the literal - eNodeDiv = Dec_FactorTrivialCube( pFForm, pDiv, Mvc_CoverReadCubeHead(pDiv), vEdgeLits ); - Mvc_CoverFree( pDiv ); - // factor the quotient and remainder - eNodeQuo = Dec_Factor_rec( pFForm, pQuo ); - Mvc_CoverFree( pQuo ); - eNodeAnd = Dec_GraphAddNodeAnd( pFForm, eNodeDiv, eNodeQuo ); - if ( Mvc_CoverReadCubeNum(pRem) == 0 ) - { - Mvc_CoverFree( pRem ); - return eNodeAnd; - } - else - { - eNodeRem = Dec_Factor_rec( pFForm, pRem ); - Mvc_CoverFree( pRem ); - return Dec_GraphAddNodeOr( pFForm, eNodeAnd, eNodeRem ); - } -} - - - -/**Function************************************************************* - - Synopsis [Factoring the cover, which has no algebraic divisors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Edge_t Dec_FactorTrivial( Dec_Graph_t * pFForm, Mvc_Cover_t * pCover ) -{ - Dec_Man_t * pManDec = Abc_FrameReadManDec(); - Vec_Int_t * vEdgeCubes = pManDec->vCubes; - Vec_Int_t * vEdgeLits = pManDec->vLits; - Mvc_Manager_t * pMem = pManDec->pMvcMem; - Dec_Edge_t eNode; - Mvc_Cube_t * pCube; - // create the factored form for each cube - Vec_IntClear( vEdgeCubes ); - Mvc_CoverForEachCube( pCover, pCube ) - { - eNode = Dec_FactorTrivialCube( pFForm, pCover, pCube, vEdgeLits ); - Vec_IntPush( vEdgeCubes, Dec_EdgeToInt_(eNode) ); - } - // balance the factored forms - return Dec_FactorTrivialTree_rec( pFForm, (Dec_Edge_t *)vEdgeCubes->pArray, vEdgeCubes->nSize, 1 ); -} - -/**Function************************************************************* - - Synopsis [Factoring the cube.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -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; - 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) ); - } - // balance the factored forms - return Dec_FactorTrivialTree_rec( pFForm, (Dec_Edge_t *)vEdgeLits->pArray, vEdgeLits->nSize, 0 ); -} - -/**Function************************************************************* - - Synopsis [Create the well-balanced tree of nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Edge_t Dec_FactorTrivialTree_rec( Dec_Graph_t * pFForm, Dec_Edge_t * peNodes, int nNodes, int fNodeOr ) -{ - Dec_Edge_t eNode1, eNode2; - int nNodes1, nNodes2; - - if ( nNodes == 1 ) - return peNodes[0]; - - // split the nodes into two parts - nNodes1 = nNodes/2; - nNodes2 = nNodes - nNodes1; -// nNodes2 = nNodes/2; -// nNodes1 = nNodes - nNodes2; - - // recursively construct the tree for the parts - eNode1 = Dec_FactorTrivialTree_rec( pFForm, peNodes, nNodes1, fNodeOr ); - eNode2 = Dec_FactorTrivialTree_rec( pFForm, peNodes + nNodes1, nNodes2, fNodeOr ); - - if ( fNodeOr ) - return Dec_GraphAddNodeOr( pFForm, eNode1, eNode2 ); - else - return Dec_GraphAddNodeAnd( pFForm, eNode1, eNode2 ); -} - - - -/**Function************************************************************* - - Synopsis [Converts SOP into MVC.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Mvc_Cover_t * Dec_ConvertSopToMvc( char * pSop ) -{ - Dec_Man_t * pManDec = Abc_FrameReadManDec(); - Mvc_Manager_t * pMem = pManDec->pMvcMem; - Mvc_Cover_t * pMvc; - Mvc_Cube_t * pMvcCube; - char * pCube; - int nVars, Value, v; - - // start the cover - nVars = Abc_SopGetVarNum(pSop); - pMvc = Mvc_CoverAlloc( pMem, nVars * 2 ); - // check the logic function of the node - Abc_SopForEachCube( pSop, nVars, pCube ) - { - // create and add the cube - pMvcCube = Mvc_CubeAlloc( pMvc ); - Mvc_CoverAddCubeTail( pMvc, pMvcCube ); - // fill in the literals - Mvc_CubeBitFill( pMvcCube ); - Abc_CubeForEachVar( pCube, Value, v ) - { - if ( Value == '0' ) - Mvc_CubeBitRemove( pMvcCube, v * 2 + 1 ); - else if ( Value == '1' ) - Mvc_CubeBitRemove( pMvcCube, v * 2 ); - } - } - return pMvc; -} - -/**Function************************************************************* - - Synopsis [Verifies that the factoring is correct.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Dec_FactorVerify( char * pSop, Dec_Graph_t * pFForm ) -{ - DdManager * dd = Abc_FrameReadManDd(); - DdNode * bFunc1, * bFunc2; - int RetValue; - bFunc1 = Abc_ConvertSopToBdd( dd, pSop ); Cudd_Ref( bFunc1 ); - bFunc2 = Dec_GraphDeriveBdd( dd, pFForm ); Cudd_Ref( bFunc2 ); -//Extra_bddPrint( dd, bFunc1 ); printf("\n"); -//Extra_bddPrint( dd, bFunc2 ); printf("\n"); - RetValue = (bFunc1 == bFunc2); - if ( bFunc1 != bFunc2 ) - { - int s; - Extra_bddPrint( dd, bFunc1 ); printf("\n"); - Extra_bddPrint( dd, bFunc2 ); printf("\n"); - s = 0; - } - Cudd_RecursiveDeref( dd, bFunc1 ); - Cudd_RecursiveDeref( dd, bFunc2 ); - return RetValue; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/dec/decMan.c b/src/opt/dec/decMan.c deleted file mode 100644 index 65857461..00000000 --- a/src/opt/dec/decMan.c +++ /dev/null @@ -1,83 +0,0 @@ -/**CFile**************************************************************** - - FileName [decMan.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Decomposition manager.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: decMan.c,v 1.1 2003/05/22 19:20:05 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "mvc.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Start the MVC manager used in the factoring package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Man_t * Dec_ManStart() -{ - Dec_Man_t * p; - int clk = clock(); - p = ALLOC( Dec_Man_t, 1 ); - p->pMvcMem = Mvc_ManagerStart(); - p->vCubes = Vec_IntAlloc( 8 ); - p->vLits = Vec_IntAlloc( 8 ); - // canonical forms, phases, perms - Extra_Truth4VarNPN( &p->puCanons, &p->pPhases, &p->pPerms, &p->pMap ); -//PRT( "NPN classes precomputation time", clock() - clk ); - return p; -} - -/**Function************************************************************* - - Synopsis [Stops the MVC maanager used in the factoring package.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Dec_ManStop( Dec_Man_t * p ) -{ - Mvc_ManagerFree( p->pMvcMem ); - Vec_IntFree( p->vCubes ); - Vec_IntFree( p->vLits ); - free( p->puCanons ); - free( p->pPhases ); - free( p->pPerms ); - free( p->pMap ); - free( p ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/dec/decPrint.c b/src/opt/dec/decPrint.c deleted file mode 100644 index 2d8f09b3..00000000 --- a/src/opt/dec/decPrint.c +++ /dev/null @@ -1,284 +0,0 @@ -/**CFile**************************************************************** - - FileName [decPrint.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Procedures to print the decomposition graphs (factored forms).] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: decPrint.c,v 1.1 2003/05/22 19:20:05 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Dec_GraphPrint_rec( FILE * pFile, Dec_Graph_t * pGraph, Dec_Node_t * pNode, int fCompl, char * pNamesIn[], int * pPos, int LitSizeMax ); -static int Dec_GraphPrintGetLeafName( FILE * pFile, int iLeaf, int fCompl, char * pNamesIn[] ); -static void Dec_GraphPrintUpdatePos( FILE * pFile, int * pPos, int LitSizeMax ); -static int Dec_GraphPrintOutputName( FILE * pFile, char * pNameOut, int fCompl ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Prints the decomposition graph.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Dec_GraphPrint( FILE * pFile, Dec_Graph_t * pGraph, char * pNamesIn[], char * pNameOut ) -{ - Vec_Ptr_t * vNamesIn = NULL; - int LitSizeMax, LitSizeCur, Pos, i; - - // create the names if not given by the user - if ( pNamesIn == NULL ) - { - vNamesIn = Abc_NodeGetFakeNames( Dec_GraphLeaveNum(pGraph) ); - pNamesIn = (char **)vNamesIn->pArray; - } - if ( pNameOut == NULL ) - pNameOut = "F"; - - // get the size of the longest literal - LitSizeMax = 0; - for ( i = 0; i < Dec_GraphLeaveNum(pGraph); i++ ) - { - LitSizeCur = strlen(pNamesIn[i]); - if ( LitSizeMax < LitSizeCur ) - LitSizeMax = LitSizeCur; - } - if ( LitSizeMax > 50 ) - LitSizeMax = 20; - - // write the decomposition graph (factored form) - if ( Dec_GraphIsConst(pGraph) ) // constant - { - Pos = Dec_GraphPrintOutputName( pFile, pNameOut, 0 ); - fprintf( pFile, "Constant %d", !Dec_GraphIsComplement(pGraph) ); - } - else if ( Dec_GraphIsVar(pGraph) ) // literal - { - Pos = Dec_GraphPrintOutputName( pFile, pNameOut, 0 ); - Dec_GraphPrintGetLeafName( pFile, Dec_GraphVarInt(pGraph), Dec_GraphIsComplement(pGraph), pNamesIn ); - } - else - { - Pos = Dec_GraphPrintOutputName( pFile, pNameOut, Dec_GraphIsComplement(pGraph) ); - Dec_GraphPrint_rec( pFile, pGraph, Dec_GraphNodeLast(pGraph), 0, pNamesIn, &Pos, LitSizeMax ); - } - fprintf( pFile, "\n" ); - - if ( vNamesIn ) - Abc_NodeFreeNames( vNamesIn ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Dec_GraphPrint2_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); - 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 ( !pNode->fNodeOr ) // FT_NODE_AND ) - { - if ( !pNode0->fNodeOr ) // != FT_NODE_OR ) - Dec_GraphPrint_rec( pFile, pGraph, pNode0, pNode->fCompl0, pNamesIn, pPos, LitSizeMax ); - else - { - fprintf( pFile, "(" ); - (*pPos)++; - Dec_GraphPrint_rec( pFile, pGraph, pNode0, pNode->fCompl0, pNamesIn, pPos, LitSizeMax ); - fprintf( pFile, ")" ); - (*pPos)++; - } - fprintf( pFile, " " ); - (*pPos)++; - - Dec_GraphPrintUpdatePos( pFile, pPos, LitSizeMax ); - - if ( !pNode1->fNodeOr ) // != FT_NODE_OR ) - Dec_GraphPrint_rec( pFile, pGraph, pNode1, pNode->fCompl1, pNamesIn, pPos, LitSizeMax ); - else - { - fprintf( pFile, "(" ); - (*pPos)++; - Dec_GraphPrint_rec( pFile, pGraph, pNode1, pNode->fCompl1, pNamesIn, pPos, LitSizeMax ); - fprintf( pFile, ")" ); - (*pPos)++; - } - return; - } - if ( pNode->fNodeOr ) // FT_NODE_OR ) - { - Dec_GraphPrint_rec( pFile, pGraph, pNode0, pNode->fCompl0, pNamesIn, pPos, LitSizeMax ); - fprintf( pFile, " + " ); - (*pPos) += 3; - - Dec_GraphPrintUpdatePos( pFile, pPos, LitSizeMax ); - - Dec_GraphPrint_rec( pFile, pGraph, pNode1, pNode->fCompl1, pNamesIn, pPos, LitSizeMax ); - return; - } - assert( 0 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - 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]; - sprintf( Buffer, "%s%s", pNamesIn[iLeaf], fCompl? "\'" : "" ); - fprintf( pFile, "%s", Buffer ); - return strlen( Buffer ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Dec_GraphPrintUpdatePos( FILE * pFile, int * pPos, int LitSizeMax ) -{ - int i; - if ( *pPos + LitSizeMax < 77 ) - return; - fprintf( pFile, "\n" ); - for ( i = 0; i < 10; i++ ) - fprintf( pFile, " " ); - *pPos = 10; -} - -/**Function************************************************************* - - Synopsis [Starts the printout for a decomposition graph.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Dec_GraphPrintOutputName( FILE * pFile, char * pNameOut, int fCompl ) -{ - if ( pNameOut == NULL ) - return 0; - fprintf( pFile, "%6s%s = ", pNameOut, fCompl? "\'" : " " ); - return 10; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/dec/decUtil.c b/src/opt/dec/decUtil.c deleted file mode 100644 index 463bc7e2..00000000 --- a/src/opt/dec/decUtil.c +++ /dev/null @@ -1,134 +0,0 @@ -/**CFile**************************************************************** - - FileName [decUtil.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Decomposition unitilies.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: decUtil.c,v 1.1 2003/05/22 19:20:05 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Converts graph to BDD.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -DdNode * Dec_GraphDeriveBdd( DdManager * dd, Dec_Graph_t * pGraph ) -{ - DdNode * bFunc, * bFunc0, * bFunc1; - Dec_Node_t * pNode; - int i; - - // sanity checks - assert( Dec_GraphLeaveNum(pGraph) >= 0 ); - assert( Dec_GraphLeaveNum(pGraph) <= pGraph->nSize ); - - // check for constant function - if ( Dec_GraphIsConst(pGraph) ) - return Cudd_NotCond( b1, Dec_GraphIsComplement(pGraph) ); - // check for a literal - if ( Dec_GraphIsVar(pGraph) ) - return Cudd_NotCond( Cudd_bddIthVar(dd, Dec_GraphVarInt(pGraph)), Dec_GraphIsComplement(pGraph) ); - - // assign the elementary variables - Dec_GraphForEachLeaf( pGraph, pNode, i ) - pNode->pFunc = Cudd_bddIthVar( dd, i ); - - // compute the function for each internal node - Dec_GraphForEachNode( pGraph, pNode, i ) - { - bFunc0 = Cudd_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); - bFunc1 = Cudd_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); - pNode->pFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( pNode->pFunc ); - } - - // deref the intermediate results - bFunc = pNode->pFunc; Cudd_Ref( bFunc ); - Dec_GraphForEachNode( pGraph, pNode, i ) - Cudd_RecursiveDeref( dd, pNode->pFunc ); - Cudd_Deref( bFunc ); - - // complement the result if necessary - return Cudd_NotCond( bFunc, Dec_GraphIsComplement(pGraph) ); -} - -/**Function************************************************************* - - Synopsis [Derives the truth table.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Dec_GraphDeriveTruth( Dec_Graph_t * pGraph ) -{ - unsigned uTruths[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; - unsigned uTruth, uTruth0, uTruth1; - Dec_Node_t * pNode; - int i; - - // sanity checks - assert( Dec_GraphLeaveNum(pGraph) >= 0 ); - assert( Dec_GraphLeaveNum(pGraph) <= pGraph->nSize ); - assert( Dec_GraphLeaveNum(pGraph) <= 5 ); - - // check for constant function - if ( Dec_GraphIsConst(pGraph) ) - return Dec_GraphIsComplement(pGraph)? 0 : ~((unsigned)0); - // check for a literal - if ( Dec_GraphIsVar(pGraph) ) - return Dec_GraphIsComplement(pGraph)? ~uTruths[Dec_GraphVarInt(pGraph)] : uTruths[Dec_GraphVarInt(pGraph)]; - - // assign the elementary variables - Dec_GraphForEachLeaf( pGraph, pNode, i ) - pNode->pFunc = (void *)uTruths[i]; - - // compute the function for each internal node - Dec_GraphForEachNode( pGraph, pNode, i ) - { - uTruth0 = (unsigned)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc; - uTruth1 = (unsigned)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc; - uTruth0 = pNode->eEdge0.fCompl? ~uTruth0 : uTruth0; - uTruth1 = pNode->eEdge1.fCompl? ~uTruth1 : uTruth1; - uTruth = uTruth0 & uTruth1; - pNode->pFunc = (void *)uTruth; - } - - // complement the result if necessary - return Dec_GraphIsComplement(pGraph)? ~uTruth : uTruth; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/dec/module.make b/src/opt/dec/module.make deleted file mode 100644 index 1e0722d5..00000000 --- a/src/opt/dec/module.make +++ /dev/null @@ -1,5 +0,0 @@ -SRC += src/opt/dec/decAbc.c \ - src/opt/dec/decFactor.c \ - src/opt/dec/decMan.c \ - src/opt/dec/decPrint.c \ - src/opt/dec/decUtil.c diff --git a/src/opt/fxu/fxu.c b/src/opt/fxu/fxu.c deleted file mode 100644 index d11fd793..00000000 --- a/src/opt/fxu/fxu.c +++ /dev/null @@ -1,254 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxu.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [The entrance into the fast extract module.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxu.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "fxuInt.h" -#include "fxu.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*===== fxuCreate.c ====================================================*/ -extern Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ); -extern void Fxu_CreateCovers( Fxu_Matrix * p, Fxu_Data_t * pData ); - -static int s_MemoryTotal; -static int s_MemoryPeak; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs fast_extract on a set of covers.] - - Description [All the covers are given in the array p->vSops. - The resulting covers are returned in the array p->vSopsNew. - The entries in these arrays correspond to objects in the network. - The entries corresponding to the PI and objects with trivial covers are NULL. - The number of extracted covers (not exceeding p->nNodesExt) is returned. - Two other things are important for the correct operation of this procedure: - (1) The input covers do not have duplicated fanins and are SCC-free. - (2) The fanins array contains the numbers of the fanin objects.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_FastExtract( Fxu_Data_t * pData ) -{ - Fxu_Matrix * p; - Fxu_Single * pSingle; - Fxu_Double * pDouble; - int Weight1, Weight2, Weight3; - int Counter = 0; - - s_MemoryTotal = 0; - s_MemoryPeak = 0; - - // create the matrix - p = Fxu_CreateMatrix( pData ); - if ( p == NULL ) - return -1; -// if ( pData->fVerbose ) -// printf( "Memory usage after construction: Total = %d. Peak = %d.\n", s_MemoryTotal, s_MemoryPeak ); -//Fxu_MatrixPrint( NULL, p ); - - if ( pData->fOnlyS ) - { - pData->nNodesNew = 0; - do - { - Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); - if ( pData->fVerbose ) - printf( "Div %5d : Best single = %5d.\r", Counter++, Weight1 ); - if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 ) - Fxu_UpdateSingle( p ); - else - break; - } - while ( ++pData->nNodesNew < pData->nNodesExt ); - } - else if ( pData->fOnlyD ) - { - pData->nNodesNew = 0; - do - { - Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); - if ( pData->fVerbose ) - printf( "Div %5d : Best double = %5d.\r", Counter++, Weight2 ); - if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 ) - Fxu_UpdateDouble( p ); - else - break; - } - while ( ++pData->nNodesNew < pData->nNodesExt ); - } - else if ( !pData->fUseCompl ) - { - pData->nNodesNew = 0; - do - { - Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); - Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); - - if ( pData->fVerbose ) - printf( "Div %5d : Best double = %5d. Best single = %5d.\r", Counter++, Weight2, Weight1 ); -//Fxu_Select( p, &pSingle, &pDouble ); - - if ( Weight1 >= Weight2 ) - { - if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 ) - Fxu_UpdateSingle( p ); - else - break; - } - else - { - if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 ) - Fxu_UpdateDouble( p ); - else - break; - } - } - while ( ++pData->nNodesNew < pData->nNodesExt ); - } - else - { // use the complement - pData->nNodesNew = 0; - do - { - Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); - Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); - - // 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 ); - - if ( Weight3 > 0 || Weight3 == 0 && pData->fUse0 ) - Fxu_Update( p, pSingle, pDouble ); - else - break; - } - while ( ++pData->nNodesNew < pData->nNodesExt ); - } - - if ( pData->fVerbose ) - 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 ); - if ( pData->nNodesNew == pData->nNodesExt ) - printf( "Warning: The limit on the number of extracted divisors has been reached.\n" ); - return pData->nNodesNew; -} - - -/**Function************************************************************* - - Synopsis [Unmarks the cubes in the ring.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixRingCubesUnmark( Fxu_Matrix * p ) -{ - Fxu_Cube * pCube, * pCube2; - // unmark the cubes - Fxu_MatrixForEachCubeInRingSafe( p, pCube, pCube2 ) - pCube->pOrder = NULL; - Fxu_MatrixRingCubesReset( p ); -} - - -/**Function************************************************************* - - Synopsis [Unmarks the vars in the ring.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixRingVarsUnmark( Fxu_Matrix * p ) -{ - Fxu_Var * pVar, * pVar2; - // unmark the vars - Fxu_MatrixForEachVarInRingSafe( p, pVar, pVar2 ) - pVar->pOrder = NULL; - Fxu_MatrixRingVarsReset( p ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Fxu_MemFetch( Fxu_Matrix * p, int nBytes ) -{ - s_MemoryTotal += nBytes; - if ( s_MemoryPeak < s_MemoryTotal ) - s_MemoryPeak = s_MemoryTotal; -// return malloc( nBytes ); - return Extra_MmFixedEntryFetch( p->pMemMan ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MemRecycle( Fxu_Matrix * p, char * pItem, int nBytes ) -{ - s_MemoryTotal -= nBytes; -// free( pItem ); - Extra_MmFixedEntryRecycle( p->pMemMan, pItem ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/fxu/fxu.h b/src/opt/fxu/fxu.h deleted file mode 100644 index e6d0b69e..00000000 --- a/src/opt/fxu/fxu.h +++ /dev/null @@ -1,93 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxu.h] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [External declarations of fast extract for unate covers.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxu.h,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __FXU_H__ -#define __FXU_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include "vec.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// STRUCTURE DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -#ifndef __cplusplus -#ifndef bool -#define bool int -#endif -#endif - -typedef struct FxuDataStruct Fxu_Data_t; - -// structure for the FX input/output data -struct FxuDataStruct -{ - // user specified parameters - bool fOnlyS; // set to 1 to have only single-cube divs - bool fOnlyD; // set to 1 to have only double-cube divs - bool fUse0; // set to 1 to have 0-weight also extracted - 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 - // 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 - // output information - Vec_Ptr_t * vSopsNew; // the SOPs for each node in the network after extraction - Vec_Ptr_t * vFaninsNew; // the fanins of each node in the network after extraction - // the SOP manager - Extra_MmFlex_t * pManSop; - // statistics - int nNodesOld; // the old number of nodes - int nNodesNew; // the number of divisors actually extracted -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/*===== fxu.c ==========================================================*/ -extern int Fxu_FastExtract( Fxu_Data_t * pData ); - -#ifdef __cplusplus -} -#endif - -#endif - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/fxu/fxuCreate.c b/src/opt/fxu/fxuCreate.c deleted file mode 100644 index e3300df9..00000000 --- a/src/opt/fxu/fxuCreate.c +++ /dev/null @@ -1,431 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuCreate.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Create matrix from covers and covers from matrix.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuCreate.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "fxuInt.h" -#include "fxu.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Int_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; - -extern int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Creates the sparse matrix from the array of SOPs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) -{ - Fxu_Matrix * p; - Fxu_Var * pVar; - Fxu_Cube * pCubeFirst, * pCubeNew; - Fxu_Cube * pCube1, * pCube2; - Vec_Int_t * vFanins; - char * pSopCover; - char * pSopCube; - int * pOrder, nBitsMax; - int i, v, c; - int nCubesTotal; - int nPairsTotal; - int nPairsStore; - int nCubes; - int iCube, iPair; - int nFanins; - - // collect all sorts of statistics - nCubesTotal = 0; - nPairsTotal = 0; - nPairsStore = 0; - nBitsMax = -1; - for ( i = 0; i < pData->nNodesOld; i++ ) - if ( pSopCover = pData->vSops->pArray[i] ) - { - nCubes = Abc_SopGetCubeNum( pSopCover ); - nFanins = Abc_SopGetVarNum( pSopCover ); - assert( nFanins > 1 && nCubes > 0 ); - - nCubesTotal += nCubes; - nPairsTotal += nCubes * (nCubes - 1) / 2; - nPairsStore += nCubes * nCubes; - if ( nBitsMax < nFanins ) - nBitsMax = nFanins; - } - if ( nBitsMax <= 0 ) - { - printf( "The current network does not have SOPs to perform extraction.\n" ); - return NULL; - } -/* - 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; - } -*/ - // start the matrix - p = Fxu_MatrixAllocate(); - // create the column labels - p->ppVars = ALLOC( Fxu_Var *, 2 * (pData->nNodesOld + pData->nNodesExt) ); - for ( i = 0; i < 2 * pData->nNodesOld; i++ ) - p->ppVars[i] = Fxu_MatrixAddVar( p ); - - // allocate storage for all cube pairs at once - p->pppPairs = ALLOC( Fxu_Pair **, nCubesTotal + 100 ); - p->ppPairs = ALLOC( Fxu_Pair *, nPairsStore + 100 ); - memset( p->ppPairs, 0, sizeof(Fxu_Pair *) * nPairsStore ); - iCube = 0; - iPair = 0; - for ( i = 0; i < pData->nNodesOld; i++ ) - if ( pSopCover = pData->vSops->pArray[i] ) - { - // get the number of cubes - nCubes = Abc_SopGetCubeNum( pSopCover ); - // get the new var in the matrix - pVar = p->ppVars[2*i+1]; - // assign the pair storage - pVar->nCubes = nCubes; - if ( nCubes > 0 ) - { - pVar->ppPairs = p->pppPairs + iCube; - pVar->ppPairs[0] = p->ppPairs + iPair; - for ( v = 1; v < nCubes; v++ ) - pVar->ppPairs[v] = pVar->ppPairs[v-1] + nCubes; - } - // update - iCube += nCubes; - iPair += nCubes * nCubes; - } - assert( iCube == nCubesTotal ); - assert( iPair == nPairsStore ); - - - // allocate room for the reordered literals - pOrder = ALLOC( int, nBitsMax ); - // create the rows - for ( i = 0; i < pData->nNodesOld; i++ ) - if ( pSopCover = pData->vSops->pArray[i] ) - { - // get the new var in the matrix - pVar = p->ppVars[2*i+1]; - // here we sort the literals of the cover - // in the increasing order of the numbers of the corresponding nodes - // because literals should be added to the matrix in this order - vFanins = pData->vFanins->pArray[i]; - s_pLits = vFanins->pArray; - // start the variable order - nFanins = Abc_SopGetVarNum( pSopCover ); - for ( v = 0; v < nFanins; v++ ) - 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] ] ); - // create the corresponding cubes in the matrix - pCubeFirst = NULL; - c = 0; - Abc_SopForEachCube( pSopCover, nFanins, pSopCube ) - { - // create the cube - pCubeNew = Fxu_MatrixAddCube( p, pVar, c++ ); - Fxu_CreateMatrixAddCube( p, pCubeNew, pSopCube, vFanins, pOrder ); - if ( pCubeFirst == NULL ) - pCubeFirst = pCubeNew; - pCubeNew->pFirst = pCubeFirst; - } - // set the first cube of this var - pVar->pFirst = pCubeFirst; - // create the divisors without preprocessing - if ( nPairsTotal <= pData->nPairsMax ) - { - for ( pCube1 = pCubeFirst; pCube1; pCube1 = pCube1->pNext ) - for ( pCube2 = pCube1? pCube1->pNext: NULL; pCube2; pCube2 = pCube2->pNext ) - Fxu_MatrixAddDivisor( p, pCube1, pCube2 ); - } - } - FREE( pOrder ); - - // 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 ); - - // add the var pairs to the heap - Fxu_MatrixComputeSingles( p, pData->fUse0, pData->nSingleMax ); - - // print stats - if ( pData->fVerbose ) - { - double Density; - Density = ((double)p->nEntries) / p->lVars.nItems / p->lCubes.nItems; - fprintf( stdout, "Matrix: [vars x cubes] = [%d x %d] ", - 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, "\n" ); - } -// Fxu_MatrixPrint( stdout, p ); - return p; -} - -/**Function************************************************************* - - Synopsis [Adds one cube with literals to the matrix.] - - Description [Create the cube and literals in the matrix corresponding - to the given cube in the SOP cover. Co-singleton transform is performed here.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_CreateMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube, char * pSopCube, Vec_Int_t * vFanins, int * pOrder ) -{ - Fxu_Var * pVar; - int Value, i; - // add literals to the matrix - Abc_CubeForEachVar( pSopCube, Value, i ) - { - Value = pSopCube[pOrder[i]]; - if ( Value == '0' ) - { - pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]] + 1 ]; // CST - Fxu_MatrixAddLiteral( p, pCube, pVar ); - } - else if ( Value == '1' ) - { - pVar = p->ppVars[ 2 * vFanins->pArray[pOrder[i]] ]; // CST - Fxu_MatrixAddLiteral( p, pCube, pVar ); - } - } -} - - -/**Function************************************************************* - - Synopsis [Creates the new array of Sop covers from the sparse matrix.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_CreateCovers( Fxu_Matrix * p, Fxu_Data_t * pData ) -{ - Fxu_Cube * pCube, * pCubeFirst, * pCubeNext; - char * pSopCover; - int iNode, n; - - // get the first cube of the first internal node - pCubeFirst = Fxu_CreateCoversFirstCube( p, pData, 0 ); - - // go through the internal nodes - for ( n = 0; n < pData->nNodesOld; n++ ) - if ( pSopCover = pData->vSops->pArray[n] ) - { - // get the number of this node - iNode = n; - // get the next first cube - pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 ); - // check if there any new variables in these cubes - for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext ) - if ( pCube->lLits.pTail && pCube->lLits.pTail->iVar >= 2 * pData->nNodesOld ) - break; - if ( pCube != pCubeNext ) - Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext ); - // update the first cube - pCubeFirst = pCubeNext; - } - - // add the covers for the extracted nodes - for ( n = 0; n < pData->nNodesNew; n++ ) - { - // get the number of this node - iNode = pData->nNodesOld + n; - // get the next first cube - pCubeNext = Fxu_CreateCoversFirstCube( p, pData, iNode + 1 ); - // the node should be added - Fxu_CreateCoversNode( p, pData, iNode, pCubeFirst, pCubeNext ); - // update the first cube - pCubeFirst = pCubeNext; - } -} - -/**Function************************************************************* - - Synopsis [Create Sop covers for one node that has changed.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_CreateCoversNode( Fxu_Matrix * p, Fxu_Data_t * pData, int iNode, Fxu_Cube * pCubeFirst, Fxu_Cube * pCubeNext ) -{ - Vec_Int_t * vInputsNew; - char * pSopCover, * pSopCube; - Fxu_Var * pVar; - Fxu_Cube * pCube; - Fxu_Lit * pLit; - int iNum, nCubes, v; - - // collect positive polarity variable in the cubes between pCubeFirst and pCubeNext - Fxu_MatrixRingVarsStart( p ); - for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext ) - for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext ) - { - pVar = p->ppVars[ 2 * (pLit->pVar->iVar/2) + 1 ]; - if ( pVar->pOrder == NULL ) - Fxu_MatrixRingVarsAdd( p, pVar ); - } - Fxu_MatrixRingVarsStop( p ); - - // collect the variable numbers - vInputsNew = Vec_IntAlloc( 4 ); - Fxu_MatrixForEachVarInRing( p, pVar ) - Vec_IntPush( vInputsNew, pVar->iVar / 2 ); - Fxu_MatrixRingVarsUnmark( p ); - - // sort the vars by their number - Vec_IntSort( vInputsNew, 0 ); - - // mark the vars with their numbers in the sorted array - for ( v = 0; v < vInputsNew->nSize; v++ ) - { - p->ppVars[ 2 * vInputsNew->pArray[v] + 0 ]->lLits.nItems = v; // hack - reuse lLits.nItems - p->ppVars[ 2 * vInputsNew->pArray[v] + 1 ]->lLits.nItems = v; // hack - reuse lLits.nItems - } - - // count the number of cubes - nCubes = 0; - for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext ) - if ( pCube->lLits.nItems ) - nCubes++; - - // allocate room for the new cover - pSopCover = Abc_SopStart( pData->pManSop, nCubes, vInputsNew->nSize ); - // set the correct polarity of the cover - if ( iNode < pData->nNodesOld && Abc_SopGetPhase( pData->vSops->pArray[iNode] ) == 0 ) - Abc_SopComplement( pSopCover ); - - // add the cubes - nCubes = 0; - for ( pCube = pCubeFirst; pCube != pCubeNext; pCube = pCube->pNext ) - { - if ( pCube->lLits.nItems == 0 ) - continue; - // get hold of the SOP cube - pSopCube = pSopCover + nCubes * (vInputsNew->nSize + 3); - // insert literals - for ( pLit = pCube->lLits.pHead; pLit; pLit = pLit->pHNext ) - { - iNum = pLit->pVar->lLits.nItems; // hack - reuse lLits.nItems - assert( iNum < vInputsNew->nSize ); - if ( pLit->pVar->iVar / 2 < pData->nNodesOld ) - pSopCube[iNum] = (pLit->pVar->iVar & 1)? '0' : '1'; // reverse CST - else - pSopCube[iNum] = (pLit->pVar->iVar & 1)? '1' : '0'; // no CST - } - // count the cube - nCubes++; - } - assert( nCubes == Abc_SopGetCubeNum(pSopCover) ); - - // set the new cover and the array of fanins - pData->vSopsNew->pArray[iNode] = pSopCover; - pData->vFaninsNew->pArray[iNode] = vInputsNew; -} - - -/**Function************************************************************* - - Synopsis [Adds the var to storage.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Cube * Fxu_CreateCoversFirstCube( Fxu_Matrix * p, Fxu_Data_t * pData, int iVar ) -{ - int v; - for ( v = iVar; v < pData->nNodesOld + pData->nNodesNew; v++ ) - if ( p->ppVars[ 2*v + 1 ]->pFirst ) - return p->ppVars[ 2*v + 1 ]->pFirst; - return NULL; -} - -/**Function************************************************************* - - Synopsis [Compares the vars by their number.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_CreateMatrixLitCompare( int * ptrX, int * ptrY ) -{ - return s_pLits[*ptrX] - s_pLits[*ptrY]; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// diff --git a/src/opt/fxu/fxuHeapD.c b/src/opt/fxu/fxuHeapD.c deleted file mode 100644 index c81ad818..00000000 --- a/src/opt/fxu/fxuHeapD.c +++ /dev/null @@ -1,445 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuHeapD.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [The priority queue for double cube divisors.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuHeapD.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "fxuInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define FXU_HEAP_DOUBLE_WEIGHT(pDiv) ((pDiv)->Weight) -#define FXU_HEAP_DOUBLE_CURRENT(p, pDiv) ((p)->pTree[(pDiv)->HNum]) -#define FXU_HEAP_DOUBLE_PARENT_EXISTS(p, pDiv) ((pDiv)->HNum > 1) -#define FXU_HEAP_DOUBLE_CHILD1_EXISTS(p, pDiv) (((pDiv)->HNum << 1) <= p->nItems) -#define FXU_HEAP_DOUBLE_CHILD2_EXISTS(p, pDiv) ((((pDiv)->HNum << 1)+1) <= p->nItems) -#define FXU_HEAP_DOUBLE_PARENT(p, pDiv) ((p)->pTree[(pDiv)->HNum >> 1]) -#define FXU_HEAP_DOUBLE_CHILD1(p, pDiv) ((p)->pTree[(pDiv)->HNum << 1]) -#define FXU_HEAP_DOUBLE_CHILD2(p, pDiv) ((p)->pTree[((pDiv)->HNum << 1)+1]) -#define FXU_HEAP_DOUBLE_ASSERT(p, pDiv) assert( (pDiv)->HNum >= 1 && (pDiv)->HNum <= p->nItemsAlloc ) - -static void Fxu_HeapDoubleResize( Fxu_HeapDouble * p ); -static void Fxu_HeapDoubleSwap( Fxu_Double ** pDiv1, Fxu_Double ** pDiv2 ); -static void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv ); -static void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_HeapDouble * Fxu_HeapDoubleStart() -{ - Fxu_HeapDouble * p; - p = ALLOC( Fxu_HeapDouble, 1 ); - memset( p, 0, sizeof(Fxu_HeapDouble) ); - p->nItems = 0; - p->nItemsAlloc = 10000; - p->pTree = ALLOC( Fxu_Double *, p->nItemsAlloc + 1 ); - p->pTree[0] = NULL; - return p; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoubleResize( Fxu_HeapDouble * p ) -{ - p->nItemsAlloc *= 2; - p->pTree = REALLOC( Fxu_Double *, p->pTree, p->nItemsAlloc + 1 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoubleStop( Fxu_HeapDouble * p ) -{ - free( p->pTree ); - free( p ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoublePrint( FILE * pFile, Fxu_HeapDouble * p ) -{ - Fxu_Double * pDiv; - int Counter = 1; - int Degree = 1; - - Fxu_HeapDoubleCheck( p ); - fprintf( pFile, "The contents of the heap:\n" ); - fprintf( pFile, "Level %d: ", Degree ); - Fxu_HeapDoubleForEachItem( p, pDiv ) - { - assert( Counter == p->pTree[Counter]->HNum ); - fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_DOUBLE_WEIGHT(p->pTree[Counter]) ); - if ( ++Counter == (1 << Degree) ) - { - fprintf( pFile, "\n" ); - Degree++; - fprintf( pFile, "Level %d: ", Degree ); - } - } - fprintf( pFile, "\n" ); - fprintf( pFile, "End of the heap printout.\n" ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoubleCheck( Fxu_HeapDouble * p ) -{ - Fxu_Double * pDiv; - Fxu_HeapDoubleForEachItem( p, pDiv ) - { - assert( pDiv->HNum == p->i ); - Fxu_HeapDoubleCheckOne( p, pDiv ); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoubleCheckOne( Fxu_HeapDouble * p, Fxu_Double * pDiv ) -{ - int Weight1, Weight2; - if ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,pDiv) ) - { - Weight1 = FXU_HEAP_DOUBLE_WEIGHT(pDiv); - Weight2 = FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD1(p,pDiv) ); - assert( Weight1 >= Weight2 ); - } - if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,pDiv) ) - { - Weight1 = FXU_HEAP_DOUBLE_WEIGHT(pDiv); - Weight2 = FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD2(p,pDiv) ); - assert( Weight1 >= Weight2 ); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoubleInsert( Fxu_HeapDouble * p, Fxu_Double * pDiv ) -{ - if ( p->nItems == p->nItemsAlloc ) - Fxu_HeapDoubleResize( p ); - // put the last entry to the last place and move up - p->pTree[++p->nItems] = pDiv; - pDiv->HNum = p->nItems; - // move the last entry up if necessary - Fxu_HeapDoubleMoveUp( p, pDiv ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoubleUpdate( Fxu_HeapDouble * p, Fxu_Double * pDiv ) -{ -//printf( "Updating divisor %d.\n", pDiv->Num ); - - FXU_HEAP_DOUBLE_ASSERT(p,pDiv); - if ( FXU_HEAP_DOUBLE_PARENT_EXISTS(p,pDiv) && - FXU_HEAP_DOUBLE_WEIGHT(pDiv) > FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_PARENT(p,pDiv) ) ) - Fxu_HeapDoubleMoveUp( p, pDiv ); - else if ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,pDiv) && - FXU_HEAP_DOUBLE_WEIGHT(pDiv) < FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD1(p,pDiv) ) ) - Fxu_HeapDoubleMoveDn( p, pDiv ); - else if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,pDiv) && - FXU_HEAP_DOUBLE_WEIGHT(pDiv) < FXU_HEAP_DOUBLE_WEIGHT( FXU_HEAP_DOUBLE_CHILD2(p,pDiv) ) ) - Fxu_HeapDoubleMoveDn( p, pDiv ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoubleDelete( Fxu_HeapDouble * p, Fxu_Double * pDiv ) -{ - FXU_HEAP_DOUBLE_ASSERT(p,pDiv); - // put the last entry to the deleted place - // decrement the number of entries - p->pTree[pDiv->HNum] = p->pTree[p->nItems--]; - p->pTree[pDiv->HNum]->HNum = pDiv->HNum; - // move the top entry down if necessary - Fxu_HeapDoubleUpdate( p, p->pTree[pDiv->HNum] ); - pDiv->HNum = 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Double * Fxu_HeapDoubleReadMax( Fxu_HeapDouble * p ) -{ - if ( p->nItems == 0 ) - return NULL; - return p->pTree[1]; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Double * Fxu_HeapDoubleGetMax( Fxu_HeapDouble * p ) -{ - Fxu_Double * pDiv; - if ( p->nItems == 0 ) - return NULL; - // prepare the return value - pDiv = p->pTree[1]; - pDiv->HNum = 0; - // put the last entry on top - // decrement the number of entries - p->pTree[1] = p->pTree[p->nItems--]; - p->pTree[1]->HNum = 1; - // move the top entry down if necessary - Fxu_HeapDoubleMoveDn( p, p->pTree[1] ); - return pDiv; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_HeapDoubleReadMaxWeight( Fxu_HeapDouble * p ) -{ - if ( p->nItems == 0 ) - return -1; - else - return FXU_HEAP_DOUBLE_WEIGHT(p->pTree[1]); -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoubleSwap( Fxu_Double ** pDiv1, Fxu_Double ** pDiv2 ) -{ - Fxu_Double * pDiv; - int Temp; - pDiv = *pDiv1; - *pDiv1 = *pDiv2; - *pDiv2 = pDiv; - Temp = (*pDiv1)->HNum; - (*pDiv1)->HNum = (*pDiv2)->HNum; - (*pDiv2)->HNum = Temp; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoubleMoveUp( Fxu_HeapDouble * p, Fxu_Double * pDiv ) -{ - Fxu_Double ** ppDiv, ** ppPar; - ppDiv = &FXU_HEAP_DOUBLE_CURRENT(p, pDiv); - while ( FXU_HEAP_DOUBLE_PARENT_EXISTS(p,*ppDiv) ) - { - ppPar = &FXU_HEAP_DOUBLE_PARENT(p,*ppDiv); - if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) > FXU_HEAP_DOUBLE_WEIGHT(*ppPar) ) - { - Fxu_HeapDoubleSwap( ppDiv, ppPar ); - ppDiv = ppPar; - } - else - break; - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapDoubleMoveDn( Fxu_HeapDouble * p, Fxu_Double * pDiv ) -{ - Fxu_Double ** ppChild1, ** ppChild2, ** ppDiv; - ppDiv = &FXU_HEAP_DOUBLE_CURRENT(p, pDiv); - while ( FXU_HEAP_DOUBLE_CHILD1_EXISTS(p,*ppDiv) ) - { // if Child1 does not exist, Child2 also does not exists - - // get the children - ppChild1 = &FXU_HEAP_DOUBLE_CHILD1(p,*ppDiv); - if ( FXU_HEAP_DOUBLE_CHILD2_EXISTS(p,*ppDiv) ) - { - ppChild2 = &FXU_HEAP_DOUBLE_CHILD2(p,*ppDiv); - - // consider two cases - if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) && - FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild2) ) - { // Div is larger than both, skip - break; - } - else - { // Div is smaller than one of them, then swap it with larger - if ( FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild2) ) - { - Fxu_HeapDoubleSwap( ppDiv, ppChild1 ); - // update the pointer - ppDiv = ppChild1; - } - else - { - Fxu_HeapDoubleSwap( ppDiv, ppChild2 ); - // update the pointer - ppDiv = ppChild2; - } - } - } - else // Child2 does not exist - { - // consider two cases - if ( FXU_HEAP_DOUBLE_WEIGHT(*ppDiv) >= FXU_HEAP_DOUBLE_WEIGHT(*ppChild1) ) - { // Div is larger than Child1, skip - break; - } - else - { // Div is smaller than Child1, then swap them - Fxu_HeapDoubleSwap( ppDiv, ppChild1 ); - // update the pointer - ppDiv = ppChild1; - } - } - } -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/fxu/fxuHeapS.c b/src/opt/fxu/fxuHeapS.c deleted file mode 100644 index eaca8363..00000000 --- a/src/opt/fxu/fxuHeapS.c +++ /dev/null @@ -1,444 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuHeapS.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [The priority queue for variables.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuHeapS.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "fxuInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define FXU_HEAP_SINGLE_WEIGHT(pSingle) ((pSingle)->Weight) -#define FXU_HEAP_SINGLE_CURRENT(p, pSingle) ((p)->pTree[(pSingle)->HNum]) -#define FXU_HEAP_SINGLE_PARENT_EXISTS(p, pSingle) ((pSingle)->HNum > 1) -#define FXU_HEAP_SINGLE_CHILD1_EXISTS(p, pSingle) (((pSingle)->HNum << 1) <= p->nItems) -#define FXU_HEAP_SINGLE_CHILD2_EXISTS(p, pSingle) ((((pSingle)->HNum << 1)+1) <= p->nItems) -#define FXU_HEAP_SINGLE_PARENT(p, pSingle) ((p)->pTree[(pSingle)->HNum >> 1]) -#define FXU_HEAP_SINGLE_CHILD1(p, pSingle) ((p)->pTree[(pSingle)->HNum << 1]) -#define FXU_HEAP_SINGLE_CHILD2(p, pSingle) ((p)->pTree[((pSingle)->HNum << 1)+1]) -#define FXU_HEAP_SINGLE_ASSERT(p, pSingle) assert( (pSingle)->HNum >= 1 && (pSingle)->HNum <= p->nItemsAlloc ) - -static void Fxu_HeapSingleResize( Fxu_HeapSingle * p ); -static void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 ); -static void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle ); -static void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_HeapSingle * Fxu_HeapSingleStart() -{ - Fxu_HeapSingle * p; - p = ALLOC( Fxu_HeapSingle, 1 ); - memset( p, 0, sizeof(Fxu_HeapSingle) ); - p->nItems = 0; - p->nItemsAlloc = 2000; - p->pTree = ALLOC( Fxu_Single *, p->nItemsAlloc + 10 ); - p->pTree[0] = NULL; - return p; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSingleResize( Fxu_HeapSingle * p ) -{ - p->nItemsAlloc *= 2; - p->pTree = REALLOC( Fxu_Single *, p->pTree, p->nItemsAlloc + 10 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSingleStop( Fxu_HeapSingle * p ) -{ - int i; - i = 0; - free( p->pTree ); - i = 1; - free( p ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p ) -{ - Fxu_Single * pSingle; - int Counter = 1; - int Degree = 1; - - Fxu_HeapSingleCheck( p ); - fprintf( pFile, "The contents of the heap:\n" ); - fprintf( pFile, "Level %d: ", Degree ); - Fxu_HeapSingleForEachItem( p, pSingle ) - { - assert( Counter == p->pTree[Counter]->HNum ); - fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_SINGLE_WEIGHT(p->pTree[Counter]) ); - if ( ++Counter == (1 << Degree) ) - { - fprintf( pFile, "\n" ); - Degree++; - fprintf( pFile, "Level %d: ", Degree ); - } - } - fprintf( pFile, "\n" ); - fprintf( pFile, "End of the heap printout.\n" ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSingleCheck( Fxu_HeapSingle * p ) -{ - Fxu_Single * pSingle; - Fxu_HeapSingleForEachItem( p, pSingle ) - { - assert( pSingle->HNum == p->i ); - Fxu_HeapSingleCheckOne( p, pSingle ); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle ) -{ - int Weight1, Weight2; - if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) ) - { - Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle); - Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) ); - assert( Weight1 >= Weight2 ); - } - if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) ) - { - Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle); - Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) ); - assert( Weight1 >= Weight2 ); - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle ) -{ - if ( p->nItems == p->nItemsAlloc ) - Fxu_HeapSingleResize( p ); - // put the last entry to the last place and move up - p->pTree[++p->nItems] = pSingle; - pSingle->HNum = p->nItems; - // move the last entry up if necessary - Fxu_HeapSingleMoveUp( p, pSingle ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle ) -{ - FXU_HEAP_SINGLE_ASSERT(p,pSingle); - if ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,pSingle) && - FXU_HEAP_SINGLE_WEIGHT(pSingle) > FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_PARENT(p,pSingle) ) ) - Fxu_HeapSingleMoveUp( p, pSingle ); - else if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) && - FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) ) ) - Fxu_HeapSingleMoveDn( p, pSingle ); - else if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) && - FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) ) ) - Fxu_HeapSingleMoveDn( p, pSingle ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle ) -{ - int Place = pSingle->HNum; - FXU_HEAP_SINGLE_ASSERT(p,pSingle); - // put the last entry to the deleted place - // decrement the number of entries - p->pTree[Place] = p->pTree[p->nItems--]; - p->pTree[Place]->HNum = Place; - // move the top entry down if necessary - Fxu_HeapSingleUpdate( p, p->pTree[Place] ); - pSingle->HNum = 0; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p ) -{ - if ( p->nItems == 0 ) - return NULL; - return p->pTree[1]; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p ) -{ - Fxu_Single * pSingle; - if ( p->nItems == 0 ) - return NULL; - // prepare the return value - pSingle = p->pTree[1]; - pSingle->HNum = 0; - // put the last entry on top - // decrement the number of entries - p->pTree[1] = p->pTree[p->nItems--]; - p->pTree[1]->HNum = 1; - // move the top entry down if necessary - Fxu_HeapSingleMoveDn( p, p->pTree[1] ); - return pSingle; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p ) -{ - if ( p->nItems == 0 ) - return -1; - return FXU_HEAP_SINGLE_WEIGHT(p->pTree[1]); -} - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 ) -{ - Fxu_Single * pSingle; - int Temp; - pSingle = *pSingle1; - *pSingle1 = *pSingle2; - *pSingle2 = pSingle; - Temp = (*pSingle1)->HNum; - (*pSingle1)->HNum = (*pSingle2)->HNum; - (*pSingle2)->HNum = Temp; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle ) -{ - Fxu_Single ** ppSingle, ** ppPar; - ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle); - while ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,*ppSingle) ) - { - ppPar = &FXU_HEAP_SINGLE_PARENT(p,*ppSingle); - if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) > FXU_HEAP_SINGLE_WEIGHT(*ppPar) ) - { - Fxu_HeapSingleSwap( ppSingle, ppPar ); - ppSingle = ppPar; - } - else - break; - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle ) -{ - Fxu_Single ** ppChild1, ** ppChild2, ** ppSingle; - ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle); - while ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,*ppSingle) ) - { // if Child1 does not exist, Child2 also does not exists - - // get the children - ppChild1 = &FXU_HEAP_SINGLE_CHILD1(p,*ppSingle); - if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,*ppSingle) ) - { - ppChild2 = &FXU_HEAP_SINGLE_CHILD2(p,*ppSingle); - - // consider two cases - if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) && - FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) ) - { // Var is larger than both, skip - break; - } - else - { // Var is smaller than one of them, then swap it with larger - if ( FXU_HEAP_SINGLE_WEIGHT(*ppChild1) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) ) - { - Fxu_HeapSingleSwap( ppSingle, ppChild1 ); - // update the pointer - ppSingle = ppChild1; - } - else - { - Fxu_HeapSingleSwap( ppSingle, ppChild2 ); - // update the pointer - ppSingle = ppChild2; - } - } - } - else // Child2 does not exist - { - // consider two cases - if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) ) - { // Var is larger than Child1, skip - break; - } - else - { // Var is smaller than Child1, then swap them - Fxu_HeapSingleSwap( ppSingle, ppChild1 ); - // update the pointer - ppSingle = ppChild1; - } - } - } -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// diff --git a/src/opt/fxu/fxuInt.h b/src/opt/fxu/fxuInt.h deleted file mode 100644 index ea85cb79..00000000 --- a/src/opt/fxu/fxuInt.h +++ /dev/null @@ -1,539 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuInt.h] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Internal declarations of fast extract for unate covers.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuInt.h,v 1.3 2003/04/10 05:42:44 donald Exp $] - -***********************************************************************/ - -#ifndef __FXU_INT_H__ -#define __FXU_INT_H__ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include "extra.h" -#include "vec.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -// uncomment this macro to switch to standard memory management -//#define USE_SYSTEM_MEMORY_MANAGEMENT - -//////////////////////////////////////////////////////////////////////// -/// STRUCTURE DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/* - Here is an informal description of the FX data structure. - (1) The sparse matrix is filled with literals, associated with - cubes (row) and variables (columns). The matrix contains - all the cubes of all the nodes in the network. - (2) A cube is associated with - (a) its literals in the matrix, - (b) the output variable of the node, to which this cube belongs, - (3) A variable is associated with - (a) its literals in the matrix and - (b) the list of cube pairs in the cover, for which it is the output - (4) A cube pair is associated with two cubes and contains the counters - of literals in the base and in the cubes without the base - (5) A double-cube divisor is associated with list of all cube pairs - that produce it and its current weight (which is updated automatically - each time a new pair is added or an old pair is removed). - (6) A single-cube divisor is associated the pair of variables. -*/ - -// sparse matrix -typedef struct FxuMatrix Fxu_Matrix; // the sparse matrix - -// sparse matrix contents: cubes (rows), vars (columns), literals (entries) -typedef struct FxuCube Fxu_Cube; // one cube in the sparse matrix -typedef struct FxuVar Fxu_Var; // one literal in the sparse matrix -typedef struct FxuLit Fxu_Lit; // one entry in the sparse matrix - -// double cube divisors -typedef struct FxuPair Fxu_Pair; // the pair of cubes -typedef struct FxuDouble Fxu_Double; // the double-cube divisor -typedef struct FxuSingle Fxu_Single; // the two-literal single-cube divisor - -// various lists -typedef struct FxuListCube Fxu_ListCube; // the list of cubes -typedef struct FxuListVar Fxu_ListVar; // the list of literals -typedef struct FxuListLit Fxu_ListLit; // the list of entries -typedef struct FxuListPair Fxu_ListPair; // the list of pairs -typedef struct FxuListDouble Fxu_ListDouble; // the list of divisors -typedef struct FxuListSingle Fxu_ListSingle; // the list of single-cube divisors - -// various heaps -typedef struct FxuHeapDouble Fxu_HeapDouble; // the heap of divisors -typedef struct FxuHeapSingle Fxu_HeapSingle; // the heap of variables - - -// various lists - -// the list of cubes in the sparse matrix -struct FxuListCube -{ - Fxu_Cube * pHead; - Fxu_Cube * pTail; - int nItems; -}; - -// the list of literals in the sparse matrix -struct FxuListVar -{ - Fxu_Var * pHead; - Fxu_Var * pTail; - int nItems; -}; - -// the list of entries in the sparse matrix -struct FxuListLit -{ - Fxu_Lit * pHead; - Fxu_Lit * pTail; - int nItems; -}; - -// the list of cube pair in the sparse matrix -struct FxuListPair -{ - Fxu_Pair * pHead; - Fxu_Pair * pTail; - int nItems; -}; - -// the list of divisors in the sparse matrix -struct FxuListDouble -{ - Fxu_Double * pHead; - Fxu_Double * pTail; - int nItems; -}; - -// the list of divisors in the sparse matrix -struct FxuListSingle -{ - Fxu_Single * pHead; - Fxu_Single * pTail; - int nItems; -}; - - -// various heaps - -// the heap of double cube divisors by weight -struct FxuHeapDouble -{ - Fxu_Double ** pTree; - int nItems; - int nItemsAlloc; - int i; -}; - -// the heap of variable by their occurrence in the cubes -struct FxuHeapSingle -{ - Fxu_Single ** pTree; - int nItems; - int nItemsAlloc; - int i; -}; - - - -// sparse matrix -struct FxuMatrix // ~ 30 words -{ - // the cubes - Fxu_ListCube lCubes; // the double linked list of cubes - // the values (binary literals) - Fxu_ListVar lVars; // the double linked list of variables - Fxu_Var ** ppVars; // the array of variables - // the double cube divisors - Fxu_ListDouble * pTable; // the hash table of divisors - int nTableSize; // the hash table size - int nDivs; // the number of divisors in the table - int nDivsTotal; // the number of divisors in the table - Fxu_HeapDouble * pHeapDouble; // the heap of divisors by weight - // 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; - // temporary storage for cubes - Fxu_Cube * pOrderCubes; - Fxu_Cube ** ppTailCubes; - // temporary storage for variables - Fxu_Var * pOrderVars; - Fxu_Var ** ppTailVars; - // temporary storage for pairs - Vec_Ptr_t * vPairs; - // statistics - int nEntries; // the total number of entries in the sparse matrix - int nDivs1; // the single cube divisors taken - int nDivs2; // the double cube divisors taken - int nDivs3; // the double cube divisors with complement - // memory manager - Extra_MmFixed_t * pMemMan; // the memory manager for all small sized entries -}; - -// the cube in the sparse matrix -struct FxuCube // 9 words -{ - int iCube; // the number of this cube in the cover - Fxu_Cube * pFirst; // the pointer to the first cube of this cover - Fxu_Var * pVar; // the variable representing the output of the cover - Fxu_ListLit lLits; // the row in the table - Fxu_Cube * pPrev; // the previous cube - Fxu_Cube * pNext; // the next cube - Fxu_Cube * pOrder; // the specialized linked list of cubes -}; - -// the variable in the sparse matrix -struct FxuVar // 10 words -{ - int iVar; // the number of this variable - int nCubes; // the number of cubes assoc with this var - Fxu_Cube * pFirst; // the first cube assoc with this var - Fxu_Pair *** ppPairs; // the pairs of cubes assoc with this var - Fxu_ListLit lLits; // the column in the table - Fxu_Var * pPrev; // the previous variable - Fxu_Var * pNext; // the next variable - Fxu_Var * pOrder; // the specialized linked list of variables -}; - -// the literal entry in the sparse matrix -struct FxuLit // 8 words -{ - int iVar; // the number of this variable - int iCube; // the number of this cube - Fxu_Cube * pCube; // the cube of this literal - Fxu_Var * pVar; // the variable of this literal - Fxu_Lit * pHPrev; // prev lit in the cube - Fxu_Lit * pHNext; // next lit in the cube - Fxu_Lit * pVPrev; // prev lit of the var - Fxu_Lit * pVNext; // next lit of the var -}; - -// the cube pair -struct FxuPair // 10 words -{ - int nLits1; // the number of literals in the two cubes - int nLits2; // the number of literals in the two cubes - int nBase; // the number of literals in the base - Fxu_Double * pDiv; // the divisor of this pair - Fxu_Cube * pCube1; // the first cube of the pair - Fxu_Cube * pCube2; // the second cube of the pair - int iCube1; // the first cube of the pair - int iCube2; // the second cube of the pair - Fxu_Pair * pDPrev; // the previous pair in the divisor - Fxu_Pair * pDNext; // the next pair in the divisor -}; - -// the double cube divisor -struct FxuDouble // 10 words -{ - int Num; // the unique number of this divisor - int HNum; // the heap number of this divisor - int Weight; // the weight of this divisor - unsigned Key; // the hash key of this divisor - Fxu_ListPair lPairs; // the pairs of cubes, which produce this divisor - Fxu_Double * pPrev; // the previous divisor in the table - Fxu_Double * pNext; // the next divisor in the table - Fxu_Double * pOrder; // the specialized linked list of divisors -}; - -// the single cube divisor -struct FxuSingle // 7 words -{ - int Num; // the unique number of this divisor - int HNum; // the heap number of this divisor - int Weight; // the weight of this divisor - Fxu_Var * pVar1; // the first variable of the single-cube divisor - Fxu_Var * pVar2; // the second variable of the single-cube divisor - Fxu_Single * pPrev; // the previous divisor in the list - Fxu_Single * pNext; // the next divisor in the list -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -// minimum/maximum -#define Fxu_Min( a, b ) ( ((a)<(b))? (a):(b) ) -#define Fxu_Max( a, b ) ( ((a)>(b))? (a):(b) ) - -// selection of the minimum/maximum cube in the pair -#define Fxu_PairMinCube( pPair ) (((pPair)->iCube1 < (pPair)->iCube2)? (pPair)->pCube1: (pPair)->pCube2) -#define Fxu_PairMaxCube( pPair ) (((pPair)->iCube1 > (pPair)->iCube2)? (pPair)->pCube1: (pPair)->pCube2) -#define Fxu_PairMinCubeInt( pPair ) (((pPair)->iCube1 < (pPair)->iCube2)? (pPair)->iCube1: (pPair)->iCube2) -#define Fxu_PairMaxCubeInt( pPair ) (((pPair)->iCube1 > (pPair)->iCube2)? (pPair)->iCube1: (pPair)->iCube2) - -// iterators - -#define Fxu_MatrixForEachCube( Matrix, Cube )\ - for ( Cube = (Matrix)->lCubes.pHead;\ - Cube;\ - Cube = Cube->pNext ) -#define Fxu_MatrixForEachCubeSafe( Matrix, Cube, Cube2 )\ - for ( Cube = (Matrix)->lCubes.pHead, Cube2 = (Cube? Cube->pNext: NULL);\ - Cube;\ - Cube = Cube2, Cube2 = (Cube? Cube->pNext: NULL) ) - -#define Fxu_MatrixForEachVariable( Matrix, Var )\ - for ( Var = (Matrix)->lVars.pHead;\ - Var;\ - Var = Var->pNext ) -#define Fxu_MatrixForEachVariableSafe( Matrix, Var, Var2 )\ - for ( Var = (Matrix)->lVars.pHead, Var2 = (Var? Var->pNext: NULL);\ - Var;\ - Var = Var2, Var2 = (Var? Var->pNext: NULL) ) - -#define Fxu_MatrixForEachSingle( Matrix, Single )\ - for ( Single = (Matrix)->lSingles.pHead;\ - Single;\ - Single = Single->pNext ) -#define Fxu_MatrixForEachSingleSafe( Matrix, Single, Single2 )\ - for ( Single = (Matrix)->lSingles.pHead, Single2 = (Single? Single->pNext: NULL);\ - Single;\ - Single = Single2, Single2 = (Single? Single->pNext: NULL) ) - -#define Fxu_TableForEachDouble( Matrix, Key, Div )\ - for ( Div = (Matrix)->pTable[Key].pHead;\ - Div;\ - Div = Div->pNext ) -#define Fxu_TableForEachDoubleSafe( Matrix, Key, Div, Div2 )\ - for ( Div = (Matrix)->pTable[Key].pHead, Div2 = (Div? Div->pNext: NULL);\ - Div;\ - Div = Div2, Div2 = (Div? Div->pNext: NULL) ) - -#define Fxu_MatrixForEachDouble( Matrix, Div, Index )\ - for ( Index = 0; Index < (Matrix)->nTableSize; Index++ )\ - Fxu_TableForEachDouble( Matrix, Index, Div ) -#define Fxu_MatrixForEachDoubleSafe( Matrix, Div, Div2, Index )\ - for ( Index = 0; Index < (Matrix)->nTableSize; Index++ )\ - Fxu_TableForEachDoubleSafe( Matrix, Index, Div, Div2 ) - - -#define Fxu_CubeForEachLiteral( Cube, Lit )\ - for ( Lit = (Cube)->lLits.pHead;\ - Lit;\ - Lit = Lit->pHNext ) -#define Fxu_CubeForEachLiteralSafe( Cube, Lit, Lit2 )\ - for ( Lit = (Cube)->lLits.pHead, Lit2 = (Lit? Lit->pHNext: NULL);\ - Lit;\ - Lit = Lit2, Lit2 = (Lit? Lit->pHNext: NULL) ) - -#define Fxu_VarForEachLiteral( Var, Lit )\ - for ( Lit = (Var)->lLits.pHead;\ - Lit;\ - Lit = Lit->pVNext ) - -#define Fxu_CubeForEachDivisor( Cube, Div )\ - for ( Div = (Cube)->lDivs.pHead;\ - Div;\ - Div = Div->pCNext ) - -#define Fxu_DoubleForEachPair( Div, Pair )\ - for ( Pair = (Div)->lPairs.pHead;\ - Pair;\ - Pair = Pair->pDNext ) -#define Fxu_DoubleForEachPairSafe( Div, Pair, Pair2 )\ - for ( Pair = (Div)->lPairs.pHead, Pair2 = (Pair? Pair->pDNext: NULL);\ - Pair;\ - Pair = Pair2, Pair2 = (Pair? Pair->pDNext: NULL) ) - - -// iterator through the cube pairs belonging to the given cube -#define Fxu_CubeForEachPair( pCube, pPair, i )\ - for ( i = 0;\ - i < pCube->pVar->nCubes &&\ - (((unsigned)(pPair = pCube->pVar->ppPairs[pCube->iCube][i])) >= 0);\ - i++ )\ - if ( pPair ) - -// iterator through all the items in the heap -#define Fxu_HeapDoubleForEachItem( Heap, Div )\ - for ( Heap->i = 1;\ - Heap->i <= Heap->nItems && (Div = Heap->pTree[Heap->i]);\ - Heap->i++ ) -#define Fxu_HeapSingleForEachItem( Heap, Single )\ - for ( Heap->i = 1;\ - Heap->i <= Heap->nItems && (Single = Heap->pTree[Heap->i]);\ - Heap->i++ ) - -// starting the rings -#define Fxu_MatrixRingCubesStart( Matrix ) (((Matrix)->ppTailCubes = &((Matrix)->pOrderCubes)), ((Matrix)->pOrderCubes = NULL)) -#define Fxu_MatrixRingVarsStart( Matrix ) (((Matrix)->ppTailVars = &((Matrix)->pOrderVars)), ((Matrix)->pOrderVars = NULL)) -// stopping the rings -#define Fxu_MatrixRingCubesStop( Matrix ) -#define Fxu_MatrixRingVarsStop( Matrix ) -// resetting the rings -#define Fxu_MatrixRingCubesReset( Matrix ) (((Matrix)->pOrderCubes = NULL), ((Matrix)->ppTailCubes = NULL)) -#define Fxu_MatrixRingVarsReset( Matrix ) (((Matrix)->pOrderVars = NULL), ((Matrix)->ppTailVars = NULL)) -// adding to the rings -#define Fxu_MatrixRingCubesAdd( Matrix, Cube) ((*((Matrix)->ppTailCubes) = Cube), ((Matrix)->ppTailCubes = &(Cube)->pOrder), ((Cube)->pOrder = (Fxu_Cube *)1)) -#define Fxu_MatrixRingVarsAdd( Matrix, Var ) ((*((Matrix)->ppTailVars ) = Var ), ((Matrix)->ppTailVars = &(Var)->pOrder ), ((Var)->pOrder = (Fxu_Var *)1)) -// iterating through the rings -#define Fxu_MatrixForEachCubeInRing( Matrix, Cube )\ - if ( (Matrix)->pOrderCubes )\ - for ( Cube = (Matrix)->pOrderCubes;\ - Cube != (Fxu_Cube *)1;\ - Cube = Cube->pOrder ) -#define Fxu_MatrixForEachCubeInRingSafe( Matrix, Cube, Cube2 )\ - if ( (Matrix)->pOrderCubes )\ - for ( Cube = (Matrix)->pOrderCubes, Cube2 = ((Cube != (Fxu_Cube *)1)? Cube->pOrder: (Fxu_Cube *)1);\ - Cube != (Fxu_Cube *)1;\ - Cube = Cube2, Cube2 = ((Cube != (Fxu_Cube *)1)? Cube->pOrder: (Fxu_Cube *)1) ) -#define Fxu_MatrixForEachVarInRing( Matrix, Var )\ - if ( (Matrix)->pOrderVars )\ - for ( Var = (Matrix)->pOrderVars;\ - Var != (Fxu_Var *)1;\ - Var = Var->pOrder ) -#define Fxu_MatrixForEachVarInRingSafe( Matrix, Var, Var2 )\ - if ( (Matrix)->pOrderVars )\ - for ( Var = (Matrix)->pOrderVars, Var2 = ((Var != (Fxu_Var *)1)? Var->pOrder: (Fxu_Var *)1);\ - Var != (Fxu_Var *)1;\ - Var = Var2, Var2 = ((Var != (Fxu_Var *)1)? Var->pOrder: (Fxu_Var *)1) ) -// the procedures are related to the above macros -extern void Fxu_MatrixRingCubesUnmark( Fxu_Matrix * p ); -extern void Fxu_MatrixRingVarsUnmark( Fxu_Matrix * p ); - - -// macros working with memory -// MEM_ALLOC: allocate the given number (Size) of items of type (Type) -// MEM_FREE: deallocate the pointer (Pointer) to the given number (Size) of items of type (Type) -#ifdef USE_SYSTEM_MEMORY_MANAGEMENT -#define MEM_ALLOC_FXU( Manager, Type, Size ) ((Type *)malloc( (Size) * sizeof(Type) )) -#define MEM_FREE_FXU( Manager, Type, Size, Pointer ) if ( Pointer ) { free(Pointer); Pointer = NULL; } -#else -#define MEM_ALLOC_FXU( Manager, Type, Size )\ - ((Type *)Fxu_MemFetch( Manager, (Size) * sizeof(Type) )) -#define MEM_FREE_FXU( Manager, Type, Size, Pointer )\ - if ( Pointer ) { Fxu_MemRecycle( Manager, (char *)(Pointer), (Size) * sizeof(Type) ); Pointer = NULL; } -#endif - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/*===== fxu.c ====================================================*/ -extern char * Fxu_MemFetch( Fxu_Matrix * p, int nBytes ); -extern void Fxu_MemRecycle( Fxu_Matrix * p, char * pItem, int nBytes ); -/*===== fxuCreate.c ====================================================*/ -/*===== fxuReduce.c ====================================================*/ -/*===== fxuPrint.c ====================================================*/ -extern void Fxu_MatrixPrint( FILE * pFile, Fxu_Matrix * p ); -extern void Fxu_MatrixPrintDivisorProfile( FILE * pFile, Fxu_Matrix * p ); -/*===== fxuSelect.c ====================================================*/ -extern int Fxu_Select( Fxu_Matrix * p, Fxu_Single ** ppSingle, Fxu_Double ** ppDouble ); -extern int Fxu_SelectSCD( Fxu_Matrix * p, int Weight, Fxu_Var ** ppVar1, Fxu_Var ** ppVar2 ); -/*===== fxuUpdate.c ====================================================*/ -extern void Fxu_Update( Fxu_Matrix * p, Fxu_Single * pSingle, Fxu_Double * pDouble ); -extern void Fxu_UpdateDouble( Fxu_Matrix * p ); -extern void Fxu_UpdateSingle( Fxu_Matrix * p ); -/*===== fxuPair.c ====================================================*/ -extern void Fxu_PairCanonicize( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 ); -extern unsigned Fxu_PairHashKeyArray( Fxu_Matrix * p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 ); -extern unsigned Fxu_PairHashKey( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, int * pnBase, int * pnLits1, int * pnLits2 ); -extern unsigned Fxu_PairHashKeyMv( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, int * pnBase, int * pnLits1, int * pnLits2 ); -extern int Fxu_PairCompare( Fxu_Pair * pPair1, Fxu_Pair * pPair2 ); -extern void Fxu_PairAllocStorage( Fxu_Var * pVar, int nCubes ); -extern void Fxu_PairFreeStorage( Fxu_Var * pVar ); -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_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ); -extern int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 ); -/*===== fxuMatrix.c ====================================================*/ -// matrix -extern Fxu_Matrix * Fxu_MatrixAllocate(); -extern void Fxu_MatrixDelete( Fxu_Matrix * p ); -// double-cube divisor -extern void Fxu_MatrixAddDivisor( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 ); -extern void Fxu_MatrixDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv ); -// single-cube divisor -extern void Fxu_MatrixAddSingle( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, int Weight ); -// variable -extern Fxu_Var * Fxu_MatrixAddVar( Fxu_Matrix * p ); -// cube -extern Fxu_Cube * Fxu_MatrixAddCube( Fxu_Matrix * p, Fxu_Var * pVar, int iCube ); -// literal -extern void Fxu_MatrixAddLiteral( Fxu_Matrix * p, Fxu_Cube * pCube, Fxu_Var * pVar ); -extern void Fxu_MatrixDelLiteral( Fxu_Matrix * p, Fxu_Lit * pLit ); -/*===== fxuList.c ====================================================*/ -// matrix -> variable -extern void Fxu_ListMatrixAddVariable( Fxu_Matrix * p, Fxu_Var * pVar ); -extern void Fxu_ListMatrixDelVariable( Fxu_Matrix * p, Fxu_Var * pVar ); -// matrix -> cube -extern void Fxu_ListMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pCube ); -extern void Fxu_ListMatrixDelCube( Fxu_Matrix * p, Fxu_Cube * pCube ); -// matrix -> single -extern void Fxu_ListMatrixAddSingle( Fxu_Matrix * p, Fxu_Single * pSingle ); -extern void Fxu_ListMatrixDelSingle( Fxu_Matrix * p, Fxu_Single * pSingle ); -// table -> divisor -extern void Fxu_ListTableAddDivisor( Fxu_Matrix * p, Fxu_Double * pDiv ); -extern void Fxu_ListTableDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv ); -// cube -> literal -extern void Fxu_ListCubeAddLiteral( Fxu_Cube * pCube, Fxu_Lit * pLit ); -extern void Fxu_ListCubeDelLiteral( Fxu_Cube * pCube, Fxu_Lit * pLit ); -// var -> literal -extern void Fxu_ListVarAddLiteral( Fxu_Var * pVar, Fxu_Lit * pLit ); -extern void Fxu_ListVarDelLiteral( Fxu_Var * pVar, Fxu_Lit * pLit ); -// divisor -> pair -extern void Fxu_ListDoubleAddPairLast( Fxu_Double * pDiv, Fxu_Pair * pLink ); -extern void Fxu_ListDoubleAddPairFirst( Fxu_Double * pDiv, Fxu_Pair * pLink ); -extern void Fxu_ListDoubleAddPairMiddle( Fxu_Double * pDiv, Fxu_Pair * pSpot, Fxu_Pair * pLink ); -extern void Fxu_ListDoubleDelPair( Fxu_Double * pDiv, Fxu_Pair * pPair ); -/*===== fxuHeapDouble.c ====================================================*/ -extern Fxu_HeapDouble * Fxu_HeapDoubleStart(); -extern void Fxu_HeapDoubleStop( Fxu_HeapDouble * p ); -extern void Fxu_HeapDoublePrint( FILE * pFile, Fxu_HeapDouble * p ); -extern void Fxu_HeapDoubleCheck( Fxu_HeapDouble * p ); -extern void Fxu_HeapDoubleCheckOne( Fxu_HeapDouble * p, Fxu_Double * pDiv ); - -extern void Fxu_HeapDoubleInsert( Fxu_HeapDouble * p, Fxu_Double * pDiv ); -extern void Fxu_HeapDoubleUpdate( Fxu_HeapDouble * p, Fxu_Double * pDiv ); -extern void Fxu_HeapDoubleDelete( Fxu_HeapDouble * p, Fxu_Double * pDiv ); -extern int Fxu_HeapDoubleReadMaxWeight( Fxu_HeapDouble * p ); -extern Fxu_Double * Fxu_HeapDoubleReadMax( Fxu_HeapDouble * p ); -extern Fxu_Double * Fxu_HeapDoubleGetMax( Fxu_HeapDouble * p ); -/*===== fxuHeapSingle.c ====================================================*/ -extern Fxu_HeapSingle * Fxu_HeapSingleStart(); -extern void Fxu_HeapSingleStop( Fxu_HeapSingle * p ); -extern void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p ); -extern void Fxu_HeapSingleCheck( Fxu_HeapSingle * p ); -extern void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle ); - -extern void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle ); -extern void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle ); -extern void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle ); -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 /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/fxu/fxuList.c b/src/opt/fxu/fxuList.c deleted file mode 100644 index 52995804..00000000 --- a/src/opt/fxu/fxuList.c +++ /dev/null @@ -1,522 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuList.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Operations on lists.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuList.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "fxuInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -// matrix -> var - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListMatrixAddVariable( Fxu_Matrix * p, Fxu_Var * pLink ) -{ - Fxu_ListVar * pList = &p->lVars; - if ( pList->pHead == NULL ) - { - pList->pHead = pLink; - pList->pTail = pLink; - pLink->pPrev = NULL; - pLink->pNext = NULL; - } - else - { - pLink->pNext = NULL; - pList->pTail->pNext = pLink; - pLink->pPrev = pList->pTail; - pList->pTail = pLink; - } - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListMatrixDelVariable( Fxu_Matrix * p, Fxu_Var * pLink ) -{ - Fxu_ListVar * pList = &p->lVars; - if ( pList->pHead == pLink ) - pList->pHead = pLink->pNext; - if ( pList->pTail == pLink ) - pList->pTail = pLink->pPrev; - if ( pLink->pPrev ) - pLink->pPrev->pNext = pLink->pNext; - if ( pLink->pNext ) - pLink->pNext->pPrev = pLink->pPrev; - pList->nItems--; -} - - -// matrix -> cube - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListMatrixAddCube( Fxu_Matrix * p, Fxu_Cube * pLink ) -{ - Fxu_ListCube * pList = &p->lCubes; - if ( pList->pHead == NULL ) - { - pList->pHead = pLink; - pList->pTail = pLink; - pLink->pPrev = NULL; - pLink->pNext = NULL; - } - else - { - pLink->pNext = NULL; - pList->pTail->pNext = pLink; - pLink->pPrev = pList->pTail; - pList->pTail = pLink; - } - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListMatrixDelCube( Fxu_Matrix * p, Fxu_Cube * pLink ) -{ - Fxu_ListCube * pList = &p->lCubes; - if ( pList->pHead == pLink ) - pList->pHead = pLink->pNext; - if ( pList->pTail == pLink ) - pList->pTail = pLink->pPrev; - if ( pLink->pPrev ) - pLink->pPrev->pNext = pLink->pNext; - if ( pLink->pNext ) - pLink->pNext->pPrev = pLink->pPrev; - pList->nItems--; -} - - -// matrix -> single - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListMatrixAddSingle( Fxu_Matrix * p, Fxu_Single * pLink ) -{ - Fxu_ListSingle * pList = &p->lSingles; - if ( pList->pHead == NULL ) - { - pList->pHead = pLink; - pList->pTail = pLink; - pLink->pPrev = NULL; - pLink->pNext = NULL; - } - else - { - pLink->pNext = NULL; - pList->pTail->pNext = pLink; - pLink->pPrev = pList->pTail; - pList->pTail = pLink; - } - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListMatrixDelSingle( Fxu_Matrix * p, Fxu_Single * pLink ) -{ - Fxu_ListSingle * pList = &p->lSingles; - if ( pList->pHead == pLink ) - pList->pHead = pLink->pNext; - if ( pList->pTail == pLink ) - pList->pTail = pLink->pPrev; - if ( pLink->pPrev ) - pLink->pPrev->pNext = pLink->pNext; - if ( pLink->pNext ) - pLink->pNext->pPrev = pLink->pPrev; - pList->nItems--; -} - - -// table -> divisor - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListTableAddDivisor( Fxu_Matrix * p, Fxu_Double * pLink ) -{ - Fxu_ListDouble * pList = &(p->pTable[pLink->Key]); - if ( pList->pHead == NULL ) - { - pList->pHead = pLink; - pList->pTail = pLink; - pLink->pPrev = NULL; - pLink->pNext = NULL; - } - else - { - pLink->pNext = NULL; - pList->pTail->pNext = pLink; - pLink->pPrev = pList->pTail; - pList->pTail = pLink; - } - pList->nItems++; - p->nDivs++; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListTableDelDivisor( Fxu_Matrix * p, Fxu_Double * pLink ) -{ - Fxu_ListDouble * pList = &(p->pTable[pLink->Key]); - if ( pList->pHead == pLink ) - pList->pHead = pLink->pNext; - if ( pList->pTail == pLink ) - pList->pTail = pLink->pPrev; - if ( pLink->pPrev ) - pLink->pPrev->pNext = pLink->pNext; - if ( pLink->pNext ) - pLink->pNext->pPrev = pLink->pPrev; - pList->nItems--; - p->nDivs--; -} - - -// cube -> literal - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListCubeAddLiteral( Fxu_Cube * pCube, Fxu_Lit * pLink ) -{ - Fxu_ListLit * pList = &(pCube->lLits); - if ( pList->pHead == NULL ) - { - pList->pHead = pLink; - pList->pTail = pLink; - pLink->pHPrev = NULL; - pLink->pHNext = NULL; - } - else - { - pLink->pHNext = NULL; - pList->pTail->pHNext = pLink; - pLink->pHPrev = pList->pTail; - pList->pTail = pLink; - } - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListCubeDelLiteral( Fxu_Cube * pCube, Fxu_Lit * pLink ) -{ - Fxu_ListLit * pList = &(pCube->lLits); - if ( pList->pHead == pLink ) - pList->pHead = pLink->pHNext; - if ( pList->pTail == pLink ) - pList->pTail = pLink->pHPrev; - if ( pLink->pHPrev ) - pLink->pHPrev->pHNext = pLink->pHNext; - if ( pLink->pHNext ) - pLink->pHNext->pHPrev = pLink->pHPrev; - pList->nItems--; -} - - -// var -> literal - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListVarAddLiteral( Fxu_Var * pVar, Fxu_Lit * pLink ) -{ - Fxu_ListLit * pList = &(pVar->lLits); - if ( pList->pHead == NULL ) - { - pList->pHead = pLink; - pList->pTail = pLink; - pLink->pVPrev = NULL; - pLink->pVNext = NULL; - } - else - { - pLink->pVNext = NULL; - pList->pTail->pVNext = pLink; - pLink->pVPrev = pList->pTail; - pList->pTail = pLink; - } - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListVarDelLiteral( Fxu_Var * pVar, Fxu_Lit * pLink ) -{ - Fxu_ListLit * pList = &(pVar->lLits); - if ( pList->pHead == pLink ) - pList->pHead = pLink->pVNext; - if ( pList->pTail == pLink ) - pList->pTail = pLink->pVPrev; - if ( pLink->pVPrev ) - pLink->pVPrev->pVNext = pLink->pVNext; - if ( pLink->pVNext ) - pLink->pVNext->pVPrev = pLink->pVPrev; - pList->nItems--; -} - - - -// divisor -> pair - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListDoubleAddPairLast( Fxu_Double * pDiv, Fxu_Pair * pLink ) -{ - Fxu_ListPair * pList = &pDiv->lPairs; - if ( pList->pHead == NULL ) - { - pList->pHead = pLink; - pList->pTail = pLink; - pLink->pDPrev = NULL; - pLink->pDNext = NULL; - } - else - { - pLink->pDNext = NULL; - pList->pTail->pDNext = pLink; - pLink->pDPrev = pList->pTail; - pList->pTail = pLink; - } - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListDoubleAddPairFirst( Fxu_Double * pDiv, Fxu_Pair * pLink ) -{ - Fxu_ListPair * pList = &pDiv->lPairs; - if ( pList->pHead == NULL ) - { - pList->pHead = pLink; - pList->pTail = pLink; - pLink->pDPrev = NULL; - pLink->pDNext = NULL; - } - else - { - pLink->pDPrev = NULL; - pList->pHead->pDPrev = pLink; - pLink->pDNext = pList->pHead; - pList->pHead = pLink; - } - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [Adds the entry in the middle of the list after the spot.] - - Description [Assumes that spot points to the link, after which the given - link should be added. Spot cannot be NULL or the tail of the list. - Therefore, the head and the tail of the list are not changed.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListDoubleAddPairMiddle( Fxu_Double * pDiv, Fxu_Pair * pSpot, Fxu_Pair * pLink ) -{ - Fxu_ListPair * pList = &pDiv->lPairs; - assert( pSpot ); - assert( pSpot != pList->pTail ); - pLink->pDPrev = pSpot; - pLink->pDNext = pSpot->pDNext; - pLink->pDPrev->pDNext = pLink; - pLink->pDNext->pDPrev = pLink; - pList->nItems++; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListDoubleDelPair( Fxu_Double * pDiv, Fxu_Pair * pLink ) -{ - Fxu_ListPair * pList = &pDiv->lPairs; - if ( pList->pHead == pLink ) - pList->pHead = pLink->pDNext; - if ( pList->pTail == pLink ) - pList->pTail = pLink->pDPrev; - if ( pLink->pDPrev ) - pLink->pDPrev->pDNext = pLink->pDNext; - if ( pLink->pDNext ) - pLink->pDNext->pDPrev = pLink->pDPrev; - pList->nItems--; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_ListDoubleAddPairPlace( Fxu_Double * pDiv, Fxu_Pair * pPair, Fxu_Pair * pPairSpot ) -{ - printf( "Fxu_ListDoubleAddPairPlace() is called!\n" ); -} - - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/fxu/fxuMatrix.c b/src/opt/fxu/fxuMatrix.c deleted file mode 100644 index 93ec7b90..00000000 --- a/src/opt/fxu/fxuMatrix.c +++ /dev/null @@ -1,374 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuMatrix.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Procedures to manipulate the sparse matrix.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuMatrix.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "fxuInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -extern unsigned int Cudd_Prime( unsigned int p ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Matrix * Fxu_MatrixAllocate() -{ - Fxu_Matrix * p; - p = ALLOC( Fxu_Matrix, 1 ); - memset( p, 0, sizeof(Fxu_Matrix) ); - p->nTableSize = Cudd_Prime(10000); - p->pTable = ALLOC( Fxu_ListDouble, p->nTableSize ); - memset( p->pTable, 0, sizeof(Fxu_ListDouble) * p->nTableSize ); -#ifndef USE_SYSTEM_MEMORY_MANAGEMENT - { - // get the largest size in bytes for the following structures: - // Fxu_Cube, Fxu_Var, Fxu_Lit, Fxu_Pair, Fxu_Double, Fxu_Single - // (currently, Fxu_Var, Fxu_Pair, Fxu_Double take 10 machine words) - int nSizeMax, nSizeCur; - nSizeMax = -1; - nSizeCur = sizeof(Fxu_Cube); - if ( nSizeMax < nSizeCur ) - nSizeMax = nSizeCur; - nSizeCur = sizeof(Fxu_Var); - if ( nSizeMax < nSizeCur ) - nSizeMax = nSizeCur; - nSizeCur = sizeof(Fxu_Lit); - if ( nSizeMax < nSizeCur ) - nSizeMax = nSizeCur; - nSizeCur = sizeof(Fxu_Pair); - if ( nSizeMax < nSizeCur ) - nSizeMax = nSizeCur; - nSizeCur = sizeof(Fxu_Double); - if ( nSizeMax < nSizeCur ) - nSizeMax = nSizeCur; - nSizeCur = sizeof(Fxu_Single); - if ( nSizeMax < nSizeCur ) - nSizeMax = nSizeCur; - p->pMemMan = Extra_MmFixedStart( nSizeMax ); - } -#endif - p->pHeapDouble = Fxu_HeapDoubleStart(); - p->pHeapSingle = Fxu_HeapSingleStart(); - p->vPairs = Vec_PtrAlloc( 100 ); - return p; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixDelete( Fxu_Matrix * p ) -{ - Fxu_HeapDoubleCheck( p->pHeapDouble ); - Fxu_HeapDoubleStop( p->pHeapDouble ); - Fxu_HeapSingleStop( p->pHeapSingle ); - - // delete other things -#ifdef USE_SYSTEM_MEMORY_MANAGEMENT - // this code is not needed when the custom memory manager is used - { - Fxu_Cube * pCube, * pCube2; - Fxu_Var * pVar, * pVar2; - Fxu_Lit * pLit, * pLit2; - Fxu_Double * pDiv, * pDiv2; - Fxu_Single * pSingle, * pSingle2; - Fxu_Pair * pPair, * pPair2; - int i; - // delete the divisors - Fxu_MatrixForEachDoubleSafe( p, pDiv, pDiv2, i ) - { - Fxu_DoubleForEachPairSafe( pDiv, pPair, pPair2 ) - MEM_FREE_FXU( p, Fxu_Pair, 1, pPair ); - MEM_FREE_FXU( p, Fxu_Double, 1, pDiv ); - } - Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 ) - MEM_FREE_FXU( p, Fxu_Single, 1, pSingle ); - // delete the entries - Fxu_MatrixForEachCube( p, pCube ) - Fxu_CubeForEachLiteralSafe( pCube, pLit, pLit2 ) - MEM_FREE_FXU( p, Fxu_Lit, 1, pLit ); - // delete the cubes - Fxu_MatrixForEachCubeSafe( p, pCube, pCube2 ) - MEM_FREE_FXU( p, Fxu_Cube, 1, pCube ); - // delete the vars - Fxu_MatrixForEachVariableSafe( p, pVar, pVar2 ) - MEM_FREE_FXU( p, Fxu_Var, 1, pVar ); - } -#else - Extra_MmFixedStop( p->pMemMan ); -#endif - - Vec_PtrFree( p->vPairs ); - FREE( p->pppPairs ); - FREE( p->ppPairs ); -// FREE( p->pPairsTemp ); - FREE( p->pTable ); - FREE( p->ppVars ); - FREE( p ); -} - - - -/**Function************************************************************* - - Synopsis [Adds a variable to the matrix.] - - Description [This procedure always adds variables at the end of the matrix. - It assigns the var's node and number. It adds the var to the linked list of - all variables and to the table of all nodes.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Var * Fxu_MatrixAddVar( Fxu_Matrix * p ) -{ - Fxu_Var * pVar; - pVar = MEM_ALLOC_FXU( p, Fxu_Var, 1 ); - memset( pVar, 0, sizeof(Fxu_Var) ); - pVar->iVar = p->lVars.nItems; - p->ppVars[pVar->iVar] = pVar; - Fxu_ListMatrixAddVariable( p, pVar ); - return pVar; -} - -/**Function************************************************************* - - Synopsis [Adds a literal to the matrix.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Cube * Fxu_MatrixAddCube( Fxu_Matrix * p, Fxu_Var * pVar, int iCube ) -{ - Fxu_Cube * pCube; - pCube = MEM_ALLOC_FXU( p, Fxu_Cube, 1 ); - memset( pCube, 0, sizeof(Fxu_Cube) ); - pCube->pVar = pVar; - pCube->iCube = iCube; - Fxu_ListMatrixAddCube( p, pCube ); - return pCube; -} - -/**Function************************************************************* - - Synopsis [Adds a literal to the matrix.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixAddLiteral( Fxu_Matrix * p, Fxu_Cube * pCube, Fxu_Var * pVar ) -{ - Fxu_Lit * pLit; - pLit = MEM_ALLOC_FXU( p, Fxu_Lit, 1 ); - memset( pLit, 0, sizeof(Fxu_Lit) ); - // insert the literal into two linked lists - Fxu_ListCubeAddLiteral( pCube, pLit ); - Fxu_ListVarAddLiteral( pVar, pLit ); - // set the back pointers - pLit->pCube = pCube; - pLit->pVar = pVar; - pLit->iCube = pCube->iCube; - pLit->iVar = pVar->iVar; - // increment the literal counter - p->nEntries++; -} - -/**Function************************************************************* - - Synopsis [Deletes the divisor from the matrix.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixDelDivisor( Fxu_Matrix * p, Fxu_Double * pDiv ) -{ - // delete divisor from the table - Fxu_ListTableDelDivisor( p, pDiv ); - // recycle the divisor - MEM_FREE_FXU( p, Fxu_Double, 1, pDiv ); -} - -/**Function************************************************************* - - Synopsis [Deletes the literal fromthe matrix.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixDelLiteral( Fxu_Matrix * p, Fxu_Lit * pLit ) -{ - // delete the literal - Fxu_ListCubeDelLiteral( pLit->pCube, pLit ); - Fxu_ListVarDelLiteral( pLit->pVar, pLit ); - MEM_FREE_FXU( p, Fxu_Lit, 1, pLit ); - // increment the literal counter - p->nEntries--; -} - - -/**Function************************************************************* - - Synopsis [Creates and adds a single cube divisor.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixAddSingle( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, int Weight ) -{ - Fxu_Single * pSingle; - assert( pVar1->iVar < pVar2->iVar ); - pSingle = MEM_ALLOC_FXU( p, Fxu_Single, 1 ); - memset( pSingle, 0, sizeof(Fxu_Single) ); - pSingle->Num = p->lSingles.nItems; - pSingle->Weight = Weight; - pSingle->HNum = 0; - pSingle->pVar1 = pVar1; - pSingle->pVar2 = pVar2; - Fxu_ListMatrixAddSingle( p, pSingle ); - // add to the heap - Fxu_HeapSingleInsert( p->pHeapSingle, pSingle ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixAddDivisor( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 ) -{ - Fxu_Pair * pPair; - Fxu_Double * pDiv; - int nBase, nLits1, nLits2; - int fFound; - unsigned Key; - - // canonicize the pair - Fxu_PairCanonicize( &pCube1, &pCube2 ); - // compute the hash key - Key = Fxu_PairHashKey( p, pCube1, pCube2, &nBase, &nLits1, &nLits2 ); - - // create the cube pair - pPair = Fxu_PairAlloc( p, pCube1, pCube2 ); - pPair->nBase = nBase; - pPair->nLits1 = nLits1; - pPair->nLits2 = nLits2; - - // check if the divisor for this pair already exists - fFound = 0; - Key %= p->nTableSize; - Fxu_TableForEachDouble( p, Key, pDiv ) - { - if ( Fxu_PairCompare( pPair, pDiv->lPairs.pTail ) ) // they are equal - { - fFound = 1; - break; - } - } - - if ( !fFound ) - { // create the new divisor - pDiv = MEM_ALLOC_FXU( p, Fxu_Double, 1 ); - memset( pDiv, 0, sizeof(Fxu_Double) ); - pDiv->Key = Key; - // set the number of this divisor - pDiv->Num = p->nDivsTotal++; // p->nDivs; - // insert the divisor in the table - Fxu_ListTableAddDivisor( p, pDiv ); - // set the initial cost of the divisor - pDiv->Weight -= pPair->nLits1 + pPair->nLits2; - } - - // link the pair to the cubes - Fxu_PairAdd( pPair ); - // connect the pair and the divisor - pPair->pDiv = pDiv; - Fxu_ListDoubleAddPairLast( pDiv, pPair ); - // update the max number of pairs in a divisor -// if ( p->nPairsMax < pDiv->lPairs.nItems ) -// p->nPairsMax = pDiv->lPairs.nItems; - // update the divisor's weight - pDiv->Weight += pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase; - if ( fFound ) // update the divisor in the heap - Fxu_HeapDoubleUpdate( p->pHeapDouble, pDiv ); - else // add the new divisor to the heap - Fxu_HeapDoubleInsert( p->pHeapDouble, pDiv ); -} - -/* - { - int piVarsC1[100], piVarsC2[100], nVarsC1, nVarsC2; - Fxu_Double * pDivCur; - Fxu_MatrixGetDoubleVars( p, pDiv, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 ); - pDivCur = Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 ); - assert( pDivCur == pDiv ); - } -*/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/fxu/fxuPair.c b/src/opt/fxu/fxuPair.c deleted file mode 100644 index 3c031ce8..00000000 --- a/src/opt/fxu/fxuPair.c +++ /dev/null @@ -1,555 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuPair.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Operations on cube pairs.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuPair.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "fxuInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define MAX_PRIMES 304 - -static s_Primes[MAX_PRIMES] = -{ - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, - 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, - 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, - 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, - 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, - 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, - 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, - 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, - 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, - 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, - 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, - 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, - 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, - 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, - 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, - 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, - 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, - 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, - 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, - 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, - 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, - 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, - 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, - 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, - 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, - 1993, 1997, 1999, 2003 -}; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Find the canonical permutation of two cubes in the pair.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_PairCanonicize( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 ) -{ - Fxu_Lit * pLit1, * pLit2; - Fxu_Cube * pCubeTemp; - - // walk through the cubes to determine - // the one that has higher first variable - pLit1 = (*ppCube1)->lLits.pHead; - pLit2 = (*ppCube2)->lLits.pHead; - while ( 1 ) - { - if ( pLit1->iVar == pLit2->iVar ) - { - pLit1 = pLit1->pHNext; - pLit2 = pLit2->pHNext; - continue; - } - assert( pLit1 && pLit2 ); // this is true if the covers are SCC-free - if ( pLit1->iVar > pLit2->iVar ) - { // swap the cubes - pCubeTemp = *ppCube1; - *ppCube1 = *ppCube2; - *ppCube2 = pCubeTemp; - } - break; - } -} - -/**Function************************************************************* - - Synopsis [Find the canonical permutation of two cubes in the pair.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_PairCanonicize2( Fxu_Cube ** ppCube1, Fxu_Cube ** ppCube2 ) -{ - Fxu_Cube * pCubeTemp; - // canonicize the pair by ordering the cubes - if ( (*ppCube1)->iCube > (*ppCube2)->iCube ) - { // swap the cubes - pCubeTemp = *ppCube1; - *ppCube1 = *ppCube2; - *ppCube2 = pCubeTemp; - } -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Fxu_PairHashKeyArray( Fxu_Matrix * p, int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 ) -{ - int Offset1 = 100, Offset2 = 200, i; - unsigned Key; - // compute the hash key - Key = 0; - for ( i = 0; i < nVarsC1; i++ ) - Key ^= s_Primes[Offset1+i] * piVarsC1[i]; - for ( i = 0; i < nVarsC2; i++ ) - Key ^= s_Primes[Offset2+i] * piVarsC2[i]; - return Key; -} - -/**Function************************************************************* - - Synopsis [Computes the hash key of the divisor represented by the pair of cubes.] - - Description [Goes through the variables in both cubes. Skips the identical - ones (this corresponds to making the cubes cube-free). Computes the hash - value of the cubes. Assigns the number of literals in the base and in the - cubes without base.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -unsigned Fxu_PairHashKey( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, - int * pnBase, int * pnLits1, int * pnLits2 ) -{ - int Offset1 = 100, Offset2 = 200; - int nBase, nLits1, nLits2; - Fxu_Lit * pLit1, * pLit2; - unsigned Key; - - // compute the hash key - Key = 0; - nLits1 = 0; - nLits2 = 0; - nBase = 0; - pLit1 = pCube1->lLits.pHead; - pLit2 = pCube2->lLits.pHead; - while ( 1 ) - { - if ( pLit1 && pLit2 ) - { - if ( pLit1->iVar == pLit2->iVar ) - { // ensure cube-free - pLit1 = pLit1->pHNext; - pLit2 = pLit2->pHNext; - // add this literal to the base - nBase++; - } - else if ( pLit1->iVar < pLit2->iVar ) - { - Key ^= s_Primes[Offset1+nLits1] * pLit1->iVar; - pLit1 = pLit1->pHNext; - nLits1++; - } - else - { - Key ^= s_Primes[Offset2+nLits2] * pLit2->iVar; - pLit2 = pLit2->pHNext; - nLits2++; - } - } - else if ( pLit1 && !pLit2 ) - { - Key ^= s_Primes[Offset1+nLits1] * pLit1->iVar; - pLit1 = pLit1->pHNext; - nLits1++; - } - else if ( !pLit1 && pLit2 ) - { - Key ^= s_Primes[Offset2+nLits2] * pLit2->iVar; - pLit2 = pLit2->pHNext; - nLits2++; - } - else - break; - } - *pnBase = nBase; - *pnLits1 = nLits1; - *pnLits2 = nLits2; - return Key; -} - -/**Function************************************************************* - - Synopsis [Compares the two pairs.] - - Description [Returns 1 if the divisors represented by these pairs - are equal.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_PairCompare( Fxu_Pair * pPair1, Fxu_Pair * pPair2 ) -{ - Fxu_Lit * pD1C1, * pD1C2; - Fxu_Lit * pD2C1, * pD2C2; - int TopVar1, TopVar2; - int Code; - - if ( pPair1->nLits1 != pPair2->nLits1 ) - return 0; - if ( pPair1->nLits2 != pPair2->nLits2 ) - return 0; - - pD1C1 = pPair1->pCube1->lLits.pHead; - pD1C2 = pPair1->pCube2->lLits.pHead; - - pD2C1 = pPair2->pCube1->lLits.pHead; - pD2C2 = pPair2->pCube2->lLits.pHead; - - Code = pD1C1? 8: 0; - Code |= pD1C2? 4: 0; - Code |= pD2C1? 2: 0; - Code |= pD2C2? 1: 0; - assert( Code == 15 ); - - while ( 1 ) - { - switch ( Code ) - { - case 0: // -- -- NULL NULL NULL NULL - return 1; - case 1: // -- -1 NULL NULL NULL pD2C2 - return 0; - case 2: // -- 1- NULL NULL pD2C1 NULL - return 0; - case 3: // -- 11 NULL NULL pD2C1 pD2C2 - if ( pD2C1->iVar != pD2C2->iVar ) - return 0; - pD2C1 = pD2C1->pHNext; - pD2C2 = pD2C2->pHNext; - break; - case 4: // -1 -- NULL pD1C2 NULL NULL - return 0; - case 5: // -1 -1 NULL pD1C2 NULL pD2C2 - if ( pD1C2->iVar != pD2C2->iVar ) - return 0; - pD1C2 = pD1C2->pHNext; - pD2C2 = pD2C2->pHNext; - break; - case 6: // -1 1- NULL pD1C2 pD2C1 NULL - return 0; - case 7: // -1 11 NULL pD1C2 pD2C1 pD2C2 - TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar ); - if ( TopVar2 == pD1C2->iVar ) - { - if ( pD2C1->iVar <= pD2C2->iVar ) - return 0; - pD1C2 = pD1C2->pHNext; - pD2C2 = pD2C2->pHNext; - } - else if ( TopVar2 < pD1C2->iVar ) - { - if ( pD2C1->iVar != pD2C2->iVar ) - return 0; - pD2C1 = pD2C1->pHNext; - pD2C2 = pD2C2->pHNext; - } - else - return 0; - break; - case 8: // 1- -- pD1C1 NULL NULL NULL - return 0; - case 9: // 1- -1 pD1C1 NULL NULL pD2C2 - return 0; - case 10: // 1- 1- pD1C1 NULL pD2C1 NULL - if ( pD1C1->iVar != pD2C1->iVar ) - return 0; - pD1C1 = pD1C1->pHNext; - pD2C1 = pD2C1->pHNext; - break; - case 11: // 1- 11 pD1C1 NULL pD2C1 pD2C2 - TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar ); - if ( TopVar2 == pD1C1->iVar ) - { - if ( pD2C1->iVar >= pD2C2->iVar ) - return 0; - pD1C1 = pD1C1->pHNext; - pD2C1 = pD2C1->pHNext; - } - else if ( TopVar2 < pD1C1->iVar ) - { - if ( pD2C1->iVar != pD2C2->iVar ) - return 0; - pD2C1 = pD2C1->pHNext; - pD2C2 = pD2C2->pHNext; - } - else - return 0; - break; - case 12: // 11 -- pD1C1 pD1C2 NULL NULL - if ( pD1C1->iVar != pD1C2->iVar ) - return 0; - pD1C1 = pD1C1->pHNext; - pD1C2 = pD1C2->pHNext; - break; - case 13: // 11 -1 pD1C1 pD1C2 NULL pD2C2 - TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar ); - if ( TopVar1 == pD2C2->iVar ) - { - if ( pD1C1->iVar <= pD1C2->iVar ) - return 0; - pD1C2 = pD1C2->pHNext; - pD2C2 = pD2C2->pHNext; - } - else if ( TopVar1 < pD2C2->iVar ) - { - if ( pD1C1->iVar != pD1C2->iVar ) - return 0; - pD1C1 = pD1C1->pHNext; - pD1C2 = pD1C2->pHNext; - } - else - return 0; - break; - case 14: // 11 1- pD1C1 pD1C2 pD2C1 NULL - TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar ); - if ( TopVar1 == pD2C1->iVar ) - { - if ( pD1C1->iVar >= pD1C2->iVar ) - return 0; - pD1C1 = pD1C1->pHNext; - pD2C1 = pD2C1->pHNext; - } - else if ( TopVar1 < pD2C1->iVar ) - { - if ( pD1C1->iVar != pD1C2->iVar ) - return 0; - pD1C1 = pD1C1->pHNext; - pD1C2 = pD1C2->pHNext; - } - else - return 0; - break; - case 15: // 11 11 pD1C1 pD1C2 pD2C1 pD2C2 - TopVar1 = Fxu_Min( pD1C1->iVar, pD1C2->iVar ); - TopVar2 = Fxu_Min( pD2C1->iVar, pD2C2->iVar ); - if ( TopVar1 == TopVar2 ) - { - if ( pD1C1->iVar == pD1C2->iVar ) - { - if ( pD2C1->iVar != pD2C2->iVar ) - return 0; - pD1C1 = pD1C1->pHNext; - pD1C2 = pD1C2->pHNext; - pD2C1 = pD2C1->pHNext; - pD2C2 = pD2C2->pHNext; - } - else - { - if ( pD2C1->iVar == pD2C2->iVar ) - return 0; - if ( pD1C1->iVar < pD1C2->iVar ) - { - if ( pD2C1->iVar > pD2C2->iVar ) - return 0; - pD1C1 = pD1C1->pHNext; - pD2C1 = pD2C1->pHNext; - } - else - { - if ( pD2C1->iVar < pD2C2->iVar ) - return 0; - pD1C2 = pD1C2->pHNext; - pD2C2 = pD2C2->pHNext; - } - } - } - else if ( TopVar1 < TopVar2 ) - { - if ( pD1C1->iVar != pD1C2->iVar ) - return 0; - pD1C1 = pD1C1->pHNext; - pD1C2 = pD1C2->pHNext; - } - else - { - if ( pD2C1->iVar != pD2C2->iVar ) - return 0; - pD2C1 = pD2C1->pHNext; - pD2C2 = pD2C2->pHNext; - } - break; - default: - assert( 0 ); - break; - } - - Code = pD1C1? 8: 0; - Code |= pD1C2? 4: 0; - Code |= pD2C1? 2: 0; - Code |= pD2C2? 1: 0; - } - return 1; -} - - -/**Function************************************************************* - - Synopsis [Allocates the storage for cubes pairs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_PairAllocStorage( Fxu_Var * pVar, int nCubes ) -{ - int k; -// assert( pVar->nCubes == 0 ); - pVar->nCubes = nCubes; - // allocate memory for all the pairs - pVar->ppPairs = ALLOC( Fxu_Pair **, nCubes ); - pVar->ppPairs[0] = ALLOC( Fxu_Pair *, nCubes * nCubes ); - memset( pVar->ppPairs[0], 0, sizeof(Fxu_Pair *) * nCubes * nCubes ); - for ( k = 1; k < nCubes; k++ ) - pVar->ppPairs[k] = pVar->ppPairs[k-1] + nCubes; -} - -/**Function************************************************************* - - Synopsis [Clears all pairs associated with this cube.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_PairClearStorage( Fxu_Cube * pCube ) -{ - Fxu_Var * pVar; - int i; - pVar = pCube->pVar; - for ( i = 0; i < pVar->nCubes; i++ ) - { - pVar->ppPairs[pCube->iCube][i] = NULL; - pVar->ppPairs[i][pCube->iCube] = NULL; - } -} - -/**Function************************************************************* - - Synopsis [Clears all pairs associated with this cube.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_PairFreeStorage( Fxu_Var * pVar ) -{ - if ( pVar->ppPairs ) - { - FREE( pVar->ppPairs[0] ); - FREE( pVar->ppPairs ); - } -} - -/**Function************************************************************* - - Synopsis [Adds the pair to storage.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 ) -{ - Fxu_Pair * pPair; - assert( pCube1->pVar == pCube2->pVar ); - pPair = MEM_ALLOC_FXU( p, Fxu_Pair, 1 ); - memset( pPair, 0, sizeof(Fxu_Pair) ); - pPair->pCube1 = pCube1; - pPair->pCube2 = pCube2; - pPair->iCube1 = pCube1->iCube; - pPair->iCube2 = pCube2->iCube; - return pPair; -} - -/**Function************************************************************* - - Synopsis [Adds the pair to storage.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_PairAdd( Fxu_Pair * pPair ) -{ - Fxu_Var * pVar; - - pVar = pPair->pCube1->pVar; - assert( pVar == pPair->pCube2->pVar ); - - pVar->ppPairs[pPair->iCube1][pPair->iCube2] = pPair; - pVar->ppPairs[pPair->iCube2][pPair->iCube1] = pPair; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/fxu/fxuPrint.c b/src/opt/fxu/fxuPrint.c deleted file mode 100644 index 232b109a..00000000 --- a/src/opt/fxu/fxuPrint.c +++ /dev/null @@ -1,195 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuPrint.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Various printing procedures.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuPrint.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "fxuInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixPrint( FILE * pFile, Fxu_Matrix * p ) -{ - Fxu_Var * pVar; - Fxu_Cube * pCube; - Fxu_Double * pDiv; - Fxu_Single * pSingle; - Fxu_Lit * pLit; - Fxu_Pair * pPair; - int i, LastNum; - int fStdout; - - fStdout = 1; - if ( pFile == NULL ) - { - pFile = fopen( "matrix.txt", "w" ); - fStdout = 0; - } - - fprintf( pFile, "Matrix has %d vars, %d cubes, %d literals, %d divisors.\n", - p->lVars.nItems, p->lCubes.nItems, p->nEntries, p->nDivs ); - fprintf( pFile, "Divisors selected so far: single = %d, double = %d.\n", - p->nDivs1, p->nDivs2 ); - fprintf( pFile, "\n" ); - - // print the numbers on top of the matrix - for ( i = 0; i < 12; i++ ) - fprintf( pFile, " " ); - Fxu_MatrixForEachVariable( p, pVar ) - fprintf( pFile, "%d", pVar->iVar % 10 ); - fprintf( pFile, "\n" ); - - // print the rows - Fxu_MatrixForEachCube( p, pCube ) - { - fprintf( pFile, "%4d", pCube->iCube ); - fprintf( pFile, " " ); - fprintf( pFile, "%4d", pCube->pVar->iVar ); - fprintf( pFile, " " ); - - // print the literals - LastNum = -1; - Fxu_CubeForEachLiteral( pCube, pLit ) - { - for ( i = LastNum + 1; i < pLit->pVar->iVar; i++ ) - fprintf( pFile, "." ); - fprintf( pFile, "1" ); - LastNum = i; - } - for ( i = LastNum + 1; i < p->lVars.nItems; i++ ) - fprintf( pFile, "." ); - fprintf( pFile, "\n" ); - } - fprintf( pFile, "\n" ); - - // print the double-cube divisors - fprintf( pFile, "The double divisors are:\n" ); - Fxu_MatrixForEachDouble( p, pDiv, i ) - { - fprintf( pFile, "Divisor #%3d (lit=%d,%d) (w=%2d): ", - pDiv->Num, pDiv->lPairs.pHead->nLits1, - pDiv->lPairs.pHead->nLits2, pDiv->Weight ); - Fxu_DoubleForEachPair( pDiv, pPair ) - fprintf( pFile, " <%d, %d> (b=%d)", - pPair->pCube1->iCube, pPair->pCube2->iCube, pPair->nBase ); - fprintf( pFile, "\n" ); - } - fprintf( pFile, "\n" ); - - // print the divisors associated with each cube - fprintf( pFile, "The cubes are:\n" ); - Fxu_MatrixForEachCube( p, pCube ) - { - fprintf( pFile, "Cube #%3d: ", pCube->iCube ); - if ( pCube->pVar->ppPairs ) - Fxu_CubeForEachPair( pCube, pPair, i ) - fprintf( pFile, " <%d %d> (d=%d) (b=%d)", - pPair->iCube1, pPair->iCube2, pPair->pDiv->Num, pPair->nBase ); - fprintf( pFile, "\n" ); - } - fprintf( pFile, "\n" ); - - // print the single-cube divisors - fprintf( pFile, "The single divisors are:\n" ); - Fxu_MatrixForEachSingle( p, pSingle ) - { - fprintf( pFile, "Single-cube divisor #%5d: Var1 = %4d. Var2 = %4d. Weight = %2d\n", - pSingle->Num, pSingle->pVar1->iVar, pSingle->pVar2->iVar, pSingle->Weight ); - } - fprintf( pFile, "\n" ); - -/* - { - int Index; - fprintf( pFile, "Distribution of divisors in the hash table:\n" ); - for ( Index = 0; Index < p->nTableSize; Index++ ) - fprintf( pFile, " %d", p->pTable[Index].nItems ); - fprintf( pFile, "\n" ); - } -*/ - if ( !fStdout ) - fclose( pFile ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixPrintDivisorProfile( FILE * pFile, Fxu_Matrix * p ) -{ - Fxu_Double * pDiv; - int WeightMax; - int * pProfile; - int Counter1; // the number of -1 weight - int CounterL; // the number of less than -1 weight - int i; - - WeightMax = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); - pProfile = ALLOC( int, (WeightMax + 1) ); - memset( pProfile, 0, sizeof(int) * (WeightMax + 1) ); - - Counter1 = 0; - CounterL = 0; - Fxu_MatrixForEachDouble( p, pDiv, i ) - { - assert( pDiv->Weight <= WeightMax ); - if ( pDiv->Weight == -1 ) - Counter1++; - else if ( pDiv->Weight < 0 ) - CounterL++; - else - pProfile[ pDiv->Weight ]++; - } - - fprintf( pFile, "The double divisors profile:\n" ); - fprintf( pFile, "Weight < -1 divisors = %6d\n", CounterL ); - fprintf( pFile, "Weight -1 divisors = %6d\n", Counter1 ); - for ( i = 0; i <= WeightMax; i++ ) - if ( pProfile[i] ) - fprintf( pFile, "Weight %3d divisors = %6d\n", i, pProfile[i] ); - fprintf( pFile, "End of divisor profile printout\n" ); - FREE( pProfile ); -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/fxu/fxuReduce.c b/src/opt/fxu/fxuReduce.c deleted file mode 100644 index 0ab8a157..00000000 --- a/src/opt/fxu/fxuReduce.c +++ /dev/null @@ -1,204 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuReduce.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Procedures to reduce the number of considered cube pairs.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuReduce.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "fxuInt.h" -#include "fxu.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Precomputes the pairs to use for creating two-cube divisors.] - - Description [This procedure takes the matrix with variables and cubes - allocated (p), the original covers of the nodes (i-sets) and their number - (ppCovers,nCovers). The maximum number of pairs to compute and the total - number of pairs in existence. This procedure adds to the storage of - divisors exactly the given number of pairs (nPairsMax) while taking - first those pairs that have the smallest number of literals in their - cube-free form.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_PreprocessCubePairs( Fxu_Matrix * p, Vec_Ptr_t * vCovers, int nPairsTotal, int nPairsMax ) -{ - unsigned char * pnLitsDiff; // storage for the counters of diff literals - int * pnPairCounters; // the counters of pairs for each number of diff literals - Fxu_Cube * pCubeFirst, * pCubeLast; - Fxu_Cube * pCube1, * pCube2; - Fxu_Var * pVar; - int nCubes, nBitsMax, nSum; - int CutOffNum, CutOffQuant; - int iPair, iQuant, k, c; - int clk = clock(); - char * pSopCover; - int nFanins; - - assert( nPairsMax < nPairsTotal ); - - // allocate storage for counter of diffs - pnLitsDiff = ALLOC( unsigned char, nPairsTotal ); - // go through the covers and precompute the distances between the pairs - iPair = 0; - nBitsMax = -1; - for ( c = 0; c < vCovers->nSize; c++ ) - if ( pSopCover = vCovers->pArray[c] ) - { - nFanins = Abc_SopGetVarNum(pSopCover); - // precompute the differences - Fxu_CountPairDiffs( pSopCover, pnLitsDiff + iPair ); - // update the counter - nCubes = Abc_SopGetCubeNum( pSopCover ); - iPair += nCubes * (nCubes - 1) / 2; - if ( nBitsMax < nFanins ) - nBitsMax = nFanins; - } - assert( iPair == nPairsTotal ); - - // allocate storage for counters of cube pairs by difference - pnPairCounters = ALLOC( int, 2 * nBitsMax ); - memset( pnPairCounters, 0, sizeof(int) * 2 * nBitsMax ); - // count the number of different pairs - for ( k = 0; k < nPairsTotal; k++ ) - 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; - for ( k = 0; k < 2 * nBitsMax; k++ ) - { - nSum += pnPairCounters[k]; - if ( nSum >= nPairsMax ) - { - CutOffNum = k; - CutOffQuant = pnPairCounters[k] - (nSum - nPairsMax); - break; - } - } - FREE( pnPairCounters ); - - // set to 0 all the pairs above the cut-off number and quantity - iQuant = 0; - iPair = 0; - for ( k = 0; k < nPairsTotal; k++ ) - if ( pnLitsDiff[k] > CutOffNum ) - pnLitsDiff[k] = 0; - else if ( pnLitsDiff[k] == CutOffNum ) - { - if ( iQuant++ >= CutOffQuant ) - pnLitsDiff[k] = 0; - else - iPair++; - } - else - iPair++; - assert( iPair == nPairsMax ); - - // collect the corresponding pairs and add the divisors - iPair = 0; - for ( c = 0; c < vCovers->nSize; c++ ) - if ( pSopCover = vCovers->pArray[c] ) - { - // get the var - pVar = p->ppVars[2*c+1]; - // get the first cube - pCubeFirst = pVar->pFirst; - // get the last cube - pCubeLast = pCubeFirst; - for ( k = 0; k < pVar->nCubes; k++ ) - pCubeLast = pCubeLast->pNext; - assert( pCubeLast == NULL || pCubeLast->pVar != pVar ); - - // go through the cube pairs - for ( pCube1 = pCubeFirst; pCube1 != pCubeLast; pCube1 = pCube1->pNext ) - for ( pCube2 = pCube1->pNext; pCube2 != pCubeLast; pCube2 = pCube2->pNext ) - if ( pnLitsDiff[iPair++] ) - { // create the divisors for this pair - Fxu_MatrixAddDivisor( p, pCube1, pCube2 ); - } - } - assert( iPair == nPairsTotal ); - FREE( pnLitsDiff ); -//PRT( "Preprocess", clock() - clk ); - return 1; -} - - -/**Function************************************************************* - - Synopsis [Counts the differences in each cube pair in the cover.] - - Description [Takes the cover (pCover) and the array where the - diff counters go (pDiffs). The array pDiffs should have as many - entries as there are different pairs of cubes in the cover: n(n-1)/2. - Fills out the array pDiffs with the following info: For each cube - pair, included in the array is the number of literals in both cubes - after they are made cube free.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_CountPairDiffs( char * pCover, unsigned char pDiffs[] ) -{ - char * pCube1, * pCube2; - int nOnes, nCubePairs, nFanins, v; - nCubePairs = 0; - nFanins = Abc_SopGetVarNum(pCover); - Abc_SopForEachCube( pCover, nFanins, pCube1 ) - Abc_SopForEachCube( pCube1, nFanins, pCube2 ) - { - if ( pCube1 == pCube2 ) - continue; - nOnes = 0; - for ( v = 0; v < nFanins; v++ ) - nOnes += (pCube1[v] != pCube2[v]); - pDiffs[nCubePairs++] = nOnes; - } - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/fxu/fxuSelect.c b/src/opt/fxu/fxuSelect.c deleted file mode 100644 index b9265487..00000000 --- a/src/opt/fxu/fxuSelect.c +++ /dev/null @@ -1,603 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuSelect.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Procedures to select the best divisor/complement pair.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuSelect.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "fxuInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define MAX_SIZE_LOOKAHEAD 20 - -static int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar ); - -static Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle ); -static Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble ); -static Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble ); - -Fxu_Double * Fxu_MatrixFindDouble( Fxu_Matrix * p, - int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 ); -void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble, - int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 ); - - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Selects the best pair (Single,Double) and returns their weight.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_Select( Fxu_Matrix * p, Fxu_Single ** ppSingle, Fxu_Double ** ppDouble ) -{ - // the top entries - Fxu_Single * pSingles[MAX_SIZE_LOOKAHEAD]; - Fxu_Double * pDoubles[MAX_SIZE_LOOKAHEAD]; - // the complements - Fxu_Double * pSCompl[MAX_SIZE_LOOKAHEAD]; - Fxu_Single * pDComplS[MAX_SIZE_LOOKAHEAD]; - Fxu_Double * pDComplD[MAX_SIZE_LOOKAHEAD]; - Fxu_Pair * pPair; - int nSingles; - int nDoubles; - int i; - int WeightBest; - int WeightCur; - int iNum, fBestS; - - // collect the top entries from the queues - for ( nSingles = 0; nSingles < MAX_SIZE_LOOKAHEAD; nSingles++ ) - { - pSingles[nSingles] = Fxu_HeapSingleGetMax( p->pHeapSingle ); - if ( pSingles[nSingles] == NULL ) - break; - } - // put them back into the queue - for ( i = 0; i < nSingles; i++ ) - if ( pSingles[i] ) - Fxu_HeapSingleInsert( p->pHeapSingle, pSingles[i] ); - - // the same for doubles - // collect the top entries from the queues - for ( nDoubles = 0; nDoubles < MAX_SIZE_LOOKAHEAD; nDoubles++ ) - { - pDoubles[nDoubles] = Fxu_HeapDoubleGetMax( p->pHeapDouble ); - if ( pDoubles[nDoubles] == NULL ) - break; - } - // put them back into the queue - for ( i = 0; i < nDoubles; i++ ) - if ( pDoubles[i] ) - Fxu_HeapDoubleInsert( p->pHeapDouble, pDoubles[i] ); - - // for each single, find the complement double (if any) - for ( i = 0; i < nSingles; i++ ) - if ( pSingles[i] ) - pSCompl[i] = Fxu_MatrixFindComplementSingle( p, pSingles[i] ); - - // for each double, find the complement single or double (if any) - for ( i = 0; i < nDoubles; i++ ) - if ( pDoubles[i] ) - { - pPair = pDoubles[i]->lPairs.pHead; - if ( pPair->nLits1 == 1 && pPair->nLits2 == 1 ) - { - pDComplS[i] = Fxu_MatrixFindComplementDouble2( p, pDoubles[i] ); - pDComplD[i] = NULL; - } -// else if ( pPair->nLits1 == 2 && pPair->nLits2 == 2 ) -// { -// pDComplS[i] = NULL; -// pDComplD[i] = Fxu_MatrixFindComplementDouble4( p, pDoubles[i] ); -// } - else - { - pDComplS[i] = NULL; - pDComplD[i] = NULL; - } - } - - // select the best pair - WeightBest = -1; - for ( i = 0; i < nSingles; i++ ) - { - WeightCur = pSingles[i]->Weight; - if ( pSCompl[i] ) - { - // add the weight of the double - WeightCur += pSCompl[i]->Weight; - // there is no need to implement this double, so... - pPair = pSCompl[i]->lPairs.pHead; - WeightCur += pPair->nLits1 + pPair->nLits2; - } - if ( WeightBest < WeightCur ) - { - WeightBest = WeightCur; - *ppSingle = pSingles[i]; - *ppDouble = pSCompl[i]; - fBestS = 1; - iNum = i; - } - } - for ( i = 0; i < nDoubles; i++ ) - { - WeightCur = pDoubles[i]->Weight; - if ( pDComplS[i] ) - { - // add the weight of the single - WeightCur += pDComplS[i]->Weight; - // there is no need to implement this double, so... - pPair = pDoubles[i]->lPairs.pHead; - WeightCur += pPair->nLits1 + pPair->nLits2; - } - if ( WeightBest < WeightCur ) - { - WeightBest = WeightCur; - *ppSingle = pDComplS[i]; - *ppDouble = pDoubles[i]; - fBestS = 0; - iNum = i; - } - } -/* - // print the statistics - printf( "\n" ); - for ( i = 0; i < nSingles; i++ ) - { - printf( "Single #%d: Weight = %3d. ", i, pSingles[i]->Weight ); - printf( "Compl: " ); - if ( pSCompl[i] == NULL ) - printf( "None." ); - else - printf( "D Weight = %3d Sum = %3d", - pSCompl[i]->Weight, pSCompl[i]->Weight + pSingles[i]->Weight ); - printf( "\n" ); - } - printf( "\n" ); - for ( i = 0; i < nDoubles; i++ ) - { - printf( "Double #%d: Weight = %3d. ", i, pDoubles[i]->Weight ); - printf( "Compl: " ); - if ( pDComplS[i] == NULL && pDComplD[i] == NULL ) - printf( "None." ); - else if ( pDComplS[i] ) - printf( "S Weight = %3d Sum = %3d", - pDComplS[i]->Weight, pDComplS[i]->Weight + pDoubles[i]->Weight ); - else if ( pDComplD[i] ) - printf( "D Weight = %3d Sum = %3d", - pDComplD[i]->Weight, pDComplD[i]->Weight + pDoubles[i]->Weight ); - printf( "\n" ); - } - if ( WeightBest == -1 ) - printf( "Selected NONE\n" ); - else - { - printf( "Selected = %s. ", fBestS? "S": "D" ); - printf( "Number = %d. ", iNum ); - printf( "Weight = %d.\n", WeightBest ); - } - printf( "\n" ); -*/ - return WeightBest; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle ) -{ -// int * pValue2Node = p->pValue2Node; - int iVar1, iVar2; - int iVar1C, iVar2C; - // get the variables of this single div - iVar1 = pSingle->pVar1->iVar; - iVar2 = pSingle->pVar2->iVar; - iVar1C = Fxu_MatrixFindComplement( p, iVar1 ); - iVar2C = Fxu_MatrixFindComplement( p, iVar2 ); - if ( iVar1C == -1 || iVar2C == -1 ) - return NULL; - assert( iVar1C < iVar2C ); - return Fxu_MatrixFindDouble( p, &iVar1C, &iVar2C, 1, 1 ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble ) -{ -// int * pValue2Node = p->pValue2Node; - int piVarsC1[10], piVarsC2[10]; - int nVarsC1, nVarsC2; - int iVar1, iVar2, iVarTemp; - int iVar1C, iVar2C; - Fxu_Single * pSingle; - - // get the variables of this double div - Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 ); - assert( nVarsC1 == 1 ); - assert( nVarsC2 == 1 ); - iVar1 = piVarsC1[0]; - iVar2 = piVarsC2[0]; - assert( iVar1 < iVar2 ); - - iVar1C = Fxu_MatrixFindComplement( p, iVar1 ); - iVar2C = Fxu_MatrixFindComplement( p, iVar2 ); - if ( iVar1C == -1 || iVar2C == -1 ) - return NULL; - - // go through the queque and find this one -// assert( iVar1C < iVar2C ); - if ( iVar1C > iVar2C ) - { - iVarTemp = iVar1C; - iVar1C = iVar2C; - iVar2C = iVarTemp; - } - - Fxu_MatrixForEachSingle( p, pSingle ) - if ( pSingle->pVar1->iVar == iVar1C && pSingle->pVar2->iVar == iVar2C ) - return pSingle; - return NULL; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble ) -{ -// int * pValue2Node = p->pValue2Node; - int piVarsC1[10], piVarsC2[10]; - int nVarsC1, nVarsC2; - int iVar11, iVar12, iVar21, iVar22; - int iVar11C, iVar12C, iVar21C, iVar22C; - int RetValue; - - // get the variables of this double div - Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 ); - assert( nVarsC1 == 2 && nVarsC2 == 2 ); - - iVar11 = piVarsC1[0]; - iVar12 = piVarsC1[1]; - iVar21 = piVarsC2[0]; - iVar22 = piVarsC2[1]; - assert( iVar11 < iVar21 ); - - iVar11C = Fxu_MatrixFindComplement( p, iVar11 ); - iVar12C = Fxu_MatrixFindComplement( p, iVar12 ); - iVar21C = Fxu_MatrixFindComplement( p, iVar21 ); - iVar22C = Fxu_MatrixFindComplement( p, iVar22 ); - if ( iVar11C == -1 || iVar12C == -1 || iVar21C == -1 || iVar22C == -1 ) - return NULL; - if ( iVar11C != iVar21 || iVar12C != iVar22 || - iVar21C != iVar11 || iVar22C != iVar12 ) - return NULL; - - // a'b' + ab => a'b + ab' - // a'b + ab' => a'b' + ab - // swap the second pair in each cube - RetValue = piVarsC1[1]; - piVarsC1[1] = piVarsC2[1]; - piVarsC2[1] = RetValue; - - return Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, 2, 2 ); -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar ) -{ - return iVar ^ 1; -/* -// int * pValue2Node = p->pValue2Node; - int iVarC; - int iNode; - int Beg, End; - - // get the nodes - iNode = pValue2Node[iVar]; - // get the first node with the same var - for ( Beg = iVar; Beg >= 0; Beg-- ) - if ( pValue2Node[Beg] != iNode ) - { - Beg++; - break; - } - // get the last node with the same var - for ( End = iVar; ; End++ ) - if ( pValue2Node[End] != iNode ) - { - End--; - break; - } - - // if one of the vars is not binary, quit - if ( End - Beg > 1 ) - return -1; - - // get the complements - if ( iVar == Beg ) - iVarC = End; - else if ( iVar == End ) - iVarC = Beg; - else - { - assert( 0 ); - } - return iVarC; -*/ -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble, - int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 ) -{ - Fxu_Pair * pPair; - Fxu_Lit * pLit1, * pLit2; - int nLits1, nLits2; - - // get the first pair - pPair = pDouble->lPairs.pHead; - // init the parameters - nLits1 = 0; - nLits2 = 0; - pLit1 = pPair->pCube1->lLits.pHead; - pLit2 = pPair->pCube2->lLits.pHead; - while ( 1 ) - { - if ( pLit1 && pLit2 ) - { - if ( pLit1->iVar == pLit2->iVar ) - { // ensure cube-free - pLit1 = pLit1->pHNext; - pLit2 = pLit2->pHNext; - } - else if ( pLit1->iVar < pLit2->iVar ) - { - piVarsC1[nLits1++] = pLit1->iVar; - pLit1 = pLit1->pHNext; - } - else - { - piVarsC2[nLits2++] = pLit2->iVar; - pLit2 = pLit2->pHNext; - } - } - else if ( pLit1 && !pLit2 ) - { - piVarsC1[nLits1++] = pLit1->iVar; - pLit1 = pLit1->pHNext; - } - else if ( !pLit1 && pLit2 ) - { - piVarsC2[nLits2++] = pLit2->iVar; - pLit2 = pLit2->pHNext; - } - else - break; - } - *pnVarsC1 = nLits1; - *pnVarsC2 = nLits2; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Fxu_Double * Fxu_MatrixFindDouble( Fxu_Matrix * p, - int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 ) -{ - int piVarsC1_[100], piVarsC2_[100]; - int nVarsC1_, nVarsC2_, i; - Fxu_Double * pDouble; - Fxu_Pair * pPair; - unsigned Key; - - assert( nVarsC1 > 0 ); - assert( nVarsC2 > 0 ); - assert( piVarsC1[0] < piVarsC2[0] ); - - // get the hash key - Key = Fxu_PairHashKeyArray( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 ); - - // check if the divisor for this pair already exists - Key %= p->nTableSize; - Fxu_TableForEachDouble( p, Key, pDouble ) - { - pPair = pDouble->lPairs.pHead; - if ( pPair->nLits1 != nVarsC1 ) - continue; - if ( pPair->nLits2 != nVarsC2 ) - continue; - // get the cubes of this divisor - Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1_, piVarsC2_, &nVarsC1_, &nVarsC2_ ); - // compare lits of the first cube - for ( i = 0; i < nVarsC1; i++ ) - if ( piVarsC1[i] != piVarsC1_[i] ) - break; - if ( i != nVarsC1 ) - continue; - // compare lits of the second cube - for ( i = 0; i < nVarsC2; i++ ) - if ( piVarsC2[i] != piVarsC2_[i] ) - break; - if ( i != nVarsC2 ) - continue; - return pDouble; - } - return NULL; -} - - - - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_SelectSCD( Fxu_Matrix * p, int WeightLimit, Fxu_Var ** ppVar1, Fxu_Var ** ppVar2 ) -{ -// int * pValue2Node = p->pValue2Node; - Fxu_Var * pVar1; - Fxu_Var * pVar2, * pVarTemp; - Fxu_Lit * pLitV, * pLitH; - int Coin; - int CounterAll; - int CounterTest; - int WeightCur; - int WeightBest; - - CounterAll = 0; - CounterTest = 0; - - WeightBest = -10; - - // iterate through the columns in the matrix - Fxu_MatrixForEachVariable( p, pVar1 ) - { - // start collecting the affected vars - Fxu_MatrixRingVarsStart( p ); - - // go through all the literals of this variable - for ( pLitV = pVar1->lLits.pHead; pLitV; pLitV = pLitV->pVNext ) - { - // for this literal, go through all the horizontal literals - for ( pLitH = pLitV->pHNext; pLitH; pLitH = pLitH->pHNext ) - { - // get another variable - pVar2 = pLitH->pVar; - CounterAll++; - // skip the var if it is already used - if ( pVar2->pOrder ) - continue; - // skip the var if it belongs to the same node -// if ( pValue2Node[pVar1->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 ) - { - CounterTest++; - - // count the coincidence - Coin = Fxu_SingleCountCoincidence( p, pVar1, pVar2 ); - assert( Coin > 0 ); - - // get the new weight - WeightCur = Coin - 2; - - // compare the weights - if ( WeightBest < WeightCur ) - { - WeightBest = WeightCur; - *ppVar1 = pVar1; - *ppVar2 = pVar2; - } - } - // unmark the vars - Fxu_MatrixForEachVarInRingSafe( p, pVar2, pVarTemp ) - pVar2->pOrder = NULL; - Fxu_MatrixRingVarsReset( p ); - } - -// if ( WeightBest == WeightLimit ) -// return -1; - return WeightBest; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/fxu/fxuSingle.c b/src/opt/fxu/fxuSingle.c deleted file mode 100644 index 73d9a76c..00000000 --- a/src/opt/fxu/fxuSingle.c +++ /dev/null @@ -1,284 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuSingle.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Procedures to compute the set of single-cube divisors.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuSingle.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "fxuInt.h" -#include "vec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Fxu_MatrixComputeSinglesOneCollect( Fxu_Matrix * p, Fxu_Var * pVar, Vec_Ptr_t * vSingles ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes and adds all single-cube divisors to storage.] - - Description [This procedure should be called once when the matrix is - already contructed before the process of logic extraction begins..] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixComputeSingles( Fxu_Matrix * p, int fUse0, int nSingleMax ) -{ - 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 ); - 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 ); -} - -/**Function************************************************************* - - Synopsis [Adds the single-cube divisors associated with a new column.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ) -{ - 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 >= 0 ) -// Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur ); - if ( WeightCur >= p->nWeightLimit ) - Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur ); - } - // unmark the vars - Fxu_MatrixRingVarsUnmark( p ); -} - -/**Function************************************************************* - - Synopsis [Computes the coincidence count of two columns.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 ) -{ - Fxu_Lit * pLit1, * pLit2; - int Result; - - // compute the coincidence count - Result = 0; - pLit1 = pVar1->lLits.pHead; - pLit2 = pVar2->lLits.pHead; - while ( 1 ) - { - if ( pLit1 && pLit2 ) - { - if ( pLit1->pCube->pVar->iVar == pLit2->pCube->pVar->iVar ) - { // the variables are the same - if ( pLit1->iCube == pLit2->iCube ) - { // the literals are the same - pLit1 = pLit1->pVNext; - pLit2 = pLit2->pVNext; - // add this literal to the coincidence - Result++; - } - else if ( pLit1->iCube < pLit2->iCube ) - pLit1 = pLit1->pVNext; - else - pLit2 = pLit2->pVNext; - } - else if ( pLit1->pCube->pVar->iVar < pLit2->pCube->pVar->iVar ) - pLit1 = pLit1->pVNext; - else - pLit2 = pLit2->pVNext; - } - else if ( pLit1 && !pLit2 ) - pLit1 = pLit1->pVNext; - else if ( !pLit1 && pLit2 ) - pLit2 = pLit2->pVNext; - else - break; - } - return Result; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/fxu/fxuUpdate.c b/src/opt/fxu/fxuUpdate.c deleted file mode 100644 index 274f79f6..00000000 --- a/src/opt/fxu/fxuUpdate.c +++ /dev/null @@ -1,806 +0,0 @@ -/**CFile**************************************************************** - - FileName [fxuUpdate.c] - - PackageName [MVSIS 2.0: Multi-valued logic synthesis system.] - - Synopsis [Updating the sparse matrix when divisors are accepted.] - - Author [MVSIS Group] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - February 1, 2003.] - - Revision [$Id: fxuUpdate.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "fxuInt.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar ); -static void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv ); -static void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem ); -static void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew ); - -static void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes ); -static int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 ); -static void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble ); - -static void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube ); -static void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube ); -static void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p ); -static void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Updates the matrix after selecting two divisors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_Update( Fxu_Matrix * p, Fxu_Single * pSingle, Fxu_Double * pDouble ) -{ - Fxu_Cube * pCube, * pCubeNew; - Fxu_Var * pVarC, * pVarD; - Fxu_Var * pVar1, * pVar2; - - // consider trivial cases - if ( pSingle == NULL ) - { - assert( pDouble->Weight == Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ) ); - Fxu_UpdateDouble( p ); - return; - } - if ( pDouble == NULL ) - { - assert( pSingle->Weight == Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ) ); - Fxu_UpdateSingle( p ); - return; - } - - // get the variables of the single - pVar1 = pSingle->pVar1; - pVar2 = pSingle->pVar2; - - // remove the best double from the heap - Fxu_HeapDoubleDelete( p->pHeapDouble, pDouble ); - // remove the best divisor from the table - Fxu_ListTableDelDivisor( p, pDouble ); - - // create two new columns (vars) - Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 ); - // create one new row (cube) - pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 ); - pCubeNew->pFirst = pCubeNew; - // set the first cube of the positive var - pVarD->pFirst = pCubeNew; - - // start collecting the affected vars and cubes - Fxu_MatrixRingCubesStart( p ); - Fxu_MatrixRingVarsStart( p ); - // add the vars - Fxu_MatrixRingVarsAdd( p, pVar1 ); - Fxu_MatrixRingVarsAdd( p, pVar2 ); - // remove the literals and collect the affected cubes - // remove the divisors associated with this cube - // add to the affected cube the literal corresponding to the new column - Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD ); - // replace each two cubes of the pair by one new cube - // the new cube contains the base and the new literal - Fxu_UpdateDoublePairs( p, pDouble, pVarC ); - // stop collecting the affected vars and cubes - Fxu_MatrixRingCubesStop( p ); - Fxu_MatrixRingVarsStop( p ); - - // add the literals to the new cube - assert( pVar1->iVar < pVar2->iVar ); - assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 ); - Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 ); - Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 ); - - // create new doubles; we cannot add them in the same loop - // because we first have to create *all* new cubes for each node - Fxu_MatrixForEachCubeInRing( p, pCube ) - Fxu_UpdateAddNewDoubles( p, pCube ); - // update the singles after removing some literals - Fxu_UpdateCleanOldSingles( p ); - - // undo the temporary rings with cubes and vars - Fxu_MatrixRingCubesUnmark( p ); - Fxu_MatrixRingVarsUnmark( p ); - // we should undo the rings before creating new singles - - // create new singles - Fxu_UpdateAddNewSingles( p, pVarC ); - Fxu_UpdateAddNewSingles( p, pVarD ); - - // recycle the divisor - MEM_FREE_FXU( p, Fxu_Double, 1, pDouble ); - p->nDivs3++; -} - -/**Function************************************************************* - - Synopsis [Updates after accepting single cube divisor.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdateSingle( Fxu_Matrix * p ) -{ - Fxu_Single * pSingle; - Fxu_Cube * pCube, * pCubeNew; - Fxu_Var * pVarC, * pVarD; - Fxu_Var * pVar1, * pVar2; - - // read the best divisor from the heap - pSingle = Fxu_HeapSingleReadMax( p->pHeapSingle ); - // get the variables of this single-cube divisor - pVar1 = pSingle->pVar1; - pVar2 = pSingle->pVar2; - - // create two new columns (vars) - Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 1 ); - // create one new row (cube) - pCubeNew = Fxu_MatrixAddCube( p, pVarD, 0 ); - pCubeNew->pFirst = pCubeNew; - // set the first cube - pVarD->pFirst = pCubeNew; - - // start collecting the affected vars and cubes - Fxu_MatrixRingCubesStart( p ); - Fxu_MatrixRingVarsStart( p ); - // add the vars - Fxu_MatrixRingVarsAdd( p, pVar1 ); - Fxu_MatrixRingVarsAdd( p, pVar2 ); - // remove the literals and collect the affected cubes - // remove the divisors associated with this cube - // add to the affected cube the literal corresponding to the new column - Fxu_UpdateMatrixSingleClean( p, pVar1, pVar2, pVarD ); - // stop collecting the affected vars and cubes - Fxu_MatrixRingCubesStop( p ); - Fxu_MatrixRingVarsStop( p ); - - // add the literals to the new cube - assert( pVar1->iVar < pVar2->iVar ); - assert( Fxu_SingleCountCoincidence( p, pVar1, pVar2 ) == 0 ); - Fxu_MatrixAddLiteral( p, pCubeNew, pVar1 ); - Fxu_MatrixAddLiteral( p, pCubeNew, pVar2 ); - - // create new doubles; we cannot add them in the same loop - // because we first have to create *all* new cubes for each node - Fxu_MatrixForEachCubeInRing( p, pCube ) - Fxu_UpdateAddNewDoubles( p, pCube ); - // update the singles after removing some literals - Fxu_UpdateCleanOldSingles( p ); - // we should undo the rings before creating new singles - - // unmark the cubes - Fxu_MatrixRingCubesUnmark( p ); - Fxu_MatrixRingVarsUnmark( p ); - - // create new singles - Fxu_UpdateAddNewSingles( p, pVarC ); - Fxu_UpdateAddNewSingles( p, pVarD ); - p->nDivs1++; -} - -/**Function************************************************************* - - Synopsis [Updates the matrix after accepting a double cube divisor.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdateDouble( Fxu_Matrix * p ) -{ - Fxu_Double * pDiv; - Fxu_Cube * pCube, * pCubeNew1, * pCubeNew2; - Fxu_Var * pVarC, * pVarD; - - // remove the best divisor from the heap - pDiv = Fxu_HeapDoubleGetMax( p->pHeapDouble ); - // remove the best divisor from the table - Fxu_ListTableDelDivisor( p, pDiv ); - - // create two new columns (vars) - Fxu_UpdateCreateNewVars( p, &pVarC, &pVarD, 2 ); - // create two new rows (cubes) - pCubeNew1 = Fxu_MatrixAddCube( p, pVarD, 0 ); - pCubeNew1->pFirst = pCubeNew1; - pCubeNew2 = Fxu_MatrixAddCube( p, pVarD, 1 ); - pCubeNew2->pFirst = pCubeNew1; - // set the first cube - pVarD->pFirst = pCubeNew1; - - // add the literals to the new cubes - Fxu_UpdateMatrixDoubleCreateCubes( p, pCubeNew1, pCubeNew2, pDiv ); - - // start collecting the affected cubes and vars - Fxu_MatrixRingCubesStart( p ); - Fxu_MatrixRingVarsStart( p ); - // replace each two cubes of the pair by one new cube - // the new cube contains the base and the new literal - Fxu_UpdateDoublePairs( p, pDiv, pVarD ); - // stop collecting the affected cubes and vars - Fxu_MatrixRingCubesStop( p ); - Fxu_MatrixRingVarsStop( p ); - - // create new doubles; we cannot add them in the same loop - // because we first have to create *all* new cubes for each node - Fxu_MatrixForEachCubeInRing( p, pCube ) - Fxu_UpdateAddNewDoubles( p, pCube ); - // update the singles after removing some literals - Fxu_UpdateCleanOldSingles( p ); - - // undo the temporary rings with cubes and vars - Fxu_MatrixRingCubesUnmark( p ); - Fxu_MatrixRingVarsUnmark( p ); - // we should undo the rings before creating new singles - - // create new singles - Fxu_UpdateAddNewSingles( p, pVarC ); - Fxu_UpdateAddNewSingles( p, pVarD ); - - // recycle the divisor - MEM_FREE_FXU( p, Fxu_Double, 1, pDiv ); - p->nDivs2++; -} - -/**Function************************************************************* - - Synopsis [Update the pairs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdateDoublePairs( Fxu_Matrix * p, Fxu_Double * pDouble, Fxu_Var * pVar ) -{ - Fxu_Pair * pPair; - Fxu_Cube * pCubeUse, * pCubeRem; - int i; - - // collect and sort the pairs - Fxu_UpdatePairsSort( p, pDouble ); -// for ( i = 0; i < p->nPairsTemp; i++ ) - for ( i = 0; i < p->vPairs->nSize; i++ ) - { - // get the pair -// pPair = p->pPairsTemp[i]; - pPair = p->vPairs->pArray[i]; - // out of the two cubes, select the one which comes earlier - pCubeUse = Fxu_PairMinCube( pPair ); - pCubeRem = Fxu_PairMaxCube( pPair ); - // collect the affected cube - assert( pCubeUse->pOrder == NULL ); - Fxu_MatrixRingCubesAdd( p, pCubeUse ); - - // remove some literals from pCubeUse and all literals from pCubeRem - Fxu_UpdateMatrixDoubleClean( p, pCubeUse, pCubeRem ); - // add a literal that depends on the new variable - Fxu_MatrixAddLiteral( p, pCubeUse, pVar ); - // check the literal count - assert( pCubeUse->lLits.nItems == pPair->nBase + 1 ); - assert( pCubeRem->lLits.nItems == 0 ); - - // update the divisors by removing useless pairs - Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeUse ); - Fxu_UpdateCleanOldDoubles( p, pDouble, pCubeRem ); - // remove the pair - MEM_FREE_FXU( p, Fxu_Pair, 1, pPair ); - } - p->vPairs->nSize = 0; -} - -/**Function************************************************************* - - Synopsis [Add two cubes corresponding to the given double-cube divisor.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdateMatrixDoubleCreateCubes( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2, Fxu_Double * pDiv ) -{ - Fxu_Lit * pLit1, * pLit2; - Fxu_Pair * pPair; - int nBase, nLits1, nLits2; - - // fill in the SOP and copy the fanins - nBase = nLits1 = nLits2 = 0; - pPair = pDiv->lPairs.pHead; - pLit1 = pPair->pCube1->lLits.pHead; - pLit2 = pPair->pCube2->lLits.pHead; - while ( 1 ) - { - if ( pLit1 && pLit2 ) - { - if ( pLit1->iVar == pLit2->iVar ) - { // skip the cube free part - pLit1 = pLit1->pHNext; - pLit2 = pLit2->pHNext; - nBase++; - } - else if ( pLit1->iVar < pLit2->iVar ) - { // add literal to the first cube - Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar ); - // move to the next literal in this cube - pLit1 = pLit1->pHNext; - nLits1++; - } - else - { // add literal to the second cube - Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar ); - // move to the next literal in this cube - pLit2 = pLit2->pHNext; - nLits2++; - } - } - else if ( pLit1 && !pLit2 ) - { // add literal to the first cube - Fxu_MatrixAddLiteral( p, pCube1, pLit1->pVar ); - // move to the next literal in this cube - pLit1 = pLit1->pHNext; - nLits1++; - } - else if ( !pLit1 && pLit2 ) - { // add literal to the second cube - Fxu_MatrixAddLiteral( p, pCube2, pLit2->pVar ); - // move to the next literal in this cube - pLit2 = pLit2->pHNext; - nLits2++; - } - else - break; - } - assert( pPair->nLits1 == nLits1 ); - assert( pPair->nLits2 == nLits2 ); - assert( pPair->nBase == nBase ); -} - - -/**Function************************************************************* - - Synopsis [Create the node equal to double-cube divisor.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdateMatrixDoubleClean( Fxu_Matrix * p, Fxu_Cube * pCubeUse, Fxu_Cube * pCubeRem ) -{ - Fxu_Lit * pLit1, * bLit1Next; - Fxu_Lit * pLit2, * bLit2Next; - - // initialize the starting literals - pLit1 = pCubeUse->lLits.pHead; - pLit2 = pCubeRem->lLits.pHead; - bLit1Next = pLit1? pLit1->pHNext: NULL; - bLit2Next = pLit2? pLit2->pHNext: NULL; - // go through the pair and remove the literals in the base - // from the first cube and all literals from the second cube - while ( 1 ) - { - if ( pLit1 && pLit2 ) - { - if ( pLit1->iVar == pLit2->iVar ) - { // this literal is present in both cubes - it belongs to the base - // mark the affected var - if ( pLit1->pVar->pOrder == NULL ) - Fxu_MatrixRingVarsAdd( p, pLit1->pVar ); - // leave the base in pCubeUse; delete it from pCubeRem - Fxu_MatrixDelLiteral( p, pLit2 ); - // step to the next literals - pLit1 = bLit1Next; - pLit2 = bLit2Next; - bLit1Next = pLit1? pLit1->pHNext: NULL; - bLit2Next = pLit2? pLit2->pHNext: NULL; - } - else if ( pLit1->iVar < pLit2->iVar ) - { // this literal is present in pCubeUse - remove it - // mark the affected var - if ( pLit1->pVar->pOrder == NULL ) - Fxu_MatrixRingVarsAdd( p, pLit1->pVar ); - // delete this literal - Fxu_MatrixDelLiteral( p, pLit1 ); - // step to the next literals - pLit1 = bLit1Next; - bLit1Next = pLit1? pLit1->pHNext: NULL; - } - else - { // this literal is present in pCubeRem - remove it - // mark the affected var - if ( pLit2->pVar->pOrder == NULL ) - Fxu_MatrixRingVarsAdd( p, pLit2->pVar ); - // delete this literal - Fxu_MatrixDelLiteral( p, pLit2 ); - // step to the next literals - pLit2 = bLit2Next; - bLit2Next = pLit2? pLit2->pHNext: NULL; - } - } - else if ( pLit1 && !pLit2 ) - { // this literal is present in pCubeUse - leave it - // mark the affected var - if ( pLit1->pVar->pOrder == NULL ) - Fxu_MatrixRingVarsAdd( p, pLit1->pVar ); - // delete this literal - Fxu_MatrixDelLiteral( p, pLit1 ); - // step to the next literals - pLit1 = bLit1Next; - bLit1Next = pLit1? pLit1->pHNext: NULL; - } - else if ( !pLit1 && pLit2 ) - { // this literal is present in pCubeRem - remove it - // mark the affected var - if ( pLit2->pVar->pOrder == NULL ) - Fxu_MatrixRingVarsAdd( p, pLit2->pVar ); - // delete this literal - Fxu_MatrixDelLiteral( p, pLit2 ); - // step to the next literals - pLit2 = bLit2Next; - bLit2Next = pLit2? pLit2->pHNext: NULL; - } - else - break; - } -} - -/**Function************************************************************* - - Synopsis [Updates the matrix after selecting a single cube divisor.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdateMatrixSingleClean( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2, Fxu_Var * pVarNew ) -{ - Fxu_Lit * pLit1, * bLit1Next; - Fxu_Lit * pLit2, * bLit2Next; - - // initialize the starting literals - pLit1 = pVar1->lLits.pHead; - pLit2 = pVar2->lLits.pHead; - bLit1Next = pLit1? pLit1->pVNext: NULL; - bLit2Next = pLit2? pLit2->pVNext: NULL; - while ( 1 ) - { - if ( pLit1 && pLit2 ) - { - if ( pLit1->pCube->pVar->iVar == pLit2->pCube->pVar->iVar ) - { // these literals coincide - if ( pLit1->iCube == pLit2->iCube ) - { // these literals coincide - - // collect the affected cube - assert( pLit1->pCube->pOrder == NULL ); - Fxu_MatrixRingCubesAdd( p, pLit1->pCube ); - - // add the literal to this cube corresponding to the new column - Fxu_MatrixAddLiteral( p, pLit1->pCube, pVarNew ); - // clean the old cubes - Fxu_UpdateCleanOldDoubles( p, NULL, pLit1->pCube ); - - // remove the literals - Fxu_MatrixDelLiteral( p, pLit1 ); - Fxu_MatrixDelLiteral( p, pLit2 ); - - // go to the next literals - pLit1 = bLit1Next; - pLit2 = bLit2Next; - bLit1Next = pLit1? pLit1->pVNext: NULL; - bLit2Next = pLit2? pLit2->pVNext: NULL; - } - else if ( pLit1->iCube < pLit2->iCube ) - { - pLit1 = bLit1Next; - bLit1Next = pLit1? pLit1->pVNext: NULL; - } - else - { - pLit2 = bLit2Next; - bLit2Next = pLit2? pLit2->pVNext: NULL; - } - } - else if ( pLit1->pCube->pVar->iVar < pLit2->pCube->pVar->iVar ) - { - pLit1 = bLit1Next; - bLit1Next = pLit1? pLit1->pVNext: NULL; - } - else - { - pLit2 = bLit2Next; - bLit2Next = pLit2? pLit2->pVNext: NULL; - } - } - else if ( pLit1 && !pLit2 ) - { - pLit1 = bLit1Next; - bLit1Next = pLit1? pLit1->pVNext: NULL; - } - else if ( !pLit1 && pLit2 ) - { - pLit2 = bLit2Next; - bLit2Next = pLit2? pLit2->pVNext: NULL; - } - else - break; - } -} - -/**Function************************************************************* - - Synopsis [Sort the pairs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdatePairsSort( Fxu_Matrix * p, Fxu_Double * pDouble ) -{ - Fxu_Pair * pPair; - // order the pairs by the first cube to ensure that new literals are added - // to the matrix from top to bottom - collect pairs into the array - p->vPairs->nSize = 0; - Fxu_DoubleForEachPair( pDouble, pPair ) - Vec_PtrPush( p->vPairs, pPair ); - if ( p->vPairs->nSize < 2 ) - return; - // sort - qsort( (void *)p->vPairs->pArray, p->vPairs->nSize, sizeof(Fxu_Pair *), - (int (*)(const void *, const void *)) Fxu_UpdatePairCompare ); - assert( Fxu_UpdatePairCompare( (Fxu_Pair**)p->vPairs->pArray, (Fxu_Pair**)p->vPairs->pArray + p->vPairs->nSize - 1 ) < 0 ); -} - -/**Function************************************************************* - - Synopsis [Compares the vars by their number.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Fxu_UpdatePairCompare( Fxu_Pair ** ppP1, Fxu_Pair ** ppP2 ) -{ - Fxu_Cube * pC1 = (*ppP1)->pCube1; - Fxu_Cube * pC2 = (*ppP2)->pCube1; - int iP1CubeMin, iP2CubeMin; - if ( pC1->pVar->iVar < pC2->pVar->iVar ) - return -1; - if ( pC1->pVar->iVar > pC2->pVar->iVar ) - return 1; - iP1CubeMin = Fxu_PairMinCubeInt( *ppP1 ); - iP2CubeMin = Fxu_PairMinCubeInt( *ppP2 ); - if ( iP1CubeMin < iP2CubeMin ) - return -1; - if ( iP1CubeMin > iP2CubeMin ) - return 1; - assert( 0 ); - return 0; -} - - -/**Function************************************************************* - - Synopsis [Create new variables.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdateCreateNewVars( Fxu_Matrix * p, Fxu_Var ** ppVarC, Fxu_Var ** ppVarD, int nCubes ) -{ - Fxu_Var * pVarC, * pVarD; - - // add a new column for the complement - pVarC = Fxu_MatrixAddVar( p ); - pVarC->nCubes = 0; - // add a new column for the divisor - pVarD = Fxu_MatrixAddVar( p ); - pVarD->nCubes = nCubes; - - // mark this entry in the Value2Node array -// assert( p->pValue2Node[pVarC->iVar] > 0 ); -// p->pValue2Node[pVarD->iVar ] = p->pValue2Node[pVarC->iVar]; -// p->pValue2Node[pVarD->iVar+1] = p->pValue2Node[pVarC->iVar]+1; - - *ppVarC = pVarC; - *ppVarD = pVarD; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdateCleanOldDoubles( Fxu_Matrix * p, Fxu_Double * pDiv, Fxu_Cube * pCube ) -{ - Fxu_Double * pDivCur; - Fxu_Pair * pPair; - int i; - - // if the cube is a recently introduced one - // it does not have pairs allocated - // in this case, there is nothing to update - if ( pCube->pVar->ppPairs == NULL ) - return; - - // go through all the pairs of this cube - Fxu_CubeForEachPair( pCube, pPair, i ) - { - // get the divisor of this pair - pDivCur = pPair->pDiv; - // skip the current divisor - if ( pDivCur == pDiv ) - continue; - // remove this pair - Fxu_ListDoubleDelPair( pDivCur, pPair ); - // the divisor may have become useless by now - if ( pDivCur->lPairs.nItems == 0 ) - { - assert( pDivCur->Weight == pPair->nBase - 1 ); - Fxu_HeapDoubleDelete( p->pHeapDouble, pDivCur ); - Fxu_MatrixDelDivisor( p, pDivCur ); - } - else - { - // update the divisor's weight - pDivCur->Weight -= pPair->nLits1 + pPair->nLits2 - 1 + pPair->nBase; - Fxu_HeapDoubleUpdate( p->pHeapDouble, pDivCur ); - } - MEM_FREE_FXU( p, Fxu_Pair, 1, pPair ); - } - // finally erase all the pair info associated with this cube - Fxu_PairClearStorage( pCube ); -} - -/**Function************************************************************* - - Synopsis [Adds the new divisors that depend on the cube.] - - Description [Go through all the non-empty cubes of this cover - (except the given cube) and, for each of them, add the new divisor - with the given cube.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdateAddNewDoubles( Fxu_Matrix * p, Fxu_Cube * pCube ) -{ - Fxu_Cube * pTemp; - assert( pCube->pOrder ); - - // if the cube is a recently introduced one - // it does not have pairs allocated - // in this case, there is nothing to update - if ( pCube->pVar->ppPairs == NULL ) - return; - - for ( pTemp = pCube->pFirst; pTemp->pVar == pCube->pVar; pTemp = pTemp->pNext ) - { - // do not add pairs with the empty cubes - if ( pTemp->lLits.nItems == 0 ) - continue; - // to prevent adding duplicated pairs of the new cubes - // do not add the pair, if the current cube is marked - if ( pTemp->pOrder && pTemp >= pCube ) - continue; - Fxu_MatrixAddDivisor( p, pTemp, pCube ); - } -} - -/**Function************************************************************* - - Synopsis [Removes old single cube divisors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -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 ) - { - pSingle->Weight = WeightNew; - Fxu_HeapSingleUpdate( p->pHeapSingle, pSingle ); - } - else - { - Fxu_HeapSingleDelete( p->pHeapSingle, pSingle ); - Fxu_ListMatrixDelSingle( p, pSingle ); - MEM_FREE_FXU( p, Fxu_Single, 1, pSingle ); - } - } - } -// printf( "Called procedure %d times.\n", Counter ); -} - -/**Function************************************************************* - - Synopsis [Updates the single cube divisors.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Fxu_UpdateAddNewSingles( Fxu_Matrix * p, Fxu_Var * pVar ) -{ - Fxu_MatrixComputeSinglesOne( p, pVar ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/fxu/module.make b/src/opt/fxu/module.make deleted file mode 100644 index dd8acd40..00000000 --- a/src/opt/fxu/module.make +++ /dev/null @@ -1,12 +0,0 @@ -SRC += src/opt/fxu/fxu.c \ - src/opt/fxu/fxuCreate.c \ - src/opt/fxu/fxuHeapD.c \ - src/opt/fxu/fxuHeapS.c \ - src/opt/fxu/fxuList.c \ - src/opt/fxu/fxuMatrix.c \ - src/opt/fxu/fxuPair.c \ - src/opt/fxu/fxuPrint.c \ - src/opt/fxu/fxuReduce.c \ - src/opt/fxu/fxuSelect.c \ - src/opt/fxu/fxuSingle.c \ - src/opt/fxu/fxuUpdate.c 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 8b8028e3..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 ); - } - if ( p->pObj->Id == 33 && i == 0 ) - { - int x = 0; - } - - // 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 ); - // 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 b2a743bd..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 27e9b3ea..00000000 --- a/src/opt/res/resCore.c +++ /dev/null @@ -1,415 +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( 512 ); - 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); - - // 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 ( 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/module.make b/src/opt/rwr/module.make deleted file mode 100644 index 077a3c01..00000000 --- a/src/opt/rwr/module.make +++ /dev/null @@ -1,7 +0,0 @@ -SRC += src/opt/rwr/rwrDec.c \ - src/opt/rwr/rwrEva.c \ - src/opt/rwr/rwrExp.c \ - src/opt/rwr/rwrLib.c \ - src/opt/rwr/rwrMan.c \ - src/opt/rwr/rwrPrint.c \ - src/opt/rwr/rwrUtil.c diff --git a/src/opt/rwr/rwr.h b/src/opt/rwr/rwr.h deleted file mode 100644 index f24f9535..00000000 --- a/src/opt/rwr/rwr.h +++ /dev/null @@ -1,169 +0,0 @@ -/**CFile**************************************************************** - - FileName [rwr.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [DAG-aware AIG rewriting package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: rwr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#ifndef __RWR_H__ -#define __RWR_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -#include "abc.h" -#include "cut.h" - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -#define RWR_LIMIT 1048576/4 // ((1 << 20) - -typedef struct Rwr_Man_t_ Rwr_Man_t; -typedef struct Rwr_Node_t_ Rwr_Node_t; - -struct Rwr_Man_t_ -{ - // internal lookups - int nFuncs; // number of four var functions - unsigned short * puCanons; // canonical forms - 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 - Vec_Ptr_t * vForest; // all the nodes - Rwr_Node_t ** pTable; // the hash table of nodes by their canonical form - Vec_Vec_t * vClasses; // the nodes of the equivalence classes - Extra_MmFixed_t * pMmNode; // memory for nodes and cuts - // statistical variables - int nTravIds; // the counter of traversal IDs - int nConsidered; // the number of nodes considered - int nAdded; // the number of nodes added to lists - 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) - 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; - int nSubgraphs; - // runtime statistics - int timeStart; - int timeCut; - int timeRes; - int timeEval; - int timeMffc; - int timeUpdate; - int timeTotal; -}; - -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 - unsigned fUsed : 1; // mark - unsigned fExor : 1; // mark - Rwr_Node_t * p0; // first child - Rwr_Node_t * p1; // second child - Rwr_Node_t * pNext; // next in the table -}; - -// 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)); } - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -/*=== 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 ); -/*=== rwrLib.c ========================================================*/ -extern void Rwr_ManPrecompute( Rwr_Man_t * p ); -extern Rwr_Node_t * Rwr_ManAddVar( Rwr_Man_t * p, unsigned uTruth, int fPrecompute ); -extern Rwr_Node_t * Rwr_ManAddNode( Rwr_Man_t * p, Rwr_Node_t * p0, Rwr_Node_t * p1, int fExor, int Level, int Volume ); -extern int Rwr_ManNodeVolume( Rwr_Man_t * p, Rwr_Node_t * p0, Rwr_Node_t * p1 ); -extern void Rwr_ManIncTravId( Rwr_Man_t * p ); -/*=== rwrMan.c ========================================================*/ -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 ); -/*=== rwrUtil.c ========================================================*/ -extern void Rwr_ManWriteToArray( Rwr_Man_t * p ); -extern void Rwr_ManLoadFromArray( Rwr_Man_t * p, int fVerbose ); -extern void Rwr_ManWriteToFile( Rwr_Man_t * p, char * pFileName ); -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 /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/rwr/rwrDec.c b/src/opt/rwr/rwrDec.c deleted file mode 100644 index ef7af34f..00000000 --- a/src/opt/rwr/rwrDec.c +++ /dev/null @@ -1,150 +0,0 @@ -/**CFile**************************************************************** - - FileName [rwrDec.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [DAG-aware AIG rewriting package.] - - Synopsis [Evaluation and decomposition procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: rwrDec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "rwr.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -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************************************************************* - - Synopsis [Preprocesses computed library of subgraphs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManPreprocess( Rwr_Man_t * p ) -{ - Dec_Graph_t * pGraph; - 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++ ) - { - if ( p->pTable[i] == NULL ) - continue; - // consider all implementations of this function - for ( pNode = p->pTable[i]; pNode; pNode = pNode->pNext ) - { - 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 - Vec_VecForEachEntry( p->vClasses, pNode, i, k ) - { - pGraph = Rwr_NodePreprocess( p, pNode ); - pNode->pNext = (Rwr_Node_t *)pGraph; - assert( pNode->uTruth == (Dec_GraphDeriveTruth(pGraph) & 0xFFFF) ); - } -} - -/**Function************************************************************* - - Synopsis [Preprocesses subgraphs rooted at this node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Graph_t * Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode ) -{ - Dec_Graph_t * pGraph; - Dec_Edge_t eRoot; - assert( !Rwr_IsComplement(pNode) ); - // consider constant - if ( pNode->uTruth == 0 ) - return Dec_GraphCreateConst0(); - // consider the case of elementary var - if ( pNode->uTruth == 0x00FF ) - return Dec_GraphCreateLeaf( 3, 4, 1 ); - // start the subgraphs - pGraph = Dec_GraphCreate( 4 ); - // collect the nodes - Rwr_ManIncTravId( p ); - eRoot = Rwr_TravCollect_rec( p, pNode, pGraph ); - Dec_GraphSetRoot( pGraph, eRoot ); - return pGraph; -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Dec_Edge_t Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Dec_Graph_t * pGraph ) -{ - Dec_Edge_t eNode0, eNode1, eNode; - // elementary variable - if ( pNode->fUsed ) - return Dec_EdgeCreate( pNode->Id - 1, 0 ); - // previously visited node - if ( pNode->TravId == p->nTravIds ) - return Dec_IntToEdge( pNode->Volume ); - pNode->TravId = p->nTravIds; - // solve for children - eNode0 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p0), pGraph ); - if ( Rwr_IsComplement(pNode->p0) ) - eNode0.fCompl = !eNode0.fCompl; - eNode1 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p1), pGraph ); - if ( Rwr_IsComplement(pNode->p1) ) - eNode1.fCompl = !eNode1.fCompl; - // create the decomposition node(s) - if ( pNode->fExor ) - eNode = Dec_GraphAddNodeXor( pGraph, eNode0, eNode1, 0 ); - else - eNode = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 ); - // save the result - pNode->Volume = Dec_EdgeToInt( eNode ); - return eNode; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/rwr/rwrEva.c b/src/opt/rwr/rwrEva.c deleted file mode 100644 index f46c16c0..00000000 --- a/src/opt/rwr/rwrEva.c +++ /dev/null @@ -1,587 +0,0 @@ -/**CFile**************************************************************** - - FileName [rwrDec.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [DAG-aware AIG rewriting package.] - - Synopsis [Evaluation and decomposition procedures.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: rwrDec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "rwr.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// 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 ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Performs rewriting for one node.] - - Description [This procedure considers all the cuts computed for the node - and tries to rewrite each of them using the "forest" of different AIG - structures precomputed and stored in the RWR manager. - Determines the best rewriting and computes the gain in the number of AIG - nodes in the final network. In the end, p->vFanins contains information - about the best cut that can be used for rewriting, while p->pGraph gives - the decomposition dag (represented using decomposition graph data structure). - Returns gain in the number of nodes or -1 if node cannot be rewritten.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUpdateLevel, int fUseZeros, int fPlaceEnable ) -{ - int fVeryVerbose = 0; - Dec_Graph_t * pGraph; - Cut_Cut_t * pCut;//, * pTemp; - Abc_Obj_t * pFanin; - unsigned uPhase, uTruthBest, uTruth; - char * pPerm; - int Required, nNodesSaved, nNodesSaveCur; - int i, GainCur, GainBest = -1; - int clk, clk2;//, Counter; - - p->nNodesConsidered++; - // get the required times - Required = fUpdateLevel? Abc_ObjRequiredLevel(pNode) : ABC_INFINITY; - - // get the node's cuts -clk = clock(); - pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0, 0 ); - 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 ) - { - // 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]; - // collect fanins with the corresponding permutation/phase - Vec_PtrClear( p->vFaninsCur ); - Vec_PtrFill( p->vFaninsCur, (int)pCut->nLeaves, 0 ); - for ( i = 0; i < (int)pCut->nLeaves; i++ ) - { - pFanin = Abc_NtkObj( pNode->pNtk, pCut->pLeaves[pPerm[i]] ); - if ( pFanin == NULL ) - break; - pFanin = Abc_ObjNotCond(pFanin, ((uPhase & (1<<i)) > 0) ); - Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin ); - } - if ( i != (int)pCut->nLeaves ) - { - p->nCutsBad++; - continue; - } - 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 ); - // 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 ); -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); - // collect fanins in the - Vec_PtrClear( p->vFanins ); - Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) - Vec_PtrPush( p->vFanins, pFanin ); - } - } -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->nNodesGained += GainBest; - if ( fUseZeros || GainBest > 0 ) - { - p->nNodesRewritten++; - } - - // report the progress - if ( fVeryVerbose && GainBest > 0 ) - { - 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( "\n" ); - } - return GainBest; -} - -/**Function************************************************************* - - Synopsis [Evaluates the cut.] - - Description [] - - SideEffects [] - - 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 ) -{ - 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] ); - p->nSubgraphs += vSubgraphs->nSize; - // determine the best subgraph - GainBest = -1; - CostBest = ABC_INFINITY; - Vec_PtrForEachEntry( vSubgraphs, pNode, i ) - { - // get the current graph - pGraphCur = (Dec_Graph_t *)pNode->pNext; - // copy the leaves - Vec_PtrForEachEntry( vFaninsCur, pFanin, k ) - Dec_GraphNode(pGraphCur, k)->pFunc = pFanin; - // detect how many unlabeled nodes will be reused - nNodesAdded = Dec_GraphToNetworkCount( pRoot, pGraphCur, nNodesSaved, LevelMax ); - 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 ) - { - GainBest = nNodesSaved - nNodesAdded; - pGraphBest = pGraphCur; - - // score the graph - if ( nNodesSaved - nNodesAdded > 0 ) - { - pNode->nScore++; - pNode->nGain += GainBest; - pNode->nAdded += nNodesAdded; - } - } - } - } - if ( GainBest == -1 ) - return NULL; - *pGainBest = GainBest; - 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 deleted file mode 100644 index 2d00bb1c..00000000 --- a/src/opt/rwr/rwrExp.c +++ /dev/null @@ -1,333 +0,0 @@ -/**CFile**************************************************************** - - FileName [rwrExp.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [DAG-aware AIG rewriting package.] - - Synopsis [Computation of practically used NN-classes of 4-input cuts.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: rwrExp.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "rwr.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Rwr_Man4_t_ Rwr_Man4_t; -struct Rwr_Man4_t_ -{ - // internal lookups - int nFuncs; // the number of four-var functions - unsigned short * puCanons; // canonical forms - int * pnCounts; // the counters of functions in each class - int nConsidered; // the number of nodes considered - int nClasses; // the number of NN classes -}; - -typedef struct Rwr_Man5_t_ Rwr_Man5_t; -struct Rwr_Man5_t_ -{ - // internal lookups - stmm_table * tTableNN; // the NN canonical forms - stmm_table * tTableNPN; // the NPN canonical forms -}; - -static Rwr_Man4_t * s_pManRwrExp4 = NULL; -static Rwr_Man5_t * s_pManRwrExp5 = NULL; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Collects stats about 4-var functions appearing in netlists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwt_Man4ExploreStart() -{ - Rwr_Man4_t * p; - p = ALLOC( Rwr_Man4_t, 1 ); - memset( p, 0, sizeof(Rwr_Man4_t) ); - // canonical forms - p->nFuncs = (1<<16); - // canonical forms, phases, perms - Extra_Truth4VarNPN( &p->puCanons, NULL, NULL, NULL ); - // counters - p->pnCounts = ALLOC( int, p->nFuncs ); - memset( p->pnCounts, 0, sizeof(int) * p->nFuncs ); - s_pManRwrExp4 = p; -} - -/**Function************************************************************* - - Synopsis [Collects stats about 4-var functions appearing in netlists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwt_Man4ExploreCount( unsigned uTruth ) -{ - assert( uTruth < (1<<16) ); - s_pManRwrExp4->pnCounts[ s_pManRwrExp4->puCanons[uTruth] ]++; -} - -/**Function************************************************************* - - Synopsis [Collects stats about 4-var functions appearing in netlists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwt_Man4ExplorePrint() -{ - FILE * pFile; - int i, CountMax, CountWrite, nCuts, nClasses; - int * pDistrib; - int * pReprs; - // find the max number of occurences - nCuts = nClasses = 0; - CountMax = 0; - for ( i = 0; i < s_pManRwrExp4->nFuncs; i++ ) - { - if ( CountMax < s_pManRwrExp4->pnCounts[i] ) - CountMax = s_pManRwrExp4->pnCounts[i]; - nCuts += s_pManRwrExp4->pnCounts[i]; - if ( s_pManRwrExp4->pnCounts[i] > 0 ) - nClasses++; - } - printf( "Number of cuts considered = %8d.\n", nCuts ); - printf( "Classes occurring at least once = %8d.\n", nClasses ); - // print the distribution of classes - pDistrib = ALLOC( int, CountMax + 1 ); - pReprs = ALLOC( int, CountMax + 1 ); - memset( pDistrib, 0, sizeof(int)*(CountMax + 1) ); - for ( i = 0; i < s_pManRwrExp4->nFuncs; i++ ) - { - pDistrib[ s_pManRwrExp4->pnCounts[i] ]++; - pReprs[ s_pManRwrExp4->pnCounts[i] ] = i; - } - - printf( "Occurence = %6d. Num classes = %4d. \n", 0, 2288-nClasses ); - for ( i = 1; i <= CountMax; i++ ) - if ( pDistrib[i] ) - { - printf( "Occurence = %6d. Num classes = %4d. Repr = ", i, pDistrib[i] ); - Extra_PrintBinary( stdout, (unsigned*)&(pReprs[i]), 16 ); - printf( "\n" ); - } - free( pDistrib ); - free( pReprs ); - // write into a file all classes above limit (5) - CountWrite = 0; - pFile = fopen( "npnclass_stats4.txt", "w" ); - for ( i = 0; i < s_pManRwrExp4->nFuncs; i++ ) - if ( s_pManRwrExp4->pnCounts[i] > 0 ) - { - Extra_PrintHex( pFile, i, 4 ); - fprintf( pFile, " %10d\n", s_pManRwrExp4->pnCounts[i] ); -// fprintf( pFile, "%d ", i ); - CountWrite++; - } - fclose( pFile ); - printf( "%d classes written into file \"%s\".\n", CountWrite, "npnclass_stats4.txt" ); -} - - - - -/**Function************************************************************* - - Synopsis [Collects stats about 4-var functions appearing in netlists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwt_Man5ExploreStart() -{ - Rwr_Man5_t * p; - p = ALLOC( Rwr_Man5_t, 1 ); - memset( p, 0, sizeof(Rwr_Man5_t) ); - p->tTableNN = stmm_init_table( st_numcmp, st_numhash ); - p->tTableNPN = stmm_init_table( st_numcmp, st_numhash ); - s_pManRwrExp5 = p; - -//Extra_PrintHex( stdout, Extra_TruthCanonNPN( 0x0000FFFF, 5 ), 5 ); -//printf( "\n" ); -} - -/**Function************************************************************* - - Synopsis [Collects stats about 4-var functions appearing in netlists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwt_Man5ExploreCount( unsigned uTruth ) -{ - int * pCounter; - if ( !stmm_find_or_add( s_pManRwrExp5->tTableNN, (char *)uTruth, (char***)&pCounter ) ) - *pCounter = 0; - (*pCounter)++; -} - -/**Function************************************************************* - - Synopsis [Collects stats about 4-var functions appearing in netlists.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwt_Man5ExplorePrint() -{ - FILE * pFile; - stmm_generator * gen; - int i, CountMax, nCuts, Counter; - int * pDistrib; - unsigned * pReprs; - unsigned uTruth, uTruthC; - int clk = clock(); - Vec_Int_t * vClassesNN, * vClassesNPN; - - // find the max number of occurences - nCuts = 0; - CountMax = 0; - stmm_foreach_item( s_pManRwrExp5->tTableNN, gen, (char **)&uTruth, (char **)&Counter ) - { - nCuts += Counter; - if ( CountMax < Counter ) - CountMax = Counter; - } - printf( "Number of cuts considered = %8d.\n", nCuts ); - printf( "Classes occurring at least once = %8d.\n", stmm_count(s_pManRwrExp5->tTableNN) ); - printf( "The largest number of occurence = %8d.\n", CountMax ); - - // print the distribution of classes - pDistrib = ALLOC( int, CountMax + 1 ); - pReprs = ALLOC( unsigned, CountMax + 1 ); - memset( pDistrib, 0, sizeof(int)*(CountMax + 1) ); - stmm_foreach_item( s_pManRwrExp5->tTableNN, gen, (char **)&uTruth, (char **)&Counter ) - { - assert( Counter <= CountMax ); - pDistrib[ Counter ]++; - pReprs[ Counter ] = uTruth; - } - - for ( i = 1; i <= CountMax; i++ ) - if ( pDistrib[i] ) - { - printf( "Occurence = %6d. Num classes = %4d. Repr = ", i, pDistrib[i] ); - Extra_PrintBinary( stdout, pReprs + i, 32 ); - printf( "\n" ); - } - free( pDistrib ); - free( pReprs ); - - - // put them into an array - vClassesNN = Vec_IntAlloc( stmm_count(s_pManRwrExp5->tTableNN) ); - stmm_foreach_item( s_pManRwrExp5->tTableNN, gen, (char **)&uTruth, NULL ) - Vec_IntPush( vClassesNN, (int)uTruth ); - Vec_IntSortUnsigned( vClassesNN ); - - // write into a file all classes - pFile = fopen( "nnclass_stats5.txt", "w" ); - Vec_IntForEachEntry( vClassesNN, uTruth, i ) - { - if ( !stmm_lookup( s_pManRwrExp5->tTableNN, (char *)uTruth, (char **)&Counter ) ) - { - assert( 0 ); - } - Extra_PrintHex( pFile, uTruth, 5 ); - fprintf( pFile, " %10d\n", Counter ); - } - fclose( pFile ); - printf( "%d classes written into file \"%s\".\n", vClassesNN->nSize, "nnclass_stats5.txt" ); - - -clk = clock(); - // how many NPN classes exist? - Vec_IntForEachEntry( vClassesNN, uTruth, i ) - { - int * pCounter; - uTruthC = Extra_TruthCanonNPN( uTruth, 5 ); - if ( !stmm_find_or_add( s_pManRwrExp5->tTableNPN, (char *)uTruthC, (char***)&pCounter ) ) - *pCounter = 0; - if ( !stmm_lookup( s_pManRwrExp5->tTableNN, (char *)uTruth, (char **)&Counter ) ) - { - assert( 0 ); - } - (*pCounter) += Counter; - } - printf( "The numbe of NPN classes = %d.\n", stmm_count(s_pManRwrExp5->tTableNPN) ); -PRT( "Computing NPN classes", clock() - clk ); - - // put them into an array - vClassesNPN = Vec_IntAlloc( stmm_count(s_pManRwrExp5->tTableNPN) ); - stmm_foreach_item( s_pManRwrExp5->tTableNPN, gen, (char **)&uTruth, NULL ) - Vec_IntPush( vClassesNPN, (int)uTruth ); - Vec_IntSortUnsigned( vClassesNPN ); - - // write into a file all classes - pFile = fopen( "npnclass_stats5.txt", "w" ); - Vec_IntForEachEntry( vClassesNPN, uTruth, i ) - { - if ( !stmm_lookup( s_pManRwrExp5->tTableNPN, (char *)uTruth, (char **)&Counter ) ) - { - assert( 0 ); - } - Extra_PrintHex( pFile, uTruth, 5 ); - fprintf( pFile, " %10d\n", Counter ); - } - fclose( pFile ); - printf( "%d classes written into file \"%s\".\n", vClassesNPN->nSize, "npnclass_stats5.txt" ); - - - // can they be uniquely characterized? - -} - - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/rwr/rwrLib.c b/src/opt/rwr/rwrLib.c deleted file mode 100644 index 1cdf350e..00000000 --- a/src/opt/rwr/rwrLib.c +++ /dev/null @@ -1,362 +0,0 @@ -/**CFile**************************************************************** - - FileName [rwrLib.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [DAG-aware AIG rewriting package.] - - Synopsis [] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: rwrLib.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "rwr.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static Rwr_Node_t * Rwr_ManTryNode( Rwr_Man_t * p, Rwr_Node_t * p0, Rwr_Node_t * p1, int fExor, int Level, int Volume ); -static void Rwr_MarkUsed_rec( Rwr_Man_t * p, Rwr_Node_t * pNode ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Precomputes the forest in the manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManPrecompute( Rwr_Man_t * p ) -{ - Rwr_Node_t * p0, * p1; - int i, k, Level, Volume; - int LevelOld = -1; - int nNodes; - - Vec_PtrForEachEntryStart( p->vForest, p0, i, 1 ) - Vec_PtrForEachEntryStart( p->vForest, p1, k, 1 ) - { - if ( LevelOld < (int)p0->Level ) - { - LevelOld = p0->Level; - printf( "Starting level %d (at %d nodes).\n", LevelOld+1, i ); - printf( "Considered = %5d M. Found = %8d. Classes = %6d. Trying %7d.\n", - p->nConsidered/1000000, p->vForest->nSize, p->nClasses, i ); - } - - if ( k == i ) - break; -// if ( p0->Level + p1->Level > 6 ) // hard -// break; - - if ( p0->Level + p1->Level > 5 ) // easy - break; - -// if ( p0->Level + p1->Level > 6 || (p0->Level == 3 && p1->Level == 3) ) -// break; - - // compute the level and volume of the new nodes - Level = 1 + ABC_MAX( p0->Level, p1->Level ); - Volume = 1 + Rwr_ManNodeVolume( p, p0, p1 ); - // try four different AND nodes - Rwr_ManTryNode( p, p0 , p1 , 0, Level, Volume ); - Rwr_ManTryNode( p, Rwr_Not(p0), p1 , 0, Level, Volume ); - Rwr_ManTryNode( p, p0 , Rwr_Not(p1), 0, Level, Volume ); - Rwr_ManTryNode( p, Rwr_Not(p0), Rwr_Not(p1), 0, Level, Volume ); - // try EXOR - Rwr_ManTryNode( p, p0 , p1 , 1, Level, Volume + 1 ); - // report the progress - if ( p->nConsidered % 50000000 == 0 ) - printf( "Considered = %5d M. Found = %8d. Classes = %6d. Trying %7d.\n", - p->nConsidered/1000000, p->vForest->nSize, p->nClasses, i ); - // quit after some time - if ( p->vForest->nSize == RWR_LIMIT + 5 ) - { - printf( "Considered = %5d M. Found = %8d. Classes = %6d. Trying %7d.\n", - p->nConsidered/1000000, p->vForest->nSize, p->nClasses, i ); - goto save; - } - } -save : - - // mark the relevant ones - Rwr_ManIncTravId( p ); - k = 5; - nNodes = 0; - Vec_PtrForEachEntryStart( p->vForest, p0, i, 5 ) - if ( p0->uTruth == p->puCanons[p0->uTruth] ) - { - Rwr_MarkUsed_rec( p, p0 ); - nNodes++; - } - - // compact the array by throwing away non-canonical - k = 5; - Vec_PtrForEachEntryStart( p->vForest, p0, i, 5 ) - if ( p0->fUsed ) - { - p->vForest->pArray[k] = p0; - p0->Id = k++; - } - p->vForest->nSize = k; - printf( "Total canonical = %4d. Total used = %5d.\n", nNodes, p->vForest->nSize ); -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Rwr_Node_t * Rwr_ManTryNode( Rwr_Man_t * p, Rwr_Node_t * p0, Rwr_Node_t * p1, int fExor, int Level, int Volume ) -{ - Rwr_Node_t * pOld, * pNew, ** ppPlace; - unsigned uTruth; - // compute truth table, level, volume - p->nConsidered++; - if ( fExor ) - { -// printf( "Considering EXOR of %d and %d.\n", p0->Id, p1->Id ); - uTruth = (p0->uTruth ^ p1->uTruth); - } - else - uTruth = (Rwr_IsComplement(p0)? ~Rwr_Regular(p0)->uTruth : Rwr_Regular(p0)->uTruth) & - (Rwr_IsComplement(p1)? ~Rwr_Regular(p1)->uTruth : Rwr_Regular(p1)->uTruth) & 0xFFFF; - // skip non-practical classes - if ( Level > 2 && !p->pPractical[p->puCanons[uTruth]] ) - return NULL; - // enumerate through the nodes with the same canonical form - ppPlace = p->pTable + uTruth; - for ( pOld = *ppPlace; pOld; ppPlace = &pOld->pNext, pOld = pOld->pNext ) - { - if ( pOld->Level < (unsigned)Level && pOld->Volume < (unsigned)Volume ) - return NULL; - if ( pOld->Level == (unsigned)Level && pOld->Volume < (unsigned)Volume ) - return NULL; -// if ( pOld->Level < (unsigned)Level && pOld->Volume == (unsigned)Volume ) -// return NULL; - } -/* - // enumerate through the nodes with the opposite polarity - for ( pOld = p->pTable[~uTruth & 0xFFFF]; pOld; pOld = pOld->pNext ) - { - if ( pOld->Level < (unsigned)Level && pOld->Volume < (unsigned)Volume ) - return NULL; - if ( pOld->Level == (unsigned)Level && pOld->Volume < (unsigned)Volume ) - return NULL; -// if ( pOld->Level < (unsigned)Level && pOld->Volume == (unsigned)Volume ) -// return NULL; - } -*/ - // count the classes - if ( p->pTable[uTruth] == NULL && p->puCanons[uTruth] == uTruth ) - p->nClasses++; - // create the new node - pNew = (Rwr_Node_t *)Extra_MmFixedEntryFetch( p->pMmNode ); - pNew->Id = p->vForest->nSize; - pNew->TravId = 0; - pNew->uTruth = uTruth; - pNew->Level = Level; - pNew->Volume = Volume; - pNew->fUsed = 0; - pNew->fExor = fExor; - pNew->p0 = p0; - pNew->p1 = p1; - pNew->pNext = NULL; - Vec_PtrPush( p->vForest, pNew ); - *ppPlace = pNew; - return pNew; -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Rwr_Node_t * Rwr_ManAddNode( Rwr_Man_t * p, Rwr_Node_t * p0, Rwr_Node_t * p1, int fExor, int Level, int Volume ) -{ - Rwr_Node_t * pNew; - unsigned uTruth; - // compute truth table, leve, volume - p->nConsidered++; - if ( fExor ) - uTruth = (p0->uTruth ^ p1->uTruth); - else - uTruth = (Rwr_IsComplement(p0)? ~Rwr_Regular(p0)->uTruth : Rwr_Regular(p0)->uTruth) & - (Rwr_IsComplement(p1)? ~Rwr_Regular(p1)->uTruth : Rwr_Regular(p1)->uTruth) & 0xFFFF; - // create the new node - pNew = (Rwr_Node_t *)Extra_MmFixedEntryFetch( p->pMmNode ); - pNew->Id = p->vForest->nSize; - pNew->TravId = 0; - pNew->uTruth = uTruth; - pNew->Level = Level; - pNew->Volume = Volume; - pNew->fUsed = 0; - pNew->fExor = fExor; - pNew->p0 = p0; - pNew->p1 = p1; - pNew->pNext = NULL; - Vec_PtrPush( p->vForest, pNew ); - // do not add if the node is not essential - if ( uTruth != p->puCanons[uTruth] ) - return pNew; - - // add to the list - p->nAdded++; - if ( p->pTable[uTruth] == NULL ) - p->nClasses++; - Rwr_ListAddToTail( p->pTable + uTruth, pNew ); - return pNew; -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Rwr_Node_t * Rwr_ManAddVar( Rwr_Man_t * p, unsigned uTruth, int fPrecompute ) -{ - Rwr_Node_t * pNew; - pNew = (Rwr_Node_t *)Extra_MmFixedEntryFetch( p->pMmNode ); - pNew->Id = p->vForest->nSize; - pNew->TravId = 0; - pNew->uTruth = uTruth; - pNew->Level = 0; - pNew->Volume = 0; - pNew->fUsed = 1; - pNew->fExor = 0; - pNew->p0 = NULL; - pNew->p1 = NULL; - pNew->pNext = NULL; - Vec_PtrPush( p->vForest, pNew ); - if ( fPrecompute ) - Rwr_ListAddToTail( p->pTable + uTruth, pNew ); - return pNew; -} - - - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_MarkUsed_rec( Rwr_Man_t * p, Rwr_Node_t * pNode ) -{ - if ( pNode->fUsed || pNode->TravId == p->nTravIds ) - return; - pNode->TravId = p->nTravIds; - pNode->fUsed = 1; - Rwr_MarkUsed_rec( p, Rwr_Regular(pNode->p0) ); - Rwr_MarkUsed_rec( p, Rwr_Regular(pNode->p1) ); -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_Trav_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, int * pVolume ) -{ - if ( pNode->fUsed || pNode->TravId == p->nTravIds ) - return; - pNode->TravId = p->nTravIds; - (*pVolume)++; - if ( pNode->fExor ) - (*pVolume)++; - Rwr_Trav_rec( p, Rwr_Regular(pNode->p0), pVolume ); - Rwr_Trav_rec( p, Rwr_Regular(pNode->p1), pVolume ); -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Rwr_ManNodeVolume( Rwr_Man_t * p, Rwr_Node_t * p0, Rwr_Node_t * p1 ) -{ - int Volume = 0; - Rwr_ManIncTravId( p ); - Rwr_Trav_rec( p, p0, &Volume ); - Rwr_Trav_rec( p, p1, &Volume ); - return Volume; -} - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManIncTravId( Rwr_Man_t * p ) -{ - Rwr_Node_t * pNode; - int i; - if ( p->nTravIds++ < 0x8FFFFFFF ) - return; - Vec_PtrForEachEntry( p->vForest, pNode, i ) - pNode->TravId = 0; - p->nTravIds = 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/rwr/rwrMan.c b/src/opt/rwr/rwrMan.c deleted file mode 100644 index 87a080c7..00000000 --- a/src/opt/rwr/rwrMan.c +++ /dev/null @@ -1,318 +0,0 @@ -/**CFile**************************************************************** - - FileName [rwrMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [DAG-aware AIG rewriting package.] - - Synopsis [Rewriting manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: rwrMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "rwr.h" -#include "main.h" -#include "dec.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts rewriting manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Rwr_Man_t * Rwr_ManStart( bool fPrecompute ) -{ - Dec_Man_t * pManDec; - Rwr_Man_t * p; - int clk = clock(); -clk = clock(); - p = ALLOC( Rwr_Man_t, 1 ); - memset( p, 0, sizeof(Rwr_Man_t) ); - p->nFuncs = (1<<16); - pManDec = Abc_FrameReadManDec(); - p->puCanons = pManDec->puCanons; - p->pPhases = pManDec->pPhases; - p->pPerms = pManDec->pPerms; - p->pMap = pManDec->pMap; - // initialize practical NPN classes - p->pPractical = Rwr_ManGetPractical( p ); - // create the table - p->pTable = ALLOC( Rwr_Node_t *, p->nFuncs ); - memset( p->pTable, 0, sizeof(Rwr_Node_t *) * p->nFuncs ); - // create the elementary nodes - p->pMmNode = Extra_MmFixedStart( sizeof(Rwr_Node_t) ); - p->vForest = Vec_PtrAlloc( 100 ); - Rwr_ManAddVar( p, 0x0000, fPrecompute ); // constant 0 - Rwr_ManAddVar( p, 0xAAAA, fPrecompute ); // var A - Rwr_ManAddVar( p, 0xCCCC, fPrecompute ); // var B - Rwr_ManAddVar( p, 0xF0F0, fPrecompute ); // var C - Rwr_ManAddVar( p, 0xFF00, fPrecompute ); // var D - p->nClasses = 5; - // other stuff - p->nTravIds = 1; - p->pPerms4 = Extra_Permutations( 4 ); - 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 ); -// Rwr_ManPrint( p ); - Rwr_ManWriteToArray( p ); - } - else - { // load saved subgraphs - Rwr_ManLoadFromArray( p, 0 ); -// Rwr_ManPrint( p ); - Rwr_ManPreprocess( p ); - } -p->timeStart = clock() - clk; - return p; -} - -/**Function************************************************************* - - Synopsis [Stops rewriting manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManStop( Rwr_Man_t * p ) -{ - if ( p->vClasses ) - { - Rwr_Node_t * pNode; - int i, k; - Vec_VecForEachEntry( p->vClasses, pNode, i, k ) - 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 ); - free( p->pTable ); - free( p->pPractical ); - free( p->pPerms4 ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManPrintStats( Rwr_Man_t * p ) -{ - int i, Counter = 0; - for ( i = 0; i < 222; i++ ) - Counter += (p->nScores[i] > 0); - - printf( "Rewriting statistics:\n" ); - printf( "Total cuts tries = %8d.\n", p->nCutsGood ); - printf( "Bad cuts found = %8d.\n", p->nCutsBad ); - printf( "Total subgraphs = %8d.\n", p->nSubgraphs ); - 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 ); - 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" ); - 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( "\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************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void * Rwr_ManReadDecs( Rwr_Man_t * p ) -{ - return p->pGraph; -} - -/**Function************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - 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; -} - -/**Function************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManAddTimeCuts( Rwr_Man_t * p, int Time ) -{ - p->timeCut += Time; -} - -/**Function************************************************************* - - Synopsis [Stops the resynthesis manager.] - - Description [] - - SideEffects [] - - 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; -} - - -/**Function************************************************************* - - Synopsis [Precomputes AIG subgraphs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_Precompute() -{ - Rwr_Man_t * p; - p = Rwr_ManStart( 1 ); - Rwr_ManStop( p ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/rwr/rwrPrint.c b/src/opt/rwr/rwrPrint.c deleted file mode 100644 index 82ad2a90..00000000 --- a/src/opt/rwr/rwrPrint.c +++ /dev/null @@ -1,266 +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 /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Adds one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_Trav2_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, int * pVolume ) -{ - if ( pNode->fUsed || pNode->TravId == p->nTravIds ) - return; - pNode->TravId = p->nTravIds; - (*pVolume)++; - Rwr_Trav2_rec( p, Rwr_Regular(pNode->p0), pVolume ); - Rwr_Trav2_rec( p, Rwr_Regular(pNode->p1), pVolume ); -} - -/**Function************************************************************* - - Synopsis [Adds the node to the end of the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_GetBushVolume( Rwr_Man_t * p, int Entry, int * pVolume, int * pnFuncs ) -{ - Rwr_Node_t * pNode; - int Volume = 0; - int nFuncs = 0; - Rwr_ManIncTravId( p ); - for ( pNode = p->pTable[Entry]; pNode; pNode = pNode->pNext ) - { - if ( pNode->uTruth != p->puCanons[pNode->uTruth] ) - continue; - nFuncs++; - Rwr_Trav2_rec( p, pNode, &Volume ); - } - *pVolume = Volume; - *pnFuncs = nFuncs; -} - -/**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 [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_NodePrint_rec( FILE * pFile, Rwr_Node_t * pNode ) -{ - assert( !Rwr_IsComplement(pNode) ); - - if ( pNode->Id == 0 ) - { - fprintf( pFile, "Const1" ); - return; - } - - if ( pNode->Id < 5 ) - { - fprintf( pFile, "%c", 'a' + pNode->Id - 1 ); - return; - } - - if ( Rwr_IsComplement(pNode->p0) ) - { - if ( Rwr_Regular(pNode->p0)->Id < 5 ) - { - Rwr_NodePrint_rec( pFile, Rwr_Regular(pNode->p0) ); - fprintf( pFile, "\'" ); - } - else - { - fprintf( pFile, "(" ); - Rwr_NodePrint_rec( pFile, Rwr_Regular(pNode->p0) ); - fprintf( pFile, ")\'" ); - } - } - else - { - if ( Rwr_Regular(pNode->p0)->Id < 5 ) - { - Rwr_NodePrint_rec( pFile, Rwr_Regular(pNode->p0) ); - } - else - { - fprintf( pFile, "(" ); - Rwr_NodePrint_rec( pFile, Rwr_Regular(pNode->p0) ); - fprintf( pFile, ")" ); - } - } - - if ( pNode->fExor ) - fprintf( pFile, "+" ); - - if ( Rwr_IsComplement(pNode->p1) ) - { - if ( Rwr_Regular(pNode->p1)->Id < 5 ) - { - Rwr_NodePrint_rec( pFile, Rwr_Regular(pNode->p1) ); - fprintf( pFile, "\'" ); - } - else - { - fprintf( pFile, "(" ); - Rwr_NodePrint_rec( pFile, Rwr_Regular(pNode->p1) ); - fprintf( pFile, ")\'" ); - } - } - else - { - if ( Rwr_Regular(pNode->p1)->Id < 5 ) - { - Rwr_NodePrint_rec( pFile, Rwr_Regular(pNode->p1) ); - } - else - { - fprintf( pFile, "(" ); - Rwr_NodePrint_rec( pFile, Rwr_Regular(pNode->p1) ); - fprintf( pFile, ")" ); - } - } -} - -/**Function************************************************************* - - Synopsis [Prints one rwr node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_NodePrint( FILE * pFile, Rwr_Man_t * p, Rwr_Node_t * pNode ) -{ - unsigned uTruth; - fprintf( pFile, "%5d : ", pNode->Id ); - Extra_PrintHex( pFile, pNode->uTruth, 4 ); - fprintf( pFile, " tt=" ); - uTruth = pNode->uTruth; - Extra_PrintBinary( pFile, &uTruth, 16 ); -// fprintf( pFile, " cn=", pNode->Id ); -// uTruth = p->puCanons[pNode->uTruth]; -// Extra_PrintBinary( pFile, &uTruth, 16 ); - fprintf( pFile, " lev=%d", pNode->Level ); - fprintf( pFile, " vol=%d", pNode->Volume ); - fprintf( pFile, " " ); - Rwr_NodePrint_rec( pFile, pNode ); - fprintf( pFile, "\n" ); -} - -/**Function************************************************************* - - Synopsis [Prints one rwr node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManPrint( Rwr_Man_t * p ) -{ - FILE * pFile; - Rwr_Node_t * pNode; - unsigned uTruth; - int Limit, Counter, Volume, nFuncs, i; - pFile = fopen( "graph_lib.txt", "w" ); - Counter = 0; - Limit = (1 << 16); - for ( i = 0; i < Limit; i++ ) - { - if ( p->pTable[i] == NULL ) - continue; - if ( i != p->puCanons[i] ) - continue; - 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) ); - uTruth = i; - Extra_PrintBinary( pFile, &uTruth, 16 ); - fprintf( pFile, "\n" ); - for ( pNode = p->pTable[i]; pNode; pNode = pNode->pNext ) - if ( pNode->uTruth == p->puCanons[pNode->uTruth] ) - Rwr_NodePrint( pFile, p, pNode ); - } - fclose( pFile ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - 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 deleted file mode 100644 index b2add2bf..00000000 --- a/src/opt/rwr/rwrUtil.c +++ /dev/null @@ -1,659 +0,0 @@ -/**CFile**************************************************************** - - FileName [rwrUtil.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [DAG-aware AIG rewriting package.] - - Synopsis [Various utilities.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: rwrUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "rwr.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -// precomputed data -#ifdef _WIN32 -unsigned short s_RwrPracticalClasses[]; -unsigned short s_RwtAigSubgraphs[]; -#else -static unsigned short s_RwrPracticalClasses[]; -static unsigned short s_RwtAigSubgraphs[]; -#endif - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Writes data.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManWriteToArray( Rwr_Man_t * p ) -{ - FILE * pFile; - Rwr_Node_t * pNode; - unsigned Entry0, Entry1; - int i, nEntries, clk = clock(); - // prepare the buffer - nEntries = p->vForest->nSize - 5; - pFile = fopen( "npn4_aig_array.txt", "w" ); - fprintf( pFile, "static unsigned short s_RwtAigSubgraphs[] = \n{" ); - for ( i = 0; i < nEntries; i++ ) - { - if ( i % 5 == 0 ) - fprintf( pFile, "\n " ); - pNode = p->vForest->pArray[i+5]; - Entry0 = (Rwr_Regular(pNode->p0)->Id << 1) | Rwr_IsComplement(pNode->p0); - Entry1 = (Rwr_Regular(pNode->p1)->Id << 1) | Rwr_IsComplement(pNode->p1); - Entry0 = (Entry0 << 1) | pNode->fExor; - Extra_PrintHex( pFile, Entry0, 4 ); - fprintf( pFile, "," ); - Extra_PrintHex( pFile, Entry1, 4 ); - fprintf( pFile, ", " ); - } - if ( i % 5 == 0 ) - fprintf( pFile, "\n " ); - Extra_PrintHex( pFile, 0, 4 ); - fprintf( pFile, "," ); - Extra_PrintHex( pFile, 0, 4 ); - fprintf( pFile, " \n};\n" ); - fclose( pFile ); - printf( "The number of nodes saved = %d. ", nEntries ); PRT( "Saving", clock() - clk ); -} - -/**Function************************************************************* - - Synopsis [Loads data.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManLoadFromArray( Rwr_Man_t * p, int fVerbose ) -{ - unsigned short * pArray = s_RwtAigSubgraphs; - Rwr_Node_t * p0, * p1; - unsigned Entry0, Entry1; - int Level, Volume, nEntries, fExor; - int i, clk = clock(); - - // reconstruct the forest - for ( i = 0; ; i++ ) - { - Entry0 = pArray[2*i + 0]; - Entry1 = pArray[2*i + 1]; - if ( Entry0 == 0 && Entry1 == 0 ) - break; - // get EXOR flag - fExor = (Entry0 & 1); - Entry0 >>= 1; - // get the nodes - p0 = p->vForest->pArray[Entry0 >> 1]; - p1 = p->vForest->pArray[Entry1 >> 1]; - // compute the level and volume of the new nodes - Level = 1 + ABC_MAX( p0->Level, p1->Level ); - Volume = 1 + Rwr_ManNodeVolume( p, p0, p1 ); - // set the complemented attributes - p0 = Rwr_NotCond( p0, (Entry0 & 1) ); - p1 = Rwr_NotCond( p1, (Entry1 & 1) ); - // add the node -// Rwr_ManTryNode( p, p0, p1, Level, Volume ); - Rwr_ManAddNode( p, p0, p1, fExor, Level, Volume + fExor ); - } - nEntries = i - 1; - if ( fVerbose ) - { - printf( "The number of classes = %d. Canonical nodes = %d.\n", p->nClasses, p->nAdded ); - printf( "The number of nodes loaded = %d. ", nEntries ); PRT( "Loading", clock() - clk ); - } -} - - -/**Function************************************************************* - - Synopsis [Writes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManWriteToFile( Rwr_Man_t * p, char * pFileName ) -{ - FILE * pFile; - Rwr_Node_t * pNode; - unsigned * pBuffer; - int i, nEntries, clk = clock(); - // prepare the buffer - nEntries = p->vForest->nSize - 5; - pBuffer = ALLOC( unsigned, nEntries * 2 ); - for ( i = 0; i < nEntries; i++ ) - { - pNode = p->vForest->pArray[i+5]; - pBuffer[2*i + 0] = (Rwr_Regular(pNode->p0)->Id << 1) | Rwr_IsComplement(pNode->p0); - pBuffer[2*i + 1] = (Rwr_Regular(pNode->p1)->Id << 1) | Rwr_IsComplement(pNode->p1); - // save EXOR flag - pBuffer[2*i + 0] = (pBuffer[2*i + 0] << 1) | pNode->fExor; - - } - pFile = fopen( pFileName, "wb" ); - fwrite( &nEntries, sizeof(int), 1, pFile ); - fwrite( pBuffer, sizeof(unsigned), nEntries * 2, pFile ); - free( pBuffer ); - fclose( pFile ); - printf( "The number of nodes saved = %d. ", nEntries ); PRT( "Saving", clock() - clk ); -} - -/**Function************************************************************* - - Synopsis [Loads data.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ManLoadFromFile( Rwr_Man_t * p, char * pFileName ) -{ - FILE * pFile; - Rwr_Node_t * p0, * p1; - unsigned * pBuffer; - int Level, Volume, nEntries, fExor; - int i, clk = clock(); - - // load the data - pFile = fopen( pFileName, "rb" ); - if ( pFile == NULL ) - { - printf( "Rwr_ManLoadFromFile: Cannot open file \"%s\".\n", pFileName ); - return; - } - fread( &nEntries, sizeof(int), 1, pFile ); - pBuffer = ALLOC( unsigned, nEntries * 2 ); - fread( pBuffer, sizeof(unsigned), nEntries * 2, pFile ); - fclose( pFile ); - // reconstruct the forest - for ( i = 0; i < nEntries; i++ ) - { - // get EXOR flag - fExor = (pBuffer[2*i + 0] & 1); - pBuffer[2*i + 0] = (pBuffer[2*i + 0] >> 1); - // get the nodes - p0 = p->vForest->pArray[pBuffer[2*i + 0] >> 1]; - p1 = p->vForest->pArray[pBuffer[2*i + 1] >> 1]; - // compute the level and volume of the new nodes - Level = 1 + ABC_MAX( p0->Level, p1->Level ); - Volume = 1 + Rwr_ManNodeVolume( p, p0, p1 ); - // set the complemented attributes - p0 = Rwr_NotCond( p0, (pBuffer[2*i + 0] & 1) ); - p1 = Rwr_NotCond( p1, (pBuffer[2*i + 1] & 1) ); - // add the node -// Rwr_ManTryNode( p, p0, p1, Level, Volume ); - Rwr_ManAddNode( p, p0, p1, fExor, Level, Volume + fExor ); - } - free( pBuffer ); - printf( "The number of classes = %d. Canonical nodes = %d.\n", p->nClasses, p->nAdded ); - printf( "The number of nodes loaded = %d. ", nEntries ); PRT( "Loading", clock() - clk ); -} - - -/**Function************************************************************* - - Synopsis [Adds the node to the end of the list.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Rwr_ListAddToTail( Rwr_Node_t ** ppList, Rwr_Node_t * pNode ) -{ - Rwr_Node_t * pTemp; - // find the last one - for ( pTemp = *ppList; pTemp; pTemp = pTemp->pNext ) - ppList = &pTemp->pNext; - // attach at the end - *ppList = pNode; -} - -/**Function************************************************************* - - Synopsis [Create practical classes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -char * Rwr_ManGetPractical( Rwr_Man_t * p ) -{ - char * pPractical; - int i; - pPractical = ALLOC( char, p->nFuncs ); - memset( pPractical, 0, sizeof(char) * p->nFuncs ); - pPractical[0] = 1; - for ( i = 1; ; i++ ) - { - if ( s_RwrPracticalClasses[i] == 0 ) - break; - pPractical[ s_RwrPracticalClasses[i] ] = 1; - } - return pPractical; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - -// the following 135 practical NPN classes of 4-variable functions were computed -// by considering all 4-input cuts appearing in IWLS, MCNC, and ISCAS benchmarks -static unsigned short s_RwrPracticalClasses[] = -{ - 0x0000, 0x0001, 0x0003, 0x0006, 0x0007, 0x000f, 0x0016, 0x0017, 0x0018, 0x0019, 0x001b, - 0x001e, 0x001f, 0x003c, 0x003d, 0x003f, 0x0069, 0x006b, 0x006f, 0x007e, 0x007f, 0x00ff, - 0x0116, 0x0118, 0x0119, 0x011a, 0x011b, 0x011e, 0x011f, 0x012c, 0x012d, 0x012f, 0x013c, - 0x013d, 0x013e, 0x013f, 0x0168, 0x0169, 0x016f, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, - 0x0186, 0x0189, 0x018b, 0x018f, 0x0198, 0x0199, 0x019b, 0x01a8, 0x01a9, 0x01aa, 0x01ab, - 0x01ac, 0x01ad, 0x01ae, 0x01af, 0x01bf, 0x01e9, 0x01ea, 0x01eb, 0x01ee, 0x01ef, 0x01fe, - 0x033c, 0x033d, 0x033f, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035f, 0x0368, - 0x0369, 0x036c, 0x036e, 0x037d, 0x03c0, 0x03c1, 0x03c3, 0x03c7, 0x03cf, 0x03d4, 0x03d5, - 0x03d7, 0x03d8, 0x03d9, 0x03dc, 0x03dd, 0x03de, 0x03fc, 0x0660, 0x0661, 0x0666, 0x0669, - 0x066f, 0x0676, 0x067e, 0x0690, 0x0696, 0x0697, 0x069f, 0x06b1, 0x06b6, 0x06f0, 0x06f2, - 0x06f6, 0x06f9, 0x0776, 0x0778, 0x07b0, 0x07b1, 0x07b4, 0x07bc, 0x07f0, 0x07f2, 0x07f8, - 0x0ff0, 0x1683, 0x1696, 0x1698, 0x169e, 0x16e9, 0x178e, 0x17e8, 0x18e7, 0x19e6, 0x1be4, - 0x1ee1, 0x3cc3, 0x6996, 0x0000 -}; - -static unsigned short s_RwtAigSubgraphs[] = -{ - 0x0008,0x0002, 0x000a,0x0002, 0x0008,0x0003, 0x000a,0x0003, 0x0009,0x0002, - 0x000c,0x0002, 0x000e,0x0002, 0x000c,0x0003, 0x000e,0x0003, 0x000d,0x0002, - 0x000c,0x0004, 0x000e,0x0004, 0x000c,0x0005, 0x000e,0x0005, 0x000d,0x0004, - 0x0010,0x0002, 0x0012,0x0002, 0x0010,0x0003, 0x0012,0x0003, 0x0011,0x0002, - 0x0010,0x0004, 0x0012,0x0004, 0x0010,0x0005, 0x0012,0x0005, 0x0011,0x0004, - 0x0010,0x0006, 0x0012,0x0006, 0x0010,0x0007, 0x0012,0x0007, 0x0011,0x0006, - 0x0016,0x0005, 0x0014,0x0006, 0x0016,0x0006, 0x0014,0x0007, 0x0016,0x0007, - 0x0015,0x0006, 0x0014,0x0008, 0x0016,0x0008, 0x0014,0x0009, 0x0016,0x0009, - 0x0015,0x0008, 0x0018,0x0006, 0x001a,0x0006, 0x0018,0x0007, 0x001a,0x0007, - 0x0019,0x0006, 0x0018,0x0009, 0x001a,0x0009, 0x0019,0x0008, 0x001e,0x0005, - 0x001c,0x0006, 0x001e,0x0006, 0x001c,0x0007, 0x001e,0x0007, 0x001d,0x0006, - 0x001c,0x0008, 0x001e,0x0008, 0x001c,0x0009, 0x001e,0x0009, 0x001d,0x0008, - 0x0020,0x0006, 0x0022,0x0006, 0x0020,0x0007, 0x0022,0x0007, 0x0021,0x0006, - 0x0020,0x0008, 0x0022,0x0008, 0x0020,0x0009, 0x0022,0x0009, 0x0021,0x0008, - 0x0024,0x0006, 0x0026,0x0006, 0x0024,0x0007, 0x0026,0x0007, 0x0025,0x0006, - 0x0026,0x0008, 0x0024,0x0009, 0x0026,0x0009, 0x0025,0x0008, 0x0028,0x0004, - 0x002a,0x0004, 0x0028,0x0005, 0x002a,0x0007, 0x0028,0x0008, 0x002a,0x0009, - 0x0029,0x0008, 0x002a,0x000b, 0x0029,0x000a, 0x002a,0x000f, 0x0029,0x000e, - 0x002a,0x0011, 0x002a,0x0013, 0x002c,0x0004, 0x002e,0x0004, 0x002c,0x0005, - 0x002c,0x0009, 0x002e,0x0009, 0x002d,0x0008, 0x002d,0x000c, 0x002e,0x000f, - 0x002e,0x0011, 0x002e,0x0012, 0x0030,0x0004, 0x0032,0x0007, 0x0032,0x0009, - 0x0031,0x0008, 0x0032,0x000b, 0x0032,0x000d, 0x0032,0x000f, 0x0031,0x000e, - 0x0032,0x0013, 0x0034,0x0004, 0x0036,0x0004, 0x0034,0x0005, 0x0036,0x0005, - 0x0035,0x0004, 0x0036,0x0008, 0x0034,0x0009, 0x0036,0x0009, 0x0035,0x0008, - 0x0036,0x000b, 0x0036,0x000d, 0x0036,0x0011, 0x0035,0x0010, 0x0036,0x0013, - 0x0038,0x0004, 0x0039,0x0004, 0x0038,0x0009, 0x003a,0x0009, 0x0039,0x0008, - 0x0038,0x000b, 0x003a,0x000b, 0x003a,0x000d, 0x003a,0x0011, 0x003a,0x0012, - 0x0038,0x0013, 0x003a,0x0013, 0x003c,0x0002, 0x003e,0x0002, 0x003c,0x0003, - 0x003e,0x0005, 0x003e,0x0007, 0x003c,0x0008, 0x003e,0x0008, 0x003c,0x0009, - 0x003e,0x0009, 0x003d,0x0008, 0x003e,0x000d, 0x003e,0x0011, 0x003e,0x0013, - 0x003e,0x0017, 0x003e,0x001b, 0x003e,0x001d, 0x0040,0x0002, 0x0042,0x0002, - 0x0042,0x0005, 0x0041,0x0006, 0x0042,0x0008, 0x0041,0x0008, 0x0042,0x000d, - 0x0042,0x0011, 0x0042,0x0015, 0x0042,0x0019, 0x0042,0x001b, 0x0042,0x001c, - 0x0041,0x001c, 0x0044,0x0002, 0x0046,0x0003, 0x0045,0x0004, 0x0046,0x0007, - 0x0045,0x0008, 0x0046,0x000b, 0x0046,0x000f, 0x0046,0x0013, 0x0045,0x0012, - 0x0046,0x0017, 0x0046,0x001b, 0x0046,0x0021, 0x0048,0x0002, 0x004a,0x0002, - 0x0048,0x0003, 0x004a,0x0003, 0x0049,0x0002, 0x0048,0x0008, 0x004a,0x0008, - 0x0048,0x0009, 0x004a,0x0009, 0x0049,0x0008, 0x004a,0x000b, 0x004a,0x000f, - 0x004a,0x0011, 0x004a,0x0012, 0x004a,0x0013, 0x004a,0x0015, 0x004a,0x0019, - 0x004a,0x001b, 0x004a,0x001d, 0x004c,0x0002, 0x004c,0x0003, 0x004d,0x0002, - 0x004c,0x0008, 0x004e,0x0008, 0x004c,0x0009, 0x004e,0x0009, 0x004d,0x0008, - 0x004c,0x000b, 0x004e,0x000b, 0x004c,0x000f, 0x004e,0x000f, 0x004e,0x0011, - 0x004c,0x0012, 0x004c,0x0013, 0x004e,0x0013, 0x004e,0x0015, 0x004c,0x0017, - 0x004e,0x0019, 0x004c,0x001b, 0x004e,0x001b, 0x004c,0x001c, 0x004c,0x001d, - 0x004e,0x001d, 0x0050,0x0004, 0x0052,0x0004, 0x0050,0x0006, 0x0052,0x0009, - 0x0052,0x000d, 0x0052,0x000f, 0x0052,0x0013, 0x0052,0x0017, 0x0052,0x0019, - 0x0052,0x001d, 0x0052,0x001f, 0x0052,0x0021, 0x0052,0x0023, 0x0052,0x0024, - 0x0052,0x0025, 0x0051,0x0024, 0x0052,0x0027, 0x0054,0x0004, 0x0056,0x0004, - 0x0054,0x0005, 0x0056,0x0006, 0x0054,0x0007, 0x0056,0x0011, 0x0056,0x001b, - 0x0056,0x001e, 0x0054,0x001f, 0x0056,0x001f, 0x0056,0x0020, 0x0054,0x0021, - 0x0055,0x0020, 0x0056,0x0024, 0x0054,0x0025, 0x0056,0x0025, 0x0055,0x0024, - 0x0054,0x0027, 0x0056,0x0027, 0x0055,0x0026, 0x005a,0x0007, 0x005a,0x0009, - 0x005a,0x000b, 0x005a,0x0015, 0x005a,0x001f, 0x0059,0x0020, 0x0058,0x0024, - 0x005a,0x0024, 0x005a,0x0027, 0x0059,0x0026, 0x005c,0x0004, 0x005e,0x0004, - 0x005c,0x0005, 0x005e,0x0006, 0x005c,0x0007, 0x005d,0x0006, 0x005e,0x000d, - 0x005e,0x0013, 0x005e,0x0017, 0x005c,0x001f, 0x005d,0x001e, 0x005e,0x0020, - 0x005e,0x0021, 0x005e,0x0022, 0x005e,0x0023, 0x005c,0x0024, 0x005e,0x0024, - 0x005c,0x0025, 0x005e,0x0025, 0x005d,0x0024, 0x005e,0x0026, 0x005e,0x0027, - 0x0062,0x0004, 0x0061,0x0004, 0x0062,0x0006, 0x0061,0x0006, 0x0060,0x000f, - 0x0060,0x0013, 0x0062,0x0013, 0x0060,0x0019, 0x0062,0x001c, 0x0060,0x001d, - 0x0062,0x001d, 0x0062,0x001f, 0x0060,0x0021, 0x0060,0x0023, 0x0062,0x0024, - 0x0060,0x0027, 0x0061,0x0026, 0x0064,0x0002, 0x0066,0x0002, 0x0064,0x0006, - 0x0066,0x0007, 0x0066,0x0009, 0x0066,0x000d, 0x0066,0x0013, 0x0066,0x0015, - 0x0066,0x0017, 0x0066,0x0019, 0x0066,0x001a, 0x0065,0x001a, 0x0066,0x001f, - 0x0066,0x0023, 0x0066,0x0027, 0x0066,0x002f, 0x0066,0x0030, 0x006a,0x0002, - 0x0068,0x0003, 0x0068,0x0006, 0x006a,0x0006, 0x006a,0x0011, 0x0068,0x0016, - 0x0068,0x0017, 0x006a,0x0017, 0x006a,0x001a, 0x006a,0x001b, 0x006a,0x0025, - 0x006a,0x002d, 0x006e,0x0003, 0x006e,0x0007, 0x006e,0x0009, 0x006e,0x000b, - 0x006e,0x0015, 0x006e,0x0016, 0x006e,0x0017, 0x006c,0x001a, 0x006e,0x001a, - 0x006e,0x001f, 0x006e,0x002b, 0x006e,0x0035, 0x0070,0x0002, 0x0070,0x0003, - 0x0072,0x0006, 0x0070,0x0007, 0x0071,0x0006, 0x0072,0x000b, 0x0072,0x000f, - 0x0072,0x0013, 0x0070,0x0015, 0x0071,0x0014, 0x0072,0x0017, 0x0072,0x0018, - 0x0070,0x0019, 0x0072,0x0019, 0x0070,0x001a, 0x0070,0x001b, 0x0072,0x001b, - 0x0071,0x001a, 0x0072,0x0021, 0x0072,0x0029, 0x0076,0x0002, 0x0076,0x0003, - 0x0075,0x0002, 0x0076,0x0006, 0x0074,0x0007, 0x0076,0x0007, 0x0075,0x0006, - 0x0076,0x000d, 0x0076,0x0011, 0x0076,0x0013, 0x0075,0x0014, 0x0076,0x0019, - 0x0076,0x001a, 0x0076,0x001b, 0x0075,0x001c, 0x0074,0x0023, 0x0075,0x0022, - 0x0074,0x0026, 0x0076,0x0026, 0x0074,0x0027, 0x0076,0x002b, 0x0076,0x002f, - 0x0078,0x0002, 0x0078,0x0004, 0x007a,0x0004, 0x007a,0x0005, 0x0079,0x0004, - 0x007a,0x0009, 0x007a,0x000a, 0x007a,0x000b, 0x007a,0x000d, 0x007a,0x000f, - 0x007a,0x0010, 0x007a,0x0011, 0x007a,0x0012, 0x007a,0x0013, 0x007a,0x0017, - 0x007a,0x001b, 0x007a,0x0021, 0x007a,0x0027, 0x007a,0x002b, 0x007a,0x002f, - 0x007a,0x0030, 0x0079,0x0034, 0x007a,0x0039, 0x007a,0x003a, 0x007e,0x0002, - 0x007c,0x0004, 0x007e,0x0004, 0x007e,0x000c, 0x007c,0x000d, 0x007e,0x0011, - 0x007e,0x0013, 0x007e,0x001b, 0x007e,0x0025, 0x007e,0x002d, 0x007e,0x0037, - 0x0082,0x0003, 0x0082,0x0005, 0x0082,0x0009, 0x0082,0x000b, 0x0080,0x0010, - 0x0082,0x0010, 0x0082,0x0012, 0x0082,0x0015, 0x0082,0x001f, 0x0082,0x002b, - 0x0082,0x0035, 0x0082,0x0039, 0x0082,0x003f, 0x0084,0x0002, 0x0086,0x0002, - 0x0084,0x0003, 0x0086,0x0003, 0x0085,0x0002, 0x0086,0x0004, 0x0084,0x0005, - 0x0085,0x0004, 0x0086,0x000a, 0x0084,0x000b, 0x0085,0x000a, 0x0086,0x000d, - 0x0086,0x000e, 0x0086,0x000f, 0x0084,0x0010, 0x0084,0x0011, 0x0086,0x0011, - 0x0085,0x0010, 0x0084,0x0012, 0x0084,0x0013, 0x0086,0x0013, 0x0085,0x0012, - 0x0086,0x0019, 0x0086,0x0023, 0x0086,0x0029, 0x0086,0x0033, 0x0086,0x0039, - 0x008a,0x0003, 0x0089,0x0002, 0x0088,0x0004, 0x008a,0x0004, 0x0088,0x0005, - 0x0089,0x0004, 0x008a,0x000b, 0x008a,0x0010, 0x0088,0x0011, 0x008a,0x0011, - 0x0089,0x0010, 0x0088,0x0012, 0x008a,0x0012, 0x0089,0x0012, 0x008a,0x0017, - 0x008a,0x001b, 0x0089,0x0020, 0x008a,0x0025, 0x0088,0x0027, 0x008a,0x002b, - 0x008a,0x002f, 0x008a,0x0039, 0x0088,0x003a, 0x008d,0x0044, 0x0092,0x0009, - 0x0092,0x0025, 0x0092,0x0029, 0x0092,0x002d, 0x0092,0x0033, 0x0092,0x0037, - 0x0092,0x003d, 0x0092,0x0041, 0x0095,0x0002, 0x0095,0x0004, 0x0095,0x0010, - 0x0095,0x0012, 0x0096,0x0021, 0x0096,0x0029, 0x0095,0x002e, 0x0096,0x0030, - 0x0096,0x0033, 0x0096,0x003a, 0x0096,0x0043, 0x009a,0x0008, 0x009a,0x0009, - 0x0099,0x0008, 0x009a,0x0011, 0x009a,0x0023, 0x009a,0x0033, 0x009a,0x003d, - 0x009a,0x0044, 0x009a,0x0045, 0x0099,0x0044, 0x009d,0x0002, 0x009e,0x0008, - 0x009c,0x0009, 0x009e,0x0009, 0x009d,0x0008, 0x009e,0x0011, 0x009d,0x0010, - 0x009e,0x001f, 0x009e,0x003f, 0x00a0,0x0009, 0x00a0,0x0011, 0x00a2,0x0030, - 0x00a2,0x0033, 0x00a6,0x0006, 0x00a6,0x0007, 0x00a6,0x0011, 0x00a6,0x0044, - 0x00a6,0x004b, 0x00aa,0x0007, 0x00aa,0x0015, 0x00ae,0x0006, 0x00ae,0x0011, - 0x00ae,0x001b, 0x00ae,0x0025, 0x00ae,0x003d, 0x00ae,0x0041, 0x00ae,0x0043, - 0x00ae,0x0045, 0x00b2,0x0006, 0x00b0,0x0007, 0x00b1,0x0006, 0x00b2,0x0017, - 0x00b1,0x0016, 0x00b0,0x0019, 0x00b2,0x0021, 0x00b2,0x003d, 0x00b5,0x004a, - 0x00ba,0x0009, 0x00ba,0x000f, 0x00bc,0x0009, 0x00be,0x0009, 0x00be,0x000f, - 0x00bd,0x000e, 0x00be,0x0017, 0x00c2,0x0009, 0x00c2,0x0019, 0x00c2,0x001f, - 0x00c2,0x0033, 0x00c6,0x0009, 0x00c5,0x000e, 0x00c6,0x0015, 0x00c6,0x0023, - 0x00c4,0x002d, 0x00c6,0x002f, 0x00c5,0x002e, 0x00c6,0x0045, 0x00ce,0x0007, - 0x00ce,0x0021, 0x00ce,0x0023, 0x00ce,0x0025, 0x00ce,0x0027, 0x00ce,0x0033, - 0x00ce,0x003d, 0x00d2,0x0006, 0x00d0,0x0015, 0x00d0,0x001b, 0x00d2,0x001b, - 0x00d1,0x001a, 0x00d0,0x001f, 0x00d2,0x0025, 0x00d1,0x0024, 0x00d2,0x0037, - 0x00d2,0x0041, 0x00d2,0x0045, 0x00d9,0x0044, 0x00e1,0x0004, 0x00e2,0x000d, - 0x00e2,0x0021, 0x00e0,0x003a, 0x00e6,0x003d, 0x00e6,0x0061, 0x00e6,0x0067, - 0x00e9,0x0004, 0x00ea,0x0008, 0x00ea,0x0009, 0x00ea,0x0039, 0x00e9,0x0038, - 0x00ea,0x003f, 0x00ec,0x000d, 0x00ee,0x000d, 0x00ee,0x0037, 0x00f2,0x003d, - 0x00f2,0x0062, 0x00f5,0x0002, 0x00fa,0x0017, 0x00fa,0x003d, 0x00fe,0x0006, - 0x00fd,0x0006, 0x00fc,0x0015, 0x00fe,0x001b, 0x00fc,0x0025, 0x00fe,0x0025, - 0x00fd,0x0024, 0x00fe,0x0041, 0x00fe,0x004d, 0x00fd,0x004e, 0x0101,0x0014, - 0x0106,0x004d, 0x010a,0x0009, 0x010a,0x000b, 0x0109,0x000a, 0x010a,0x004f, - 0x010a,0x0058, 0x010e,0x0008, 0x010c,0x0009, 0x010e,0x0009, 0x010d,0x0008, - 0x010e,0x000b, 0x010e,0x002b, 0x010d,0x002a, 0x010e,0x0035, 0x010e,0x003d, - 0x010e,0x003f, 0x010e,0x0049, 0x010e,0x0057, 0x010d,0x0056, 0x010d,0x0058, - 0x0111,0x0004, 0x0111,0x0006, 0x0110,0x0009, 0x0112,0x0009, 0x0111,0x0008, - 0x0112,0x002f, 0x0110,0x0035, 0x0110,0x0037, 0x0112,0x0039, 0x0112,0x003d, - 0x0112,0x003f, 0x0112,0x0045, 0x0111,0x0044, 0x0112,0x004b, 0x0112,0x0059, - 0x0112,0x0069, 0x0112,0x007f, 0x0116,0x0009, 0x0115,0x0008, 0x0114,0x000b, - 0x0116,0x000b, 0x0116,0x0058, 0x011a,0x0015, 0x011a,0x001f, 0x011a,0x002b, - 0x011a,0x003f, 0x011a,0x0049, 0x011a,0x0085, 0x011e,0x0007, 0x011e,0x0019, - 0x011e,0x001b, 0x011e,0x0023, 0x011e,0x0027, 0x011e,0x002f, 0x011e,0x0043, - 0x011e,0x004b, 0x011e,0x004e, 0x011e,0x004f, 0x011e,0x005f, 0x011e,0x0061, - 0x011e,0x0065, 0x011e,0x0083, 0x0122,0x0006, 0x0120,0x0007, 0x0122,0x0007, - 0x0121,0x0006, 0x0122,0x0049, 0x0121,0x004e, 0x0122,0x008f, 0x0125,0x0004, - 0x0124,0x0007, 0x0125,0x0006, 0x0124,0x001b, 0x0126,0x001b, 0x0126,0x0045, - 0x0126,0x0087, 0x0128,0x0007, 0x0129,0x0006, 0x012a,0x0019, 0x012a,0x003d, - 0x012a,0x0051, 0x012a,0x0065, 0x012a,0x0083, 0x012d,0x005a, 0x0132,0x0009, - 0x0132,0x008f, 0x0134,0x0009, 0x0135,0x003e, 0x013a,0x003d, 0x013a,0x0044, - 0x0139,0x0044, 0x013e,0x0009, 0x013d,0x0008, 0x013c,0x003d, 0x013c,0x0044, - 0x013c,0x0053, 0x013e,0x008f, 0x013e,0x0095, 0x0142,0x0044, 0x0142,0x0097, - 0x0142,0x009e, 0x0144,0x0007, 0x0148,0x0015, 0x0148,0x001c, 0x0148,0x001f, - 0x0148,0x0026, 0x0149,0x0086, 0x014d,0x0006, 0x014e,0x0044, 0x014d,0x0048, - 0x014e,0x009e, 0x0152,0x0009, 0x0151,0x00a6, 0x0155,0x0030, 0x015d,0x003a, - 0x0162,0x009e, 0x0164,0x000f, 0x0164,0x0013, 0x0169,0x000e, 0x0174,0x0009, - 0x0179,0x0008, 0x0180,0x0009, 0x0181,0x0044, 0x0186,0x0044, 0x0185,0x0044, - 0x018a,0x0068, 0x0195,0x004e, 0x01a6,0x0009, 0x01a5,0x0008, 0x01b1,0x003a, - 0x01c4,0x0029, 0x01c4,0x0030, 0x01ca,0x008f, 0x01ca,0x0095, 0x01cc,0x0029, - 0x01cc,0x0033, 0x01ce,0x003d, 0x01d6,0x00b2, 0x01d8,0x0009, 0x01d9,0x002a, - 0x01d9,0x0056, 0x01d9,0x00a4, 0x01dd,0x003a, 0x01e2,0x00b2, 0x01e6,0x0013, - 0x01e6,0x009f, 0x01e6,0x00ba, 0x01e6,0x00c0, 0x01e6,0x00d3, 0x01e6,0x00d5, - 0x01e6,0x00e5, 0x01e8,0x0005, 0x01f2,0x0013, 0x01f2,0x0095, 0x01f2,0x009f, - 0x01f2,0x00ba, 0x01f2,0x00c0, 0x01f2,0x00d3, 0x0202,0x008f, 0x0202,0x0095, - 0x0202,0x00f3, 0x0202,0x00f9, 0x020a,0x0044, 0x0209,0x00b4, 0x020e,0x0009, - 0x020d,0x0008, 0x020c,0x003d, 0x020c,0x0044, 0x020c,0x0053, 0x020e,0x008f, - 0x020e,0x0095, 0x020c,0x00b1, 0x020e,0x00f3, 0x020e,0x00f9, 0x0210,0x0013, - 0x0211,0x0024, 0x0210,0x0026, 0x0219,0x0004, 0x021e,0x008f, 0x021e,0x0095, - 0x0221,0x003a, 0x0230,0x0009, 0x0236,0x0009, 0x0234,0x0029, 0x0234,0x0030, - 0x0234,0x0033, 0x0234,0x003a, 0x0234,0x003d, 0x0234,0x0044, 0x0235,0x00a6, - 0x023a,0x0009, 0x023d,0x003a, 0x0245,0x0044, 0x0249,0x003a, 0x024e,0x009e, - 0x024e,0x0106, 0x0251,0x0026, 0x0258,0x0013, 0x0259,0x0024, 0x0258,0x0061, - 0x0259,0x0086, 0x0258,0x00c7, 0x0258,0x00df, 0x0259,0x00ec, 0x0258,0x00fc, - 0x025d,0x0024, 0x025d,0x00de, 0x0260,0x00f6, 0x0268,0x0009, 0x0269,0x0044, - 0x0268,0x00f3, 0x0268,0x00f9, 0x026d,0x003a, 0x0270,0x0068, 0x0275,0x003a, - 0x027a,0x0044, 0x0279,0x0044, 0x027e,0x007e, 0x0281,0x0044, 0x0285,0x0008, - 0x028d,0x0006, 0x028d,0x00d2, 0x0295,0x00cc, 0x0296,0x00f6, 0x0295,0x00f8, - 0x0299,0x0030, 0x029e,0x007e, 0x029d,0x0080, 0x02a6,0x008f, 0x02a6,0x0095, - 0x02aa,0x0029, 0x02aa,0x0030, 0x02b5,0x0008, 0x02b9,0x003a, 0x02bd,0x0004, - 0x02bd,0x00fc, 0x02c2,0x00b2, 0x02c1,0x00b4, 0x02c4,0x0029, 0x02c8,0x0029, - 0x02c8,0x0033, 0x02ca,0x003d, 0x02ce,0x0029, 0x02ce,0x0030, 0x02d2,0x0068, - 0x02d1,0x006a, 0x02d5,0x006a, 0x02d9,0x0008, 0x02de,0x012c, 0x02e2,0x012c, - 0x02e4,0x0009, 0x02e5,0x002a, 0x02e5,0x0056, 0x02e5,0x012c, 0x02ea,0x0029, - 0x02ea,0x0030, 0x02e9,0x0030, 0x02ec,0x0029, 0x02ec,0x0030, 0x02ee,0x012c, - 0x02f1,0x0068, 0x02f1,0x00b2, 0x02f1,0x0108, 0x02f1,0x012c, 0x02f6,0x0013, - 0x02f6,0x0015, 0x02f6,0x001f, 0x02f6,0x0030, 0x02f6,0x0065, 0x02f6,0x0067, - 0x02f6,0x009f, 0x02f6,0x00b6, 0x02f6,0x00b9, 0x02f6,0x00c0, 0x02f6,0x00cf, - 0x02f6,0x0107, 0x02f6,0x010b, 0x02f6,0x010f, 0x02f6,0x0115, 0x02f6,0x012d, - 0x02f6,0x0134, 0x02f6,0x0153, 0x02f6,0x0171, 0x02f6,0x0176, 0x02f8,0x0003, - 0x02fa,0x017b, 0x02fc,0x00ba, 0x02fc,0x00d3, 0x0302,0x0013, 0x0302,0x001f, - 0x0302,0x0030, 0x0302,0x005d, 0x0302,0x0065, 0x0302,0x0067, 0x0302,0x0099, - 0x0302,0x009f, 0x0302,0x00ad, 0x0302,0x00b9, 0x0302,0x00c0, 0x0302,0x00cf, - 0x0301,0x00d2, 0x0301,0x00fe, 0x0302,0x0107, 0x0302,0x010b, 0x0302,0x010f, - 0x0302,0x0117, 0x0302,0x0134, 0x0302,0x0153, 0x0302,0x0157, 0x0302,0x0176, - 0x0306,0x0029, 0x0308,0x00b2, 0x0309,0x00dc, 0x030d,0x00f8, 0x0312,0x00f3, - 0x0318,0x007e, 0x031d,0x0080, 0x0321,0x0008, 0x0321,0x0094, 0x0326,0x017b, - 0x0326,0x0181, 0x0329,0x012e, 0x032a,0x017b, 0x032a,0x0181, 0x032e,0x008f, - 0x032e,0x0095, 0x032e,0x00f3, 0x032e,0x00f9, 0x0332,0x0009, 0x0331,0x0008, - 0x0330,0x003d, 0x0330,0x0044, 0x0330,0x0053, 0x0332,0x008f, 0x0332,0x0095, - 0x0330,0x00b1, 0x0332,0x00f3, 0x0332,0x00f9, 0x0330,0x0127, 0x0332,0x017b, - 0x0332,0x0181, 0x033c,0x0013, 0x033c,0x001c, 0x033d,0x0086, 0x033d,0x00ec, - 0x033d,0x0172, 0x033e,0x019d, 0x0345,0x0002, 0x0344,0x008f, 0x0344,0x00f3, - 0x034d,0x0030, 0x0352,0x0033, 0x0354,0x0029, 0x0354,0x0030, 0x035a,0x0009, - 0x035a,0x017b, 0x035a,0x019b, 0x035a,0x01a2, 0x035e,0x0181, 0x0360,0x0009, - 0x0366,0x0009, 0x0364,0x0029, 0x0364,0x0030, 0x0364,0x0033, 0x0364,0x003a, - 0x0364,0x003d, 0x0364,0x0044, 0x0369,0x0030, 0x0370,0x0029, 0x0370,0x0030, - 0x0376,0x0033, 0x037a,0x0009, 0x037a,0x019b, 0x037a,0x01a2, 0x037c,0x0009, - 0x0382,0x0181, 0x0386,0x0009, 0x0384,0x0029, 0x0384,0x0030, 0x0384,0x0033, - 0x0384,0x003a, 0x0384,0x003d, 0x0384,0x0044, 0x038a,0x0044, 0x038a,0x009e, - 0x038a,0x0106, 0x038a,0x0198, 0x038d,0x010e, 0x038d,0x0152, 0x038d,0x0158, - 0x0392,0x009e, 0x0392,0x0106, 0x0392,0x0198, 0x0395,0x0086, 0x0395,0x009a, - 0x0395,0x00ec, 0x0395,0x0172, 0x0398,0x014e, 0x0398,0x0175, 0x0398,0x018d, - 0x039c,0x0023, 0x039c,0x0027, 0x039c,0x00ef, 0x039c,0x0139, 0x039c,0x0168, - 0x03a0,0x0019, 0x03a0,0x001d, 0x03a0,0x0023, 0x03a0,0x0027, 0x03a1,0x004e, - 0x03a4,0x0162, 0x03a4,0x0183, 0x03a8,0x0013, 0x03a8,0x0027, 0x03a8,0x0133, - 0x03a8,0x0148, 0x03a8,0x0181, 0x03ac,0x0013, 0x03ac,0x0027, 0x03b0,0x017b, - 0x03b0,0x0181, 0x03b4,0x004b, 0x03b4,0x00e0, 0x03b4,0x00fb, 0x03b8,0x000f, - 0x03b8,0x0013, 0x03b8,0x00ab, 0x03b8,0x00bf, 0x03b8,0x00d0, 0x03bd,0x00da, - 0x03bd,0x012c, 0x03c8,0x000f, 0x03c8,0x0013, 0x03c8,0x0019, 0x03c8,0x001d, - 0x03cd,0x0086, 0x03cd,0x00ec, 0x03cd,0x0172, 0x03d2,0x00e0, 0x03d2,0x00ef, - 0x03d2,0x0112, 0x03d2,0x0139, 0x03d2,0x0168, 0x03d6,0x017b, 0x03d6,0x0181, - 0x03da,0x0133, 0x03da,0x0148, 0x03e2,0x0023, 0x03e2,0x0027, 0x03e6,0x0027, - 0x03e6,0x0181, 0x03ee,0x017b, 0x03ee,0x0181, 0x03fe,0x003d, 0x0401,0x012a, - 0x0401,0x019e, 0x0405,0x01a0, 0x040a,0x000d, 0x040a,0x011f, 0x040a,0x016f, - 0x040d,0x012a, 0x0412,0x017b, 0x041a,0x0033, 0x041a,0x003d, 0x041a,0x0181, - 0x0421,0x0086, 0x0421,0x009a, 0x0421,0x00ec, 0x0421,0x0172, 0x042e,0x0205, - 0x043a,0x0205, 0x043e,0x017b, 0x0442,0x01f5, 0x044c,0x0007, 0x0452,0x0033, - 0x0452,0x01ce, 0x0452,0x01d0, 0x0452,0x01f1, 0x0452,0x01fb, 0x0452,0x0225, - 0x0454,0x0005, 0x045a,0x0033, 0x045a,0x0181, 0x045a,0x01ce, 0x045a,0x01d0, - 0x045a,0x01f1, 0x0469,0x01de, 0x046e,0x0181, 0x047a,0x01ce, 0x047a,0x01f1, - 0x0485,0x012c, 0x0489,0x012c, 0x0490,0x01d8, 0x0496,0x0033, 0x0496,0x003d, - 0x0498,0x008f, 0x0498,0x00f3, 0x049e,0x0044, 0x049e,0x0221, 0x04a1,0x0006, - 0x04a2,0x0044, 0x04a6,0x0221, 0x04a9,0x0004, 0x04ac,0x0027, 0x04b1,0x009a, - 0x04b6,0x0097, 0x04b8,0x0027, 0x04c6,0x0219, 0x04ca,0x017b, 0x04cc,0x004b, - 0x04d0,0x00ab, 0x04d6,0x017b, 0x04d8,0x000f, 0x04d8,0x0019, 0x04d8,0x0033, - 0x04d8,0x003d, 0x04de,0x003d, 0x04de,0x0103, 0x04de,0x018b, 0x04de,0x0231, - 0x04e2,0x0044, 0x04e2,0x009e, 0x04e2,0x0106, 0x04e2,0x0198, 0x04e5,0x01a4, - 0x04e5,0x01b6, 0x04ea,0x009e, 0x04ea,0x0106, 0x04ea,0x0198, 0x04ed,0x002e, - 0x04ed,0x0038, 0x04ed,0x00a2, 0x04f1,0x0086, 0x04f1,0x009a, 0x04f1,0x00ec, - 0x04f1,0x0172, 0x04f9,0x004e, 0x04f8,0x0229, 0x04f8,0x022d, 0x0500,0x023e, - 0x0504,0x0217, 0x0510,0x00f3, 0x0514,0x0043, 0x0514,0x004d, 0x0514,0x00c3, - 0x0514,0x013d, 0x0514,0x0215, 0x0514,0x0232, 0x0515,0x0260, 0x0519,0x002a, - 0x0518,0x0030, 0x0518,0x0067, 0x0518,0x00c9, 0x0518,0x01eb, 0x0518,0x01ef, - 0x051c,0x0139, 0x051c,0x0168, 0x0520,0x0027, 0x0526,0x014e, 0x0526,0x0175, - 0x0526,0x018d, 0x052d,0x0200, 0x0532,0x0021, 0x0532,0x00bf, 0x0532,0x00d0, - 0x0532,0x0239, 0x0532,0x0266, 0x053d,0x0024, 0x053d,0x00da, 0x054a,0x000f, - 0x054a,0x00ab, 0x054a,0x023a, 0x054e,0x0043, 0x054e,0x004d, 0x054e,0x00c3, - 0x054e,0x013d, 0x054e,0x0215, 0x054e,0x0232, 0x054e,0x029d, 0x0552,0x014e, - 0x0552,0x018d, 0x0556,0x00f3, 0x0556,0x01e4, 0x055a,0x0299, 0x055d,0x0086, - 0x055d,0x009a, 0x055d,0x00ec, 0x055d,0x0172, 0x0566,0x01dc, 0x0566,0x02a5, - 0x056d,0x020a, 0x057a,0x003d, 0x057a,0x01d4, 0x057a,0x01f3, 0x0579,0x025e, - 0x057e,0x0139, 0x057e,0x0168, 0x0581,0x0006, 0x0586,0x017b, 0x0586,0x0181, - 0x0586,0x028c, 0x0588,0x0007, 0x058e,0x0033, 0x058e,0x008f, 0x058e,0x01d0, - 0x058e,0x027c, 0x0590,0x0003, 0x0596,0x0033, 0x0596,0x008f, 0x0596,0x0095, - 0x0596,0x01d0, 0x0596,0x027c, 0x05a2,0x026f, 0x05a5,0x0284, 0x05aa,0x017b, - 0x05ac,0x0205, 0x05b2,0x008f, 0x05b6,0x017b, 0x05b8,0x01da, 0x05c1,0x0276, - 0x05c6,0x0248, 0x05c8,0x0247, 0x05c8,0x027e, 0x05cc,0x003d, 0x05cc,0x01d4, - 0x05cc,0x01f3, 0x05d0,0x014e, 0x05d0,0x018d, 0x05da,0x00f9, 0x05dd,0x0006, - 0x05de,0x0044, 0x05e5,0x002e, 0x05e6,0x02f1, 0x05ea,0x01d4, 0x05ea,0x01f3, - 0x05ea,0x022d, 0x05ed,0x0002, 0x05f6,0x0027, 0x05fa,0x0097, 0x05fc,0x003d, - 0x0602,0x003d, 0x0606,0x00f3, 0x060a,0x0027, 0x060e,0x003d, 0x060e,0x0103, - 0x060e,0x018b, 0x060e,0x0231, 0x060e,0x02d1, 0x0611,0x01fc, 0x0611,0x0234, - 0x061a,0x0287, 0x061d,0x0214, 0x0621,0x01d4, 0x062a,0x0027, 0x062a,0x022d, - 0x062e,0x009e, 0x062e,0x0106, 0x062e,0x0198, 0x0632,0x009e, 0x0632,0x0106, - 0x0632,0x0198, 0x0639,0x0042, 0x0639,0x00b2, 0x0639,0x0108, 0x063d,0x01f8, - 0x0641,0x0086, 0x0641,0x009a, 0x0641,0x00ec, 0x0641,0x0172, 0x0645,0x0044, - 0x0649,0x0042, 0x0648,0x0087, 0x0648,0x00ed, 0x0648,0x0173, 0x0649,0x01a0, - 0x0648,0x0241, 0x0648,0x026f, 0x0648,0x02df, 0x0648,0x0307, 0x064c,0x023a, - 0x064c,0x02b3, 0x0651,0x0062, 0x0650,0x0217, 0x0651,0x02ac, 0x0650,0x02d6, - 0x0655,0x0042, 0x065d,0x0042, 0x0664,0x02b1, 0x0664,0x02ce, 0x0669,0x0238, - 0x066d,0x002a, 0x066c,0x0039, 0x066d,0x01f6, 0x066c,0x0213, 0x066c,0x022e, - 0x066d,0x02a2, 0x066c,0x02e1, 0x0671,0x002a, 0x0670,0x0030, 0x0670,0x0067, - 0x0670,0x00c9, 0x0670,0x01eb, 0x0670,0x01ef, 0x0670,0x02c3, 0x0675,0x0020, - 0x0678,0x0133, 0x0678,0x0148, 0x067c,0x0027, 0x0681,0x023a, 0x0684,0x0021, - 0x0684,0x00bf, 0x0684,0x00d0, 0x0689,0x01fc, 0x068e,0x0162, 0x068e,0x0183, - 0x0691,0x0200, 0x0696,0x0023, 0x0696,0x00e0, 0x0696,0x00fb, 0x0696,0x0268, - 0x069a,0x0282, 0x069d,0x007e, 0x06a2,0x004b, 0x06a2,0x023e, 0x06a2,0x02dc, - 0x06a6,0x0097, 0x06aa,0x02b1, 0x06aa,0x02ce, 0x06ae,0x0039, 0x06ae,0x0213, - 0x06ae,0x022e, 0x06ae,0x02e1, 0x06b2,0x0162, 0x06b2,0x0183, 0x06b6,0x0023, - 0x06b6,0x00e0, 0x06b6,0x00fb, 0x06ba,0x008f, 0x06ba,0x01e4, 0x06be,0x034b, - 0x06c1,0x0086, 0x06c1,0x009a, 0x06c1,0x00ec, 0x06c1,0x0172, 0x06c6,0x01da, - 0x06c6,0x0280, 0x06c6,0x0351, 0x06ce,0x008f, 0x06d2,0x01e3, 0x06d2,0x0287, - 0x06d2,0x0353, 0x06d6,0x027a, 0x06d6,0x029b, 0x06da,0x0033, 0x06da,0x01ce, - 0x06da,0x01f1, 0x06de,0x0133, 0x06de,0x0148, 0x06e2,0x0021, 0x06e2,0x00bf, - 0x06e2,0x00d0, 0x06e5,0x023a, 0x06e9,0x0004, 0x06ee,0x028c, 0x06ee,0x0338, - 0x06f2,0x0328, 0x06f2,0x0330, 0x06f4,0x0005, 0x06f9,0x01e0, 0x06fe,0x0328, - 0x06fe,0x0330, 0x0702,0x003d, 0x0702,0x00f3, 0x0702,0x0330, 0x0704,0x0003, - 0x070a,0x003d, 0x070a,0x00f3, 0x070a,0x01d4, 0x070a,0x01f3, 0x070a,0x0330, - 0x0711,0x032a, 0x0711,0x032e, 0x0716,0x003d, 0x0718,0x0205, 0x0718,0x0282, - 0x071e,0x00f3, 0x0720,0x01dc, 0x0720,0x02a5, 0x0726,0x0324, 0x072a,0x028a, - 0x072a,0x02a7, 0x0729,0x031c, 0x0729,0x032a, 0x072e,0x003d, 0x072e,0x00f9, - 0x072e,0x022d, 0x072e,0x0248, 0x072e,0x02e4, 0x0730,0x003d, 0x0730,0x0247, - 0x0730,0x02e3, 0x0730,0x0324, 0x0732,0x0324, 0x0739,0x032e, 0x073e,0x003d, - 0x0740,0x003d, 0x0744,0x027a, 0x0744,0x029b, 0x0748,0x0033, 0x0748,0x01ce, - 0x0748,0x01f1, 0x074c,0x0162, 0x074c,0x0183, 0x0750,0x0023, 0x0750,0x00e0, - 0x0750,0x00fb, 0x0755,0x0246, 0x075a,0x0095, 0x075a,0x0397, 0x075d,0x0004, - 0x076a,0x03b3, 0x076d,0x0002, 0x0772,0x02fb, 0x0772,0x0301, 0x0772,0x0315, - 0x0772,0x0397, 0x0776,0x008f, 0x077e,0x0027, 0x078a,0x00a1, 0x0792,0x009d, - 0x0792,0x00c3, 0x0792,0x02fb, 0x0792,0x0301, 0x0792,0x0315, 0x0792,0x03bd, - 0x0796,0x0027, 0x0796,0x024f, 0x079e,0x009d, 0x07a6,0x009d, 0x07a6,0x02fb, - 0x07a6,0x0301, 0x07a6,0x0315, 0x07a6,0x03bd, 0x07aa,0x0027, 0x07aa,0x024f, - 0x07ae,0x009d, 0x07b9,0x004e, 0x07b8,0x0087, 0x07b8,0x00ed, 0x07b8,0x0173, - 0x07b8,0x0197, 0x07b9,0x021a, 0x07b9,0x02b8, 0x07b9,0x0364, 0x07be,0x0029, - 0x07be,0x0030, 0x07c0,0x017b, 0x07c6,0x017b, 0x07c8,0x00f3, 0x07ce,0x00f3, - 0x07d0,0x008f, 0x07d6,0x008f, 0x07d9,0x01e8, 0x07dd,0x0292, 0x07e2,0x0053, - 0x07e6,0x008f, 0x07e6,0x00f3, 0x07e6,0x017b, 0x07e8,0x0029, 0x07e8,0x0030, - 0x07ec,0x0021, 0x07ec,0x02ad, 0x07f2,0x0181, 0x07f2,0x0315, 0x07f4,0x0021, - 0x07f8,0x020f, 0x07fd,0x002e, 0x0800,0x008f, 0x0805,0x0006, 0x0809,0x03c2, - 0x080d,0x0084, 0x0812,0x0009, 0x0811,0x0008, 0x0812,0x00f3, 0x0812,0x00f9, - 0x0812,0x017b, 0x0812,0x0181, 0x0814,0x0033, 0x0818,0x0023, 0x081c,0x0285, - 0x0826,0x03bd, 0x082c,0x008f, 0x082c,0x017b, 0x0832,0x0043, 0x0832,0x011b, - 0x0832,0x01b3, 0x0832,0x01c3, 0x0835,0x032a, 0x0838,0x0085, 0x0839,0x032a, - 0x083e,0x0049, 0x083d,0x0084, 0x083e,0x02fb, 0x083e,0x0301, 0x083e,0x0315, - 0x083e,0x0397, 0x0842,0x0009, 0x0841,0x0008, 0x0844,0x0009, 0x0846,0x008f, - 0x084a,0x0033, 0x084e,0x0285, 0x0851,0x009a, 0x0856,0x00a1, 0x0859,0x031c, - 0x085d,0x00b2, 0x0861,0x0012, 0x0861,0x02cc, 0x0865,0x0058, 0x0865,0x007e, - 0x0869,0x004a, 0x0871,0x0010, 0x0876,0x003d, 0x0879,0x032c, 0x087e,0x0089, - 0x0882,0x0229, 0x0882,0x022d, 0x0882,0x02c7, 0x0882,0x02cb, 0x0886,0x0021, - 0x0886,0x02ad, 0x0885,0x0356, 0x088a,0x0017, 0x088a,0x020f, 0x0889,0x0354, - 0x088d,0x009c, 0x0892,0x0089, 0x0895,0x0246, 0x089a,0x03bd, 0x089e,0x008f, - 0x089e,0x02f9, 0x089e,0x0313, 0x08a1,0x032a, 0x08a6,0x0053, 0x08a6,0x0095, - 0x08a6,0x0397, 0x08a8,0x017b, 0x08ad,0x031a, 0x08b2,0x017b, 0x08b4,0x00f3, - 0x08b5,0x02a0, 0x08b8,0x0089, 0x08c1,0x0024, 0x08c4,0x00f3, 0x08c9,0x007e, - 0x08cd,0x007c, 0x08cd,0x0222, 0x08cd,0x0294, 0x08d1,0x003a, 0x08d6,0x0009, - 0x08d9,0x003a, 0x08dc,0x001f, 0x08e0,0x008f, 0x08e0,0x017b, 0x08e4,0x0009, - 0x08e8,0x01ed, 0x08ed,0x031c, 0x08f2,0x003d, 0x08f6,0x008f, 0x08f6,0x017b, - 0x08fa,0x0009, 0x08fe,0x003d, 0x0902,0x01e9, 0x0904,0x01e9, 0x0904,0x0381, - 0x090a,0x03b1, 0x090d,0x031a, 0x0910,0x0299, 0x0914,0x034b, 0x0919,0x0008, - 0x091c,0x0033, 0x091c,0x003d, 0x0920,0x0027, 0x0924,0x0027, 0x0924,0x01fb, - 0x092a,0x01ce, 0x092a,0x01f1, 0x092d,0x031c, 0x0930,0x001f, 0x0936,0x00c5, - 0x0938,0x00c5, 0x0938,0x0381, 0x093c,0x001b, 0x0942,0x017d, 0x094a,0x0027, - 0x094e,0x0027, 0x094e,0x01fb, 0x0952,0x03b1, 0x095a,0x0029, 0x095a,0x0030, - 0x095d,0x0030, 0x0961,0x0030, 0x0966,0x02f9, 0x0966,0x0313, 0x0968,0x02eb, - 0x096d,0x0008, 0x0970,0x017b, 0x0974,0x0033, 0x0979,0x0150, 0x097d,0x009a, - 0x0982,0x0293, 0x0984,0x0293, 0x0984,0x0379, 0x098a,0x02eb, 0x098e,0x0009, - 0x0992,0x003d, 0x0996,0x003d, 0x0999,0x0062, 0x099e,0x003d, 0x09a0,0x0027, - 0x09a5,0x0144, 0x09a8,0x02b5, 0x09ae,0x008f, 0x09ae,0x009d, 0x09b2,0x004d, - 0x09b2,0x0053, 0x09b2,0x00c3, 0x09b2,0x013d, 0x09b2,0x01c5, 0x09b2,0x0271, - 0x09b4,0x0025, 0x09ba,0x0033, 0x09ba,0x0079, 0x09bc,0x0015, 0x09c2,0x013f, - 0x09c4,0x013f, 0x09c4,0x0379, 0x09ca,0x02b5, 0x09cd,0x0006, 0x09da,0x0009, - 0x09d9,0x0008, 0x09dc,0x000b, 0x09dc,0x004f, 0x09dd,0x0086, 0x09e0,0x0009, - 0x09e6,0x00a1, 0x09e8,0x0009, 0x09ed,0x0086, 0x09f2,0x001f, 0x09f2,0x002f, - 0x09f2,0x0049, 0x09f2,0x006f, 0x09f2,0x0085, 0x09f2,0x0091, 0x09f2,0x00a9, - 0x09f2,0x00d3, 0x09f2,0x00d7, 0x09f2,0x011d, 0x09f2,0x0121, 0x09f2,0x0235, - 0x09f2,0x0393, 0x09f6,0x0324, 0x09f8,0x0049, 0x09f8,0x00a9, 0x09f8,0x011d, - 0x09fe,0x001f, 0x09fe,0x0029, 0x09fe,0x0033, 0x09fe,0x003d, 0x09fe,0x0085, - 0x09fe,0x008f, 0x09fe,0x00d3, 0x0a00,0x003d, 0x0a06,0x012d, 0x0a0e,0x00b3, - 0x0a10,0x000b, 0x0a10,0x0387, 0x0a16,0x0059, 0x0a18,0x0009, 0x0a1e,0x0043, - 0x0a24,0x0085, 0x0a2a,0x0009, 0x0a2d,0x0008, 0x0a32,0x028a, 0x0a32,0x02a7, - 0x0a31,0x031c, 0x0a35,0x032e, 0x0a39,0x0006, 0x0a3a,0x0105, 0x0a3a,0x024f, - 0x0a3c,0x0299, 0x0a42,0x01ed, 0x0a46,0x0299, 0x0a48,0x01ed, 0x0a4c,0x0059, - 0x0a52,0x000b, 0x0a52,0x0387, 0x0a56,0x000b, 0x0a5e,0x0009, 0x0a60,0x003d, - 0x0a66,0x0105, 0x0a6a,0x0195, 0x0a6c,0x000b, 0x0a76,0x0053, 0x0a78,0x0009, - 0x0a7a,0x008f, 0x0a82,0x0299, 0x0a86,0x01ed, 0x0a8a,0x0027, 0x0a8e,0x004b, - 0x0a92,0x003d, 0x0a95,0x0322, 0x0a99,0x0038, 0x0a99,0x0090, 0x0a9c,0x0061, - 0x0a9c,0x00c7, 0x0a9c,0x012d, 0x0a9c,0x016f, 0x0a9c,0x017d, 0x0a9c,0x02c9, - 0x0a9c,0x0383, 0x0aa1,0x0010, 0x0aa4,0x00b3, 0x0aa8,0x002f, 0x0aac,0x0027, - 0x0ab0,0x004b, 0x0ab4,0x0043, 0x0ab9,0x0090, 0x0abd,0x0010, 0x0ac4,0x0019, - 0x0acc,0x00f5, 0x0acc,0x022b, 0x0acc,0x037b, 0x0ad2,0x008f, 0x0ad2,0x01f1, - 0x0ad6,0x0324, 0x0ad9,0x0330, 0x0ade,0x008f, 0x0ade,0x01f1, 0x0ae0,0x017b, - 0x0ae4,0x008f, 0x0ae9,0x004e, 0x0aee,0x0027, 0x0af2,0x028a, 0x0af2,0x02a7, - 0x0af1,0x031c, 0x0af6,0x0027, 0x0af9,0x031c, 0x0afe,0x00e9, 0x0afe,0x02bb, - 0x0b02,0x000b, 0x0b06,0x00f5, 0x0b06,0x022b, 0x0b06,0x037b, 0x0b0a,0x003d, - 0x0000,0x0000 -}; - - diff --git a/src/opt/sim/module.make b/src/opt/sim/module.make deleted file mode 100644 index 54058402..00000000 --- a/src/opt/sim/module.make +++ /dev/null @@ -1,10 +0,0 @@ -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 \ - src/opt/sim/simSymSat.c \ - src/opt/sim/simSymSim.c \ - src/opt/sim/simSymStr.c \ - src/opt/sim/simUtils.c diff --git a/src/opt/sim/sim.h b/src/opt/sim/sim.h deleted file mode 100644 index 7fcf5ae6..00000000 --- a/src/opt/sim/sim.h +++ /dev/null @@ -1,233 +0,0 @@ -/**CFile**************************************************************** - - FileName [sim.h] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Simulation package.] - - Synopsis [External declarations.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - 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, - Simulation, and Satisfiability". -*/ - -//////////////////////////////////////////////////////////////////////// -/// INCLUDES /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// PARAMETERS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// BASIC TYPES /// -//////////////////////////////////////////////////////////////////////// - -typedef struct Sym_Man_t_ Sym_Man_t; -struct Sym_Man_t_ -{ - // info about the network - Abc_Ntk_t * pNtk; // the network - Vec_Ptr_t * vNodes; // internal nodes in topological order - int nInputs; - int nOutputs; - // internal simulation information - int nSimWords; // the number of bits in simulation info - Vec_Ptr_t * vSim; // simulation info - // support information - Vec_Ptr_t * vSuppFun; // bit representation - Vec_Vec_t * vSupports; // integer representation - // symmetry info for each output - Vec_Ptr_t * vMatrSymms; // symmetric pairs - Vec_Ptr_t * vMatrNonSymms; // non-symmetric pairs - Vec_Int_t * vPairsTotal; // total pairs - Vec_Int_t * vPairsSym; // symmetric pairs - Vec_Int_t * vPairsNonSym; // non-symmetric pairs - // temporary simulation info - unsigned * uPatRand; - unsigned * uPatCol; - unsigned * uPatRow; - // temporary - Vec_Int_t * vVarsU; - Vec_Int_t * vVarsV; - int iOutput; - int iVar1; - int iVar2; - int iVar1Old; - int iVar2Old; - // internal data structures - int nSatRuns; - int nSatRunsSat; - int nSatRunsUnsat; - // pairs - int nPairsSymm; - int nPairsSymmStr; - int nPairsNonSymm; - int nPairsRem; - int nPairsTotal; - // runtime statistics - int timeStruct; - int timeCount; - int timeMatr; - int timeSim; - int timeFraig; - int timeSat; - int timeTotal; -}; - -typedef struct Sim_Man_t_ Sim_Man_t; -struct Sim_Man_t_ -{ - // info about the network - 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 - Vec_Ptr_t * vSim0; // simulation info 1 - Vec_Ptr_t * vSim1; // simulation info 2 - // support information - int nSuppBits; // the number of bits in support info - int nSuppWords; // the number of words in support info - Vec_Ptr_t * vSuppStr; // structural supports - Vec_Ptr_t * vSuppFun; // functional supports - // simulation targets - Vec_Vec_t * vSuppTargs; // support targets - int iInput; // the input current processed - // internal data structures - Extra_MmFixed_t * pMmPat; - Vec_Ptr_t * vFifo; - Vec_Int_t * vDiffs; - int nSatRuns; - int nSatRunsSat; - int nSatRunsUnsat; - // runtime statistics - int timeSim; - int timeTrav; - int timeFraig; - int timeSat; - int timeTotal; -}; - -typedef struct Sim_Pat_t_ Sim_Pat_t; -struct Sim_Pat_t_ -{ - int Input; // the input which it has detected - int Output; // the output for which it was collected - unsigned * pData; // the simulation data -}; - -//////////////////////////////////////////////////////////////////////// -/// MACRO DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -#define SIM_NUM_WORDS(n) (((n)>>5) + (((n)&31) > 0)) -#define SIM_LAST_BITS(n) ((((n)&31) > 0)? (n)&31 : 32) - -#define SIM_MASK_FULL (0xFFFFFFFF) -#define SIM_MASK_BEG(n) (SIM_MASK_FULL >> (32-n)) -#define SIM_MASK_END(n) (SIM_MASK_FULL << (n)) -#define SIM_SET_0_FROM(m,n) ((m) & ~SIM_MASK_BEG(n)) -#define SIM_SET_1_FROM(m,n) ((m) | SIM_MASK_END(n)) - -// generating random unsigned (#define RAND_MAX 0x7fff) -#define SIM_RANDOM_UNSIGNED ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand())) - -// macros to get hold of bits in a bit string -#define Sim_SetBit(p,i) ((p)[(i)>>5] |= (1<<((i) & 31))) -#define Sim_XorBit(p,i) ((p)[(i)>>5] ^= (1<<((i) & 31))) -#define Sim_HasBit(p,i) (((p)[(i)>>5] & (1<<((i) & 31))) > 0) - -// macros to get hold of the support info -#define Sim_SuppStrSetVar(vSupps,pNode,v) Sim_SetBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v)) -#define Sim_SuppStrHasVar(vSupps,pNode,v) Sim_HasBit((unsigned*)(vSupps)->pArray[(pNode)->Id],(v)) -#define Sim_SuppFunSetVar(vSupps,Output,v) Sim_SetBit((unsigned*)(vSupps)->pArray[Output],(v)) -#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 /// -//////////////////////////////////////////////////////////////////////// - -/*=== simMan.c ==========================================================*/ -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 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 ); -/*=== simSym.c ==========================================================*/ -extern int Sim_ComputeTwoVarSymms( Abc_Ntk_t * pNtk, int fVerbose ); -/*=== simSymSat.c ==========================================================*/ -extern int Sim_SymmsGetPatternUsingSat( Sym_Man_t * p, unsigned * pPattern ); -/*=== simSymStr.c ==========================================================*/ -extern void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * vSuppFun ); -/*=== simSymSim.c ==========================================================*/ -extern void Sim_SymmsSimulate( Sym_Man_t * p, unsigned * pPatRand, Vec_Ptr_t * vMatrsNonSym ); -/*=== simUtil.c ==========================================================*/ -extern Vec_Ptr_t * Sim_UtilInfoAlloc( int nSize, int nWords, bool fClean ); -extern void Sim_UtilInfoFree( Vec_Ptr_t * p ); -extern void Sim_UtilInfoAdd( unsigned * pInfo1, unsigned * pInfo2, int nWords ); -extern void Sim_UtilInfoDetectDiffs( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ); -extern void Sim_UtilInfoDetectNews( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ); -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 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 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 /// -//////////////////////////////////////////////////////////////////////// - diff --git a/src/opt/sim/simMan.c b/src/opt/sim/simMan.c deleted file mode 100644 index 3b50ad84..00000000 --- a/src/opt/sim/simMan.c +++ /dev/null @@ -1,288 +0,0 @@ -/**CFile**************************************************************** - - FileName [simMan.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation manager.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Starts the simulation manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Sym_Man_t * Sym_ManStart( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Sym_Man_t * p; - int i, v; - // start the manager - p = ALLOC( Sym_Man_t, 1 ); - memset( p, 0, sizeof(Sym_Man_t) ); - p->pNtk = pNtk; - p->vNodes = Abc_NtkDfs( pNtk, 0 ); - p->nInputs = Abc_NtkCiNum(p->pNtk); - p->nOutputs = Abc_NtkCoNum(p->pNtk); - // internal simulation information - p->nSimWords = SIM_NUM_WORDS(p->nInputs); - p->vSim = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), p->nSimWords, 0 ); - // symmetry info for each output - p->vMatrSymms = Vec_PtrStart( p->nOutputs ); - p->vMatrNonSymms = Vec_PtrStart( p->nOutputs ); - p->vPairsTotal = Vec_IntStart( p->nOutputs ); - p->vPairsSym = Vec_IntStart( p->nOutputs ); - p->vPairsNonSym = Vec_IntStart( p->nOutputs ); - for ( i = 0; i < p->nOutputs; i++ ) - { - p->vMatrSymms->pArray[i] = Extra_BitMatrixStart( p->nInputs ); - p->vMatrNonSymms->pArray[i] = Extra_BitMatrixStart( p->nInputs ); - } - // temporary patterns - p->uPatRand = ALLOC( unsigned, p->nSimWords ); - p->uPatCol = ALLOC( unsigned, p->nSimWords ); - p->uPatRow = ALLOC( unsigned, p->nSimWords ); - p->vVarsU = Vec_IntStart( 100 ); - p->vVarsV = Vec_IntStart( 100 ); - // compute supports - p->vSuppFun = Sim_ComputeFunSupp( pNtk, fVerbose ); - p->vSupports = Vec_VecStart( p->nOutputs ); - for ( i = 0; i < p->nOutputs; i++ ) - for ( v = 0; v < p->nInputs; v++ ) - if ( Sim_SuppFunHasVar( p->vSuppFun, i, v ) ) - Vec_VecPush( p->vSupports, i, (void *)v ); - return p; -} - -/**Function************************************************************* - - Synopsis [Stops the simulation manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sym_ManStop( Sym_Man_t * p ) -{ - int i; - Sym_ManPrintStats( p ); - if ( p->vSuppFun ) Sim_UtilInfoFree( p->vSuppFun ); - if ( p->vSim ) Sim_UtilInfoFree( p->vSim ); - if ( p->vNodes ) Vec_PtrFree( p->vNodes ); - if ( p->vSupports ) Vec_VecFree( p->vSupports ); - for ( i = 0; i < p->nOutputs; i++ ) - { - Extra_BitMatrixStop( p->vMatrSymms->pArray[i] ); - Extra_BitMatrixStop( p->vMatrNonSymms->pArray[i] ); - } - Vec_IntFree( p->vVarsU ); - Vec_IntFree( p->vVarsV ); - Vec_PtrFree( p->vMatrSymms ); - Vec_PtrFree( p->vMatrNonSymms ); - Vec_IntFree( p->vPairsTotal ); - Vec_IntFree( p->vPairsSym ); - Vec_IntFree( p->vPairsNonSym ); - FREE( p->uPatRand ); - FREE( p->uPatCol ); - FREE( p->uPatRow ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Prints the manager statisticis.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sym_ManPrintStats( Sym_Man_t * p ) -{ -// printf( "Inputs = %5d. Outputs = %5d. Sim words = %5d.\n", -// Abc_NtkCiNum(p->pNtk), Abc_NtkCoNum(p->pNtk), p->nSimWords ); - printf( "Total symm = %8d.\n", p->nPairsSymm ); - printf( "Structural symm = %8d.\n", p->nPairsSymmStr ); - printf( "Total non-sym = %8d.\n", p->nPairsNonSymm ); - printf( "Total var pairs = %8d.\n", p->nPairsTotal ); - printf( "Sat runs SAT = %8d.\n", p->nSatRunsSat ); - printf( "Sat runs UNSAT = %8d.\n", p->nSatRunsUnsat ); - PRT( "Structural ", p->timeStruct ); - PRT( "Simulation ", p->timeSim ); - PRT( "Matrix ", p->timeMatr ); - PRT( "Counting ", p->timeCount ); - PRT( "Fraiging ", p->timeFraig ); - PRT( "SAT ", p->timeSat ); - PRT( "TOTAL ", p->timeTotal ); -} - - -/**Function************************************************************* - - Synopsis [Starts the simulation manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Sim_Man_t * Sim_ManStart( Abc_Ntk_t * pNtk, int fLightweight ) -{ - Sim_Man_t * p; - // start the manager - p = ALLOC( Sim_Man_t, 1 ); - memset( p, 0, sizeof(Sim_Man_t) ); - p->pNtk = pNtk; - p->nInputs = Abc_NtkCiNum(p->pNtk); - p->nOutputs = Abc_NtkCoNum(p->pNtk); - // internal simulation information - 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 ); - } - return p; -} - -/**Function************************************************************* - - Synopsis [Stops the simulation manager.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_ManStop( Sim_Man_t * p ) -{ - Sim_ManPrintStats( p ); - if ( p->vSim0 ) Sim_UtilInfoFree( p->vSim0 ); - if ( p->vSim1 ) Sim_UtilInfoFree( p->vSim1 ); - 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->vFifo ) Vec_PtrFree( p->vFifo ); - if ( p->vDiffs ) Vec_IntFree( p->vDiffs ); - free( p ); -} - -/**Function************************************************************* - - Synopsis [Prints the manager statisticis.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_ManPrintStats( Sim_Man_t * p ) -{ -// printf( "Inputs = %5d. Outputs = %5d. Sim words = %5d.\n", -// Abc_NtkCiNum(p->pNtk), Abc_NtkCoNum(p->pNtk), p->nSimWords ); - printf( "Total func supps = %8d.\n", Sim_UtilCountSuppSizes(p, 0) ); - printf( "Total struct supps = %8d.\n", Sim_UtilCountSuppSizes(p, 1) ); - printf( "Sat runs SAT = %8d.\n", p->nSatRunsSat ); - printf( "Sat runs UNSAT = %8d.\n", p->nSatRunsUnsat ); - PRT( "Simulation ", p->timeSim ); - PRT( "Traversal ", p->timeTrav ); - PRT( "Fraiging ", p->timeFraig ); - PRT( "SAT ", p->timeSat ); - PRT( "TOTAL ", p->timeTotal ); -} - - - -/**Function************************************************************* - - Synopsis [Returns one simulation pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Sim_Pat_t * Sim_ManPatAlloc( Sim_Man_t * p ) -{ - Sim_Pat_t * pPat; - pPat = (Sim_Pat_t *)Extra_MmFixedEntryFetch( p->pMmPat ); - pPat->Output = -1; - pPat->pData = (unsigned *)((char *)pPat + sizeof(Sim_Pat_t)); - memset( pPat->pData, 0, p->nSuppWords * sizeof(unsigned) ); - return pPat; -} - -/**Function************************************************************* - - Synopsis [Returns one simulation pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_ManPatFree( Sim_Man_t * p, Sim_Pat_t * pPat ) -{ - Extra_MmFixedEntryRecycle( p->pMmPat, (char *)pPat ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/sim/simSat.c b/src/opt/sim/simSat.c deleted file mode 100644 index d514f7f2..00000000 --- a/src/opt/sim/simSat.c +++ /dev/null @@ -1,48 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSat.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation to determine functional support.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - 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 deleted file mode 100644 index f7048f4a..00000000 --- a/src/opt/sim/simSupp.c +++ /dev/null @@ -1,597 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSupp.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation to determine functional support.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simSupp.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "fraig.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int Sim_ComputeSuppRound( Sim_Man_t * p, bool fUseTargets ); -static int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets ); -static void Sim_ComputeSuppSetTargets( Sim_Man_t * p ); - -static void Sim_UtilAssignRandom( Sim_Man_t * p ); -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 ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes structural supports.] - - Description [Supports are returned as an array of bit strings, one - for each CO.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Sim_ComputeStrSupp( Abc_Ntk_t * pNtk ) -{ - Vec_Ptr_t * vSuppStr; - Abc_Obj_t * pNode; - unsigned * pSimmNode, * pSimmNode1, * pSimmNode2; - int nSuppWords, i, k; - // allocate room for structural supports - nSuppWords = SIM_NUM_WORDS( Abc_NtkCiNum(pNtk) ); - vSuppStr = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nSuppWords, 1 ); - // assign the structural support to the PIs - Abc_NtkForEachCi( pNtk, pNode, i ) - Sim_SuppStrSetVar( vSuppStr, pNode, i ); - // derive the structural supports of the internal nodes - Abc_NtkForEachNode( pNtk, pNode, i ) - { -// if ( Abc_NodeIsConst(pNode) ) -// continue; - pSimmNode = vSuppStr->pArray[ pNode->Id ]; - pSimmNode1 = vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ]; - pSimmNode2 = vSuppStr->pArray[ Abc_ObjFaninId1(pNode) ]; - for ( k = 0; k < nSuppWords; k++ ) - pSimmNode[k] = pSimmNode1[k] | pSimmNode2[k]; - } - // set the structural supports of the PO nodes - Abc_NtkForEachCo( pNtk, pNode, i ) - { - pSimmNode = vSuppStr->pArray[ pNode->Id ]; - pSimmNode1 = vSuppStr->pArray[ Abc_ObjFaninId0(pNode) ]; - for ( k = 0; k < nSuppWords; k++ ) - pSimmNode[k] = pSimmNode1[k]; - } - return vSuppStr; -} - -/**Function************************************************************* - - Synopsis [Compute functional supports.] - - Description [Supports are returned as an array of bit strings, one - for each CO.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Sim_ComputeFunSupp( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Sim_Man_t * p; - Vec_Ptr_t * vResult; - int nSolved, i, clk = clock(); - - srand( 0xABC ); - - // start the simulation manager - p = Sim_ManStart( pNtk, 0 ); - - // compute functional support using one round of random simulation - Sim_UtilAssignRandom( p ); - Sim_ComputeSuppRound( p, 0 ); - - // set the support targets - Sim_ComputeSuppSetTargets( p ); -if ( fVerbose ) - printf( "Number of support targets after simulation = %5d.\n", Vec_VecSizeSize(p->vSuppTargs) ); - if ( Vec_VecSizeSize(p->vSuppTargs) == 0 ) - goto exit; - - for ( i = 0; i < 1; i++ ) - { - // compute patterns using one round of random simulation - Sim_UtilAssignRandom( p ); - nSolved = Sim_ComputeSuppRound( p, 1 ); - if ( Vec_VecSizeSize(p->vSuppTargs) == 0 ) - goto exit; - -if ( fVerbose ) - printf( "Targets = %5d. Solved = %5d. Fifo = %5d.\n", - Vec_VecSizeSize(p->vSuppTargs), nSolved, Vec_PtrSize(p->vFifo) ); - } - - // try to solve the support targets - while ( Vec_VecSizeSize(p->vSuppTargs) > 0 ) - { - // solve targets until the first disproved one (which gives counter-example) - Sim_SolveTargetsUsingSat( p, p->nSimWords/p->nSuppWords ); - // compute additional functional support - Sim_UtilAssignFromFifo( p ); - nSolved = Sim_ComputeSuppRound( p, 1 ); - -if ( fVerbose ) - printf( "Targets = %5d. Solved = %5d. Fifo = %5d. SAT runs = %3d.\n", - Vec_VecSizeSize(p->vSuppTargs), nSolved, Vec_PtrSize(p->vFifo), p->nSatRuns ); - } - -exit: -p->timeTotal = clock() - clk; - vResult = p->vSuppFun; - // p->vSuppFun = NULL; - Sim_ManStop( p ); - return vResult; -} - -/**Function************************************************************* - - Synopsis [Computes functional support using one round of simulation.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_ComputeSuppRound( Sim_Man_t * p, bool fUseTargets ) -{ - Vec_Int_t * vTargets; - int i, Counter = 0; - int clk; - // perform one round of random simulation -clk = clock(); - Sim_UtilSimulate( p, 0 ); -p->timeSim += clock() - clk; - // iterate through the CIs and detect COs that depend on them - for ( i = p->iInput; i < p->nInputs; i++ ) - { - vTargets = p->vSuppTargs->pArray[i]; - if ( fUseTargets && vTargets->nSize == 0 ) - continue; - Counter += Sim_ComputeSuppRoundNode( p, i, fUseTargets ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Computes functional support for one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_ComputeSuppRoundNode( Sim_Man_t * p, int iNumCi, bool fUseTargets ) -{ - int fVerbose = 0; - Sim_Pat_t * pPat; - Vec_Int_t * vTargets; - Vec_Vec_t * vNodesByLevel; - Abc_Obj_t * pNodeCi, * pNode; - int i, k, v, Output, LuckyPat, fType0, fType1; - int Counter = 0; - int fFirst = 1; - int clk; - // collect nodes by level in the TFO of the CI - // this proceduredoes not collect the CIs and COs - // but it increments TravId of the collected nodes and CIs/COs -clk = clock(); - pNodeCi = Abc_NtkCi( p->pNtk, iNumCi ); - vNodesByLevel = Abc_DfsLevelized( pNodeCi, 0 ); -p->timeTrav += clock() - clk; - // complement the simulation info of the selected CI - Sim_UtilInfoFlip( p, pNodeCi ); - // simulate the levelized structure of nodes - Vec_VecForEachEntry( vNodesByLevel, pNode, i, k ) - { - fType0 = Abc_NodeIsTravIdCurrent( Abc_ObjFanin0(pNode) ); - fType1 = Abc_NodeIsTravIdCurrent( Abc_ObjFanin1(pNode) ); -clk = clock(); - Sim_UtilSimulateNode( p, pNode, 1, fType0, fType1 ); -p->timeSim += clock() - clk; - } - // set the simulation info of the affected COs - if ( fUseTargets ) - { - vTargets = p->vSuppTargs->pArray[iNumCi]; - for ( i = vTargets->nSize - 1; i >= 0; i-- ) - { - // get the target output - Output = vTargets->pArray[i]; - // get the target node - pNode = Abc_ObjFanin0( Abc_NtkCo(p->pNtk, Output) ); - // the output should be in the cone - assert( Abc_NodeIsTravIdCurrent(pNode) ); - - // skip if the simulation info is equal - if ( Sim_UtilInfoCompare( p, pNode ) ) - continue; - - // otherwise, we solved a new target - Vec_IntRemove( vTargets, Output ); -if ( fVerbose ) - printf( "(%d,%d) ", iNumCi, Output ); - Counter++; - // make sure this variable is not yet detected - assert( !Sim_SuppFunHasVar(p->vSuppFun, Output, iNumCi) ); - // set this variable - Sim_SuppFunSetVar( p->vSuppFun, Output, iNumCi ); - - // detect the differences in the simulation info - Sim_UtilInfoDetectDiffs( p->vSim0->pArray[pNode->Id], p->vSim1->pArray[pNode->Id], p->nSimWords, p->vDiffs ); - // create new patterns - if ( !fFirst && p->vFifo->nSize > 1000 ) - continue; - - Vec_IntForEachEntry( p->vDiffs, LuckyPat, k ) - { - // set the new pattern - pPat = Sim_ManPatAlloc( p ); - pPat->Input = iNumCi; - pPat->Output = Output; - Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) - if ( Sim_SimInfoHasVar( p->vSim0, pNodeCi, LuckyPat ) ) - Sim_SetBit( pPat->pData, v ); - Vec_PtrPush( p->vFifo, pPat ); - - fFirst = 0; - break; - } - } -if ( fVerbose && Counter ) -printf( "\n" ); - } - else - { - Abc_NtkForEachCo( p->pNtk, pNode, Output ) - { - if ( !Abc_NodeIsTravIdCurrent( pNode ) ) - continue; - if ( !Sim_UtilInfoCompare( p, Abc_ObjFanin0(pNode) ) ) - { - if ( !Sim_SuppFunHasVar(p->vSuppFun, Output, iNumCi) ) - { - Counter++; - Sim_SuppFunSetVar( p->vSuppFun, Output, iNumCi ); - } - } - } - } - Vec_VecFree( vNodesByLevel ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Sets the simulation targets.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_ComputeSuppSetTargets( Sim_Man_t * p ) -{ - Abc_Obj_t * pNode; - unsigned * pSuppStr, * pSuppFun; - int i, k, Num; - Abc_NtkForEachCo( p->pNtk, pNode, i ) - { - pSuppStr = p->vSuppStr->pArray[pNode->Id]; - pSuppFun = p->vSuppFun->pArray[i]; - // find vars in the structural support that are not in the functional support - Sim_UtilInfoDetectNews( pSuppFun, pSuppStr, p->nSuppWords, p->vDiffs ); - Vec_IntForEachEntry( p->vDiffs, Num, k ) - Vec_VecPush( p->vSuppTargs, Num, (void *)i ); - } -} - -/**Function************************************************************* - - Synopsis [Assigns random simulation info to the PIs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilAssignRandom( Sim_Man_t * p ) -{ - Abc_Obj_t * pNode; - unsigned * pSimInfo; - int i, k; - // assign the random/systematic simulation info to the PIs - Abc_NtkForEachCi( p->pNtk, pNode, i ) - { - pSimInfo = p->vSim0->pArray[pNode->Id]; - for ( k = 0; k < p->nSimWords; k++ ) - pSimInfo[k] = SIM_RANDOM_UNSIGNED; - } -} - -/**Function************************************************************* - - Synopsis [Sets the new patterns from fifo.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilAssignFromFifo( Sim_Man_t * p ) -{ - int fUseOneWord = 0; - Abc_Obj_t * pNode; - Sim_Pat_t * pPat; - unsigned * pSimInfo; - int nWordsNew, iWord, iWordLim, i, w; - int iBeg, iEnd; - int Counter = 0; - // go through the patterns and fill in the dist-1 minterms for each - for ( iWord = 0; p->vFifo->nSize > 0; iWord = iWordLim ) - { - ++Counter; - // get the pattern - pPat = Vec_PtrPop( p->vFifo ); - if ( fUseOneWord ) - { - // get the first word of the next series - iWordLim = iWord + 1; - // set the pattern for all PIs from iBit to iWord + p->nInputs - iBeg = p->iInput; - iEnd = ABC_MIN( iBeg + 32, p->nInputs ); -// for ( i = iBeg; i < iEnd; i++ ) - Abc_NtkForEachCi( p->pNtk, pNode, i ) - { - pNode = Abc_NtkCi(p->pNtk,i); - pSimInfo = p->vSim0->pArray[pNode->Id]; - if ( Sim_HasBit(pPat->pData, i) ) - pSimInfo[iWord] = SIM_MASK_FULL; - else - pSimInfo[iWord] = 0; - // flip one bit - if ( i >= iBeg && i < iEnd ) - Sim_XorBit( pSimInfo + iWord, i-iBeg ); - } - } - else - { - // get the number of words for the remaining inputs - nWordsNew = p->nSuppWords; -// nWordsNew = SIM_NUM_WORDS( p->nInputs - p->iInput ); - // get the first word of the next series - iWordLim = (iWord + nWordsNew < p->nSimWords)? iWord + nWordsNew : p->nSimWords; - // set the pattern for all CIs from iWord to iWord + nWordsNew - Abc_NtkForEachCi( p->pNtk, pNode, i ) - { - pSimInfo = p->vSim0->pArray[pNode->Id]; - if ( Sim_HasBit(pPat->pData, i) ) - { - for ( w = iWord; w < iWordLim; w++ ) - pSimInfo[w] = SIM_MASK_FULL; - } - else - { - for ( w = iWord; w < iWordLim; w++ ) - pSimInfo[w] = 0; - } - Sim_XorBit( pSimInfo + iWord, i ); - // flip one bit -// if ( i >= p->iInput ) -// Sim_XorBit( pSimInfo + iWord, i-p->iInput ); - } - } - Sim_ManPatFree( p, pPat ); - // stop if we ran out of room for patterns - if ( iWordLim == p->nSimWords ) - break; -// if ( Counter == 1 ) -// break; - } -} - -/**Function************************************************************* - - Synopsis [Get the given number of counter-examples using SAT.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SolveTargetsUsingSat( Sim_Man_t * p, int Limit ) -{ - Fraig_Params_t Params; - Fraig_Man_t * pMan; - Abc_Obj_t * pNodeCi; - Abc_Ntk_t * pMiter; - Sim_Pat_t * pPat; - void * pEntry; - int * pModel; - int RetValue, Output, Input, k, v; - int Counter = 0; - int clk; - - p->nSatRuns = 0; - // put targets into one array - Vec_VecForEachEntryReverse( p->vSuppTargs, pEntry, Input, k ) - { - p->nSatRuns++; - Output = (int)pEntry; - - // set up the miter for the two cofactors of this output w.r.t. this input - pMiter = Abc_NtkMiterForCofactors( p->pNtk, Output, Input, -1 ); - - // 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 ); -p->timeFraig += clock() - clk; -clk = clock(); - Fraig_ManProveMiter( pMan ); -p->timeSat += clock() - clk; - - // analyze the result - RetValue = Fraig_ManCheckMiter( pMan ); - assert( RetValue >= 0 ); - if ( RetValue == 1 ) // unsat - { - p->nSatRunsUnsat++; - pModel = NULL; - Vec_PtrRemove( p->vSuppTargs->pArray[Input], pEntry ); - } - else // sat - { - p->nSatRunsSat++; - pModel = Fraig_ManReadModel( pMan ); - assert( pModel != NULL ); - assert( Sim_SolveSuppModelVerify( p->pNtk, pModel, Input, Output ) ); - -//printf( "Solved by SAT (%d,%d).\n", Input, Output ); - // set the new pattern - pPat = Sim_ManPatAlloc( p ); - pPat->Input = Input; - pPat->Output = Output; - Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) - if ( pModel[v] ) - Sim_SetBit( pPat->pData, v ); - Vec_PtrPush( p->vFifo, pPat ); -/* - // set the new pattern - pPat = Sim_ManPatAlloc( p ); - pPat->Input = Input; - pPat->Output = Output; - Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) - if ( pModel[v] ) - Sim_SetBit( pPat->pData, v ); - Sim_XorBit( pPat->pData, Input ); // add this bit in the opposite polarity - Vec_PtrPush( p->vFifo, pPat ); -*/ - Counter++; - } - // delete the fraig manager - Fraig_ManFree( pMan ); - // delete the miter - Abc_NtkDelete( pMiter ); - - // makr the input, which we are processing - p->iInput = Input; - - // stop when we found enough patterns -// if ( Counter == Limit ) - if ( Counter == 1 ) - return; - } -} - - -/**Function************************************************************* - - Synopsis [Saves the counter example.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_NtkSimTwoPats_rec( Abc_Obj_t * pNode ) -{ - int Value0, Value1; - if ( Abc_NodeIsTravIdCurrent( pNode ) ) - return (int)pNode->pCopy; - Abc_NodeSetTravIdCurrent( pNode ); - Value0 = Sim_NtkSimTwoPats_rec( Abc_ObjFanin0(pNode) ); - Value1 = Sim_NtkSimTwoPats_rec( Abc_ObjFanin1(pNode) ); - if ( Abc_ObjFaninC0(pNode) ) - Value0 = ~Value0; - if ( Abc_ObjFaninC1(pNode) ) - Value1 = ~Value1; - pNode->pCopy = (Abc_Obj_t *)(Value0 & Value1); - return Value0 & Value1; -} - -/**Function************************************************************* - - Synopsis [Verifies that pModel proves the presence of Input in the support of Output.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_SolveSuppModelVerify( Abc_Ntk_t * pNtk, int * pModel, int Input, int Output ) -{ - Abc_Obj_t * pNode; - int RetValue, i; - // set the PI values - Abc_NtkIncrementTravId( pNtk ); - Abc_NtkForEachCi( pNtk, pNode, i ) - { - Abc_NodeSetTravIdCurrent( pNode ); - if ( pNode == Abc_NtkCi(pNtk,Input) ) - pNode->pCopy = (Abc_Obj_t *)1; - else if ( pModel[i] == 1 ) - pNode->pCopy = (Abc_Obj_t *)3; - else - pNode->pCopy = NULL; - } - // perform the traversal - RetValue = 3 & Sim_NtkSimTwoPats_rec( Abc_ObjFanin0( Abc_NtkCo(pNtk,Output) ) ); -// assert( RetValue == 1 || RetValue == 2 ); - return RetValue == 1 || RetValue == 2; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/sim/simSwitch.c b/src/opt/sim/simSwitch.c deleted file mode 100644 index 218d4d59..00000000 --- a/src/opt/sim/simSwitch.c +++ /dev/null @@ -1,107 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSwitch.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Computes switching activity of nodes in the ABC network.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simSwitch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static void Sim_NodeSimulate( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ); -static float Sim_ComputeSwitching( unsigned * pSimInfo, int nSimWords ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes switching activity using simulation.] - - Description [Computes switching activity, which is understood as the - probability of switching under random simulation. Assigns the - random simulation information at the CI and propagates it through - the internal nodes of the AIG.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Int_t * Sim_NtkComputeSwitching( Abc_Ntk_t * pNtk, int nPatterns ) -{ - Vec_Int_t * vSwitching; - float * pSwitching; - Vec_Ptr_t * vNodes; - Vec_Ptr_t * vSimInfo; - Abc_Obj_t * pNode; - unsigned * pSimInfo; - int nSimWords, i; - - // allocate space for simulation info of all nodes - nSimWords = SIM_NUM_WORDS(nPatterns); - vSimInfo = Sim_UtilInfoAlloc( Abc_NtkObjNumMax(pNtk), nSimWords, 0 ); - // assign the random simulation to the CIs - vSwitching = Vec_IntStart( Abc_NtkObjNumMax(pNtk) ); - pSwitching = (float *)vSwitching->pArray; - Abc_NtkForEachCi( pNtk, pNode, i ) - { - pSimInfo = Vec_PtrEntry(vSimInfo, pNode->Id); - Sim_UtilSetRandom( pSimInfo, nSimWords ); - pSwitching[pNode->Id] = Sim_ComputeSwitching( pSimInfo, nSimWords ); - } - // simulate the internal nodes - vNodes = Abc_AigDfs( pNtk, 1, 0 ); - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - pSimInfo = Vec_PtrEntry(vSimInfo, pNode->Id); - Sim_UtilSimulateNodeOne( pNode, vSimInfo, nSimWords, 0 ); - pSwitching[pNode->Id] = Sim_ComputeSwitching( pSimInfo, nSimWords ); - } - Vec_PtrFree( vNodes ); - Sim_UtilInfoFree( vSimInfo ); - return vSwitching; -} - -/**Function************************************************************* - - Synopsis [Computes switching activity of one node.] - - Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -float Sim_ComputeSwitching( unsigned * pSimInfo, int nSimWords ) -{ - int nOnes, nTotal; - nTotal = 32 * nSimWords; - nOnes = Sim_UtilCountOnes( pSimInfo, nSimWords ); - return (float)2.0 * nOnes * (nTotal - nOnes) / nTotal / nTotal; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/sim/simSym.c b/src/opt/sim/simSym.c deleted file mode 100644 index 71de5b05..00000000 --- a/src/opt/sim/simSym.c +++ /dev/null @@ -1,142 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSym.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation to determine two-variable symmetries.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simSym.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes two variable symmetries.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_ComputeTwoVarSymms( Abc_Ntk_t * pNtk, int fVerbose ) -{ - Sym_Man_t * p; - Vec_Ptr_t * vResult; - int Result; - int i, clk, clkTotal = clock(); - - srand( 0xABC ); - - // start the simulation manager - p = Sym_ManStart( pNtk, fVerbose ); - p->nPairsTotal = p->nPairsRem = Sim_UtilCountAllPairs( p->vSuppFun, p->nSimWords, p->vPairsTotal ); - if ( fVerbose ) - printf( "Total = %8d. Sym = %8d. NonSym = %8d. Remaining = %8d.\n", - p->nPairsTotal, p->nPairsSymm, p->nPairsNonSymm, p->nPairsRem ); - - // detect symmetries using circuit structure -clk = clock(); - Sim_SymmsStructCompute( pNtk, p->vMatrSymms, p->vSuppFun ); -p->timeStruct = clock() - clk; - - Sim_UtilCountPairsAll( p ); - p->nPairsSymmStr = p->nPairsSymm; - if ( fVerbose ) - printf( "Total = %8d. Sym = %8d. NonSym = %8d. Remaining = %8d.\n", - p->nPairsTotal, p->nPairsSymm, p->nPairsNonSymm, p->nPairsRem ); - - // detect symmetries using simulation - for ( i = 1; i <= 1000; i++ ) - { - // simulate this pattern - Sim_UtilSetRandom( p->uPatRand, p->nSimWords ); - Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms ); - if ( i % 50 != 0 ) - continue; - // check disjointness - assert( Sim_UtilMatrsAreDisjoint( p ) ); - // count the number of pairs - Sim_UtilCountPairsAll( p ); - if ( i % 500 != 0 ) - continue; - if ( fVerbose ) - printf( "Total = %8d. Sym = %8d. NonSym = %8d. Remaining = %8d.\n", - p->nPairsTotal, p->nPairsSymm, p->nPairsNonSymm, p->nPairsRem ); - } - - // detect symmetries using SAT - for ( i = 1; Sim_SymmsGetPatternUsingSat( p, p->uPatRand ); i++ ) - { - // simulate this pattern in four polarities - Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms ); - Sim_XorBit( p->uPatRand, p->iVar1 ); - Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms ); - Sim_XorBit( p->uPatRand, p->iVar2 ); - Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms ); - Sim_XorBit( p->uPatRand, p->iVar1 ); - Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms ); - Sim_XorBit( p->uPatRand, p->iVar2 ); -/* - // try the previuos pair - Sim_XorBit( p->uPatRand, p->iVar1Old ); - Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms ); - Sim_XorBit( p->uPatRand, p->iVar2Old ); - Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms ); - Sim_XorBit( p->uPatRand, p->iVar1Old ); - Sim_SymmsSimulate( p, p->uPatRand, p->vMatrNonSymms ); -*/ - if ( i % 10 != 0 ) - continue; - // check disjointness - assert( Sim_UtilMatrsAreDisjoint( p ) ); - // count the number of pairs - Sim_UtilCountPairsAll( p ); - if ( i % 50 != 0 ) - continue; - if ( fVerbose ) - printf( "Total = %8d. Sym = %8d. NonSym = %8d. Remaining = %8d.\n", - p->nPairsTotal, p->nPairsSymm, p->nPairsNonSymm, p->nPairsRem ); - } - - // count the number of pairs - Sim_UtilCountPairsAll( p ); - 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; -p->timeTotal = clock() - clkTotal; - // p->vMatrSymms = NULL; - Sym_ManStop( p ); - return Result; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/sim/simSymSat.c b/src/opt/sim/simSymSat.c deleted file mode 100644 index 7690a891..00000000 --- a/src/opt/sim/simSymSat.c +++ /dev/null @@ -1,199 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSymSat.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Satisfiability to determine two variable symmetries.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simSymSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" -#include "fraig.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -static int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * pPattern ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Tries to prove the remaining pairs using SAT.] - - Description [Continues to prove as long as it encounters symmetric pairs. - Returns 1 if a non-symmetric pair is found (which gives a counter-example). - Returns 0 if it finishes considering all pairs for all outputs.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_SymmsGetPatternUsingSat( Sym_Man_t * p, unsigned * pPattern ) -{ - Vec_Int_t * vSupport; - Extra_BitMat_t * pMatSym, * pMatNonSym; - int Index1, Index2, Index3, IndexU, IndexV; - int v, u, i, k, b, out; - - // iterate through outputs - for ( out = p->iOutput; out < p->nOutputs; out++ ) - { - pMatSym = Vec_PtrEntry( p->vMatrSymms, out ); - pMatNonSym = Vec_PtrEntry( p->vMatrNonSymms, out ); - - // go through the remaining variable pairs - vSupport = Vec_VecEntry( p->vSupports, out ); - Vec_IntForEachEntry( vSupport, v, Index1 ) - Vec_IntForEachEntryStart( vSupport, u, Index2, Index1+1 ) - { - if ( Extra_BitMatrixLookup1( pMatSym, v, u ) || Extra_BitMatrixLookup1( pMatNonSym, v, u ) ) - continue; - p->nSatRuns++; - - // collect the support variables that are symmetric with u and v - Vec_IntClear( p->vVarsU ); - Vec_IntClear( p->vVarsV ); - Vec_IntForEachEntry( vSupport, b, Index3 ) - { - if ( Extra_BitMatrixLookup1( pMatSym, u, b ) ) - Vec_IntPush( p->vVarsU, b ); - if ( Extra_BitMatrixLookup1( pMatSym, v, b ) ) - Vec_IntPush( p->vVarsV, b ); - } - - if ( Sim_SymmsSatProveOne( p, out, v, u, pPattern ) ) - { // update the symmetric variable info - p->nSatRunsUnsat++; - Vec_IntForEachEntry( p->vVarsU, i, IndexU ) - Vec_IntForEachEntry( p->vVarsV, k, IndexV ) - { - Extra_BitMatrixInsert1( pMatSym, i, k ); // Theorem 1 - Extra_BitMatrixInsert2( pMatSym, i, k ); // Theorem 1 - Extra_BitMatrixOrTwo( pMatNonSym, i, k ); // Theorem 2 - } - } - else - { // update the assymmetric variable info - p->nSatRunsSat++; - Vec_IntForEachEntry( p->vVarsU, i, IndexU ) - Vec_IntForEachEntry( p->vVarsV, k, IndexV ) - { - Extra_BitMatrixInsert1( pMatNonSym, i, k ); // Theorem 3 - Extra_BitMatrixInsert2( pMatNonSym, i, k ); // Theorem 3 - } - - // remember the out - p->iOutput = out; - p->iVar1Old = p->iVar1; - p->iVar2Old = p->iVar2; - p->iVar1 = v; - p->iVar2 = u; - return 1; - - } - } - // make sure that the symmetry matrix contains only cliques - assert( Extra_BitMatrixIsClique( pMatSym ) ); - } - - // mark that we finished all outputs - p->iOutput = p->nOutputs; - return 0; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the variables are symmetric; 0 otherwise.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * pPattern ) -{ - Fraig_Params_t Params; - Fraig_Man_t * pMan; - Abc_Ntk_t * pMiter; - int RetValue, i, clk; - int * pModel; - - // get the miter for this problem - pMiter = Abc_NtkMiterForCofactors( p->pNtk, Out, Var1, Var2 ); - // transform the miter into a fraig - Fraig_ParamsSetDefault( &Params ); - Params.fInternal = 1; - Params.nPatsRand = 512; - Params.nPatsDyna = 512; - Params.nSeconds = ABC_INFINITY; - -clk = clock(); - pMan = Abc_NtkToFraig( pMiter, &Params, 0, 0 ); -p->timeFraig += clock() - clk; -clk = clock(); - Fraig_ManProveMiter( pMan ); -p->timeSat += clock() - clk; - - // analyze the result - RetValue = Fraig_ManCheckMiter( pMan ); -// assert( RetValue >= 0 ); - // save the pattern - if ( RetValue == 0 ) - { - // get the pattern - pModel = Fraig_ManReadModel( pMan ); - assert( pModel != NULL ); -//printf( "Disproved by SAT: out = %d pair = (%d, %d)\n", Out, Var1, Var2 ); - // transfer the model into the pattern - for ( i = 0; i < p->nSimWords; i++ ) - pPattern[i] = 0; - for ( i = 0; i < p->nInputs; i++ ) - if ( pModel[i] ) - Sim_SetBit( pPattern, i ); - // make sure these variables have the same value (1) - Sim_SetBit( pPattern, Var1 ); - Sim_SetBit( pPattern, Var2 ); - } - else if ( RetValue == -1 ) - { - // this should never happen; if it happens, such is life - // we are conservative and assume that there is no symmetry -//printf( "STRANGE THING: out = %d %s pair = (%d %s, %d %s)\n", -// Out, Abc_ObjName(Abc_NtkCo(p->pNtk,Out)), -// Var1, Abc_ObjName(Abc_NtkCi(p->pNtk,Var1)), -// Var2, Abc_ObjName(Abc_NtkCi(p->pNtk,Var2)) ); - memset( pPattern, 0, sizeof(unsigned) * p->nSimWords ); - RetValue = 0; - } - // delete the fraig manager - Fraig_ManFree( pMan ); - // delete the miter - Abc_NtkDelete( pMiter ); - return RetValue; -} - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/sim/simSymSim.c b/src/opt/sim/simSymSim.c deleted file mode 100644 index 2282825b..00000000 --- a/src/opt/sim/simSymSim.c +++ /dev/null @@ -1,173 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSymSim.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Simulation to determine two-variable symmetries.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simSymSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -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************************************************************* - - Synopsis [Detects non-symmetric pairs using one pattern.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsSimulate( Sym_Man_t * p, unsigned * pPat, Vec_Ptr_t * vMatrsNonSym ) -{ - Abc_Obj_t * pNode; - int i, nPairsTotal, nPairsSym, nPairsNonSym; - int clk; - - // create the simulation matrix - Sim_SymmsCreateSquare( p, pPat ); - // simulate each node in the DFS order -clk = clock(); - Vec_PtrForEachEntry( p->vNodes, pNode, i ) - { -// if ( Abc_NodeIsConst(pNode) ) -// continue; - Sim_UtilSimulateNodeOne( pNode, p->vSim, p->nSimWords, 0 ); - } -p->timeSim += clock() - clk; - // collect info into the CO matrices -clk = clock(); - Abc_NtkForEachCo( p->pNtk, pNode, i ) - { - pNode = Abc_ObjFanin0(pNode); -// if ( Abc_ObjIsCi(pNode) || Abc_AigNodeIsConst(pNode) ) -// continue; - nPairsTotal = Vec_IntEntry(p->vPairsTotal, i); - nPairsSym = Vec_IntEntry(p->vPairsSym, i); - nPairsNonSym = Vec_IntEntry(p->vPairsNonSym,i); - assert( nPairsTotal >= nPairsSym + nPairsNonSym ); - if ( nPairsTotal == nPairsSym + nPairsNonSym ) - continue; - Sim_SymmsDeriveInfo( p, pPat, pNode, vMatrsNonSym, i ); - } -p->timeMatr += clock() - clk; -} - -/**Function************************************************************* - - Synopsis [Creates the square matrix of simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsCreateSquare( Sym_Man_t * p, unsigned * pPat ) -{ - unsigned * pSimInfo; - Abc_Obj_t * pNode; - int i, w; - // for each PI var copy the pattern - Abc_NtkForEachCi( p->pNtk, pNode, i ) - { - pSimInfo = Vec_PtrEntry( p->vSim, pNode->Id ); - if ( Sim_HasBit(pPat, i) ) - { - for ( w = 0; w < p->nSimWords; w++ ) - pSimInfo[w] = SIM_MASK_FULL; - } - else - { - for ( w = 0; w < p->nSimWords; w++ ) - pSimInfo[w] = 0; - } - // flip one bit - Sim_XorBit( pSimInfo, i ); - } -} - -/**Function************************************************************* - - Synopsis [Transfers the info to the POs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsDeriveInfo( Sym_Man_t * p, unsigned * pPat, Abc_Obj_t * pNode, Vec_Ptr_t * vMatrsNonSym, int Output ) -{ - Extra_BitMat_t * pMat; - Vec_Int_t * vSupport; - unsigned * pSupport; - unsigned * pSimInfo; - int i, w, Index; - // get the matrix, the support, and the simulation info - pMat = Vec_PtrEntry( vMatrsNonSym, Output ); - vSupport = Vec_VecEntry( p->vSupports, Output ); - pSupport = Vec_PtrEntry( p->vSuppFun, Output ); - pSimInfo = Vec_PtrEntry( p->vSim, pNode->Id ); - // generate vectors A1 and A2 - for ( w = 0; w < p->nSimWords; w++ ) - { - p->uPatCol[w] = pSupport[w] & pPat[w] & pSimInfo[w]; - p->uPatRow[w] = pSupport[w] & pPat[w] & ~pSimInfo[w]; - } - // add two dimensions - Vec_IntForEachEntry( vSupport, i, Index ) - if ( Sim_HasBit( p->uPatCol, i ) ) - Extra_BitMatrixOr( pMat, i, p->uPatRow ); - // add two dimensions - Vec_IntForEachEntry( vSupport, i, Index ) - if ( Sim_HasBit( p->uPatRow, i ) ) - Extra_BitMatrixOr( pMat, i, p->uPatCol ); - // generate vectors B1 and B2 - for ( w = 0; w < p->nSimWords; w++ ) - { - p->uPatCol[w] = pSupport[w] & ~pPat[w] & pSimInfo[w]; - p->uPatRow[w] = pSupport[w] & ~pPat[w] & ~pSimInfo[w]; - } - // add two dimensions - Vec_IntForEachEntry( vSupport, i, Index ) - if ( Sim_HasBit( p->uPatCol, i ) ) - Extra_BitMatrixOr( pMat, i, p->uPatRow ); - // add two dimensions - Vec_IntForEachEntry( vSupport, i, Index ) - if ( Sim_HasBit( p->uPatRow, i ) ) - Extra_BitMatrixOr( pMat, i, p->uPatCol ); -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/sim/simSymStr.c b/src/opt/sim/simSymStr.c deleted file mode 100644 index d52c4328..00000000 --- a/src/opt/sim/simSymStr.c +++ /dev/null @@ -1,488 +0,0 @@ -/**CFile**************************************************************** - - FileName [simSymStr.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Structural detection of symmetries.] - - Author [Alan Mishchenko] - - Affiliation [UC Berkeley] - - Date [Ver. 1.0. Started - June 20, 2005.] - - Revision [$Id: simSymStr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "abc.h" -#include "sim.h" - -//////////////////////////////////////////////////////////////////////// -/// DECLARATIONS /// -//////////////////////////////////////////////////////////////////////// - -#define SIM_READ_SYMMS(pNode) ((Vec_Int_t *)pNode->pCopy) -#define SIM_SET_SYMMS(pNode,vVect) (pNode->pCopy = (Abc_Obj_t *)(vVect)) - -static void Sim_SymmsStructComputeOne( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int * pMap ); -static void Sim_SymmsBalanceCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ); -static void Sim_SymmsPartitionNodes( Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesPis0, Vec_Ptr_t * vNodesPis1, Vec_Ptr_t * vNodesOther ); -static void Sim_SymmsAppendFromGroup( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodesPi, Vec_Ptr_t * vNodesOther, Vec_Int_t * vSymms, int * pMap ); -static void Sim_SymmsAppendFromNode( Abc_Ntk_t * pNtk, Vec_Int_t * vSymms0, Vec_Ptr_t * vNodesOther, Vec_Ptr_t * vNodesPi0, Vec_Ptr_t * vNodesPi1, Vec_Int_t * vSymms, int * pMap ); -static int Sim_SymmsIsCompatibleWithNodes( Abc_Ntk_t * pNtk, unsigned uSymm, Vec_Ptr_t * vNodesOther, int * pMap ); -static int Sim_SymmsIsCompatibleWithGroup( unsigned uSymm, Vec_Ptr_t * vNodesPi, int * pMap ); -static void Sim_SymmsPrint( Vec_Int_t * vSymms ); -static void Sim_SymmsTrans( Vec_Int_t * vSymms ); -static void Sim_SymmsTransferToMatrix( Extra_BitMat_t * pMatSymm, Vec_Int_t * vSymms, unsigned * pSupport ); -static int * Sim_SymmsCreateMap( Abc_Ntk_t * pNtk ); - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Computes symmetries for a single output function.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsStructCompute( Abc_Ntk_t * pNtk, Vec_Ptr_t * vMatrs, Vec_Ptr_t * vSuppFun ) -{ - Vec_Ptr_t * vNodes; - Abc_Obj_t * pTemp; - int * pMap, i; - - assert( Abc_NtkCiNum(pNtk) + 10 < (1<<16) ); - - // get the structural support - pNtk->vSupps = Sim_ComputeStrSupp( pNtk ); - // set elementary info for the CIs - Abc_NtkForEachCi( pNtk, pTemp, i ) - SIM_SET_SYMMS( pTemp, Vec_IntAlloc(0) ); - // create the map of CI ids into their numbers - pMap = Sim_SymmsCreateMap( pNtk ); - // collect the nodes in the TFI cone of this output - vNodes = Abc_NtkDfs( pNtk, 0 ); - Vec_PtrForEachEntry( vNodes, pTemp, i ) - { -// 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) ) - continue; - Sim_SymmsTransferToMatrix( Vec_PtrEntry(vMatrs, i), SIM_READ_SYMMS(pTemp), Vec_PtrEntry(vSuppFun, i) ); - } - // clean the intermediate results - Sim_UtilInfoFree( pNtk->vSupps ); - pNtk->vSupps = NULL; - Abc_NtkForEachCi( pNtk, pTemp, i ) - Vec_IntFree( SIM_READ_SYMMS(pTemp) ); - Vec_PtrForEachEntry( vNodes, pTemp, i ) -// if ( !Abc_NodeIsConst(pTemp) ) - Vec_IntFree( SIM_READ_SYMMS(pTemp) ); - Vec_PtrFree( vNodes ); - free( pMap ); -} - -/**Function************************************************************* - - Synopsis [Recursively computes symmetries. ] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsStructComputeOne( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, int * pMap ) -{ - Vec_Ptr_t * vNodes, * vNodesPi0, * vNodesPi1, * vNodesOther; - Vec_Int_t * vSymms; - Abc_Obj_t * pTemp; - int i; - - // allocate the temporary arrays - vNodes = Vec_PtrAlloc( 10 ); - vNodesPi0 = Vec_PtrAlloc( 10 ); - vNodesPi1 = Vec_PtrAlloc( 10 ); - vNodesOther = Vec_PtrAlloc( 10 ); - - // collect the fanins of the implication supergate - Sim_SymmsBalanceCollect_rec( pNode, vNodes ); - - // sort the nodes in the implication supergate - Sim_SymmsPartitionNodes( vNodes, vNodesPi0, vNodesPi1, vNodesOther ); - - // start the resulting set - vSymms = Vec_IntAlloc( 10 ); - // generate symmetries from the groups - Sim_SymmsAppendFromGroup( pNtk, vNodesPi0, vNodesOther, vSymms, pMap ); - Sim_SymmsAppendFromGroup( pNtk, vNodesPi1, vNodesOther, vSymms, pMap ); - // add symmetries from other inputs - for ( i = 0; i < vNodesOther->nSize; i++ ) - { - pTemp = Abc_ObjRegular(vNodesOther->pArray[i]); - Sim_SymmsAppendFromNode( pNtk, SIM_READ_SYMMS(pTemp), vNodesOther, vNodesPi0, vNodesPi1, vSymms, pMap ); - } - Vec_PtrFree( vNodes ); - Vec_PtrFree( vNodesPi0 ); - Vec_PtrFree( vNodesPi1 ); - Vec_PtrFree( vNodesOther ); - - // set the symmetry at the node - SIM_SET_SYMMS( pNode, vSymms ); -} - - -/**Function************************************************************* - - Synopsis [Returns the array of nodes to be combined into one multi-input AND-gate.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsBalanceCollect_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes ) -{ - // if the new node is complemented, another gate begins - if ( Abc_ObjIsComplement(pNode) ) - { - Vec_PtrPushUnique( vNodes, pNode ); - return; - } - // if pNew is the PI node, return - if ( Abc_ObjIsCi(pNode) ) - { - Vec_PtrPushUnique( vNodes, pNode ); - return; - } - // go through the branches - Sim_SymmsBalanceCollect_rec( Abc_ObjChild0(pNode), vNodes ); - Sim_SymmsBalanceCollect_rec( Abc_ObjChild1(pNode), vNodes ); -} - -/**Function************************************************************* - - Synopsis [Divides PI variables into groups.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsPartitionNodes( Vec_Ptr_t * vNodes, Vec_Ptr_t * vNodesPis0, - Vec_Ptr_t * vNodesPis1, Vec_Ptr_t * vNodesOther ) -{ - Abc_Obj_t * pNode; - int i; - Vec_PtrForEachEntry( vNodes, pNode, i ) - { - if ( !Abc_ObjIsCi(Abc_ObjRegular(pNode)) ) - Vec_PtrPush( vNodesOther, pNode ); - else if ( Abc_ObjIsComplement(pNode) ) - Vec_PtrPush( vNodesPis0, pNode ); - else - Vec_PtrPush( vNodesPis1, pNode ); - } -} - -/**Function************************************************************* - - Synopsis [Makes the product of two partitions.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsAppendFromGroup( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodesPi, Vec_Ptr_t * vNodesOther, Vec_Int_t * vSymms, int * pMap ) -{ - Abc_Obj_t * pNode1, * pNode2; - unsigned uSymm; - int i, k; - - if ( vNodesPi->nSize == 0 ) - return; - - // go through the pairs - for ( i = 0; i < vNodesPi->nSize; i++ ) - for ( k = i+1; k < vNodesPi->nSize; k++ ) - { - // get the two PI nodes - pNode1 = Abc_ObjRegular(vNodesPi->pArray[i]); - pNode2 = Abc_ObjRegular(vNodesPi->pArray[k]); - assert( pMap[pNode1->Id] != pMap[pNode2->Id] ); - assert( pMap[pNode1->Id] >= 0 ); - assert( pMap[pNode2->Id] >= 0 ); - // generate symmetry - if ( pMap[pNode1->Id] < pMap[pNode2->Id] ) - uSymm = ((pMap[pNode1->Id] << 16) | pMap[pNode2->Id]); - else - uSymm = ((pMap[pNode2->Id] << 16) | pMap[pNode1->Id]); - // check if symmetry belongs - if ( Sim_SymmsIsCompatibleWithNodes( pNtk, uSymm, vNodesOther, pMap ) ) - Vec_IntPushUnique( vSymms, (int)uSymm ); - } -} - -/**Function************************************************************* - - Synopsis [Add the filters symmetries from the nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsAppendFromNode( Abc_Ntk_t * pNtk, Vec_Int_t * vSymms0, Vec_Ptr_t * vNodesOther, - Vec_Ptr_t * vNodesPi0, Vec_Ptr_t * vNodesPi1, Vec_Int_t * vSymms, int * pMap ) -{ - unsigned uSymm; - int i; - - if ( vSymms0->nSize == 0 ) - return; - - // go through the pairs - for ( i = 0; i < vSymms0->nSize; i++ ) - { - uSymm = (unsigned)vSymms0->pArray[i]; - // check if symmetry belongs - if ( Sim_SymmsIsCompatibleWithNodes( pNtk, uSymm, vNodesOther, pMap ) && - Sim_SymmsIsCompatibleWithGroup( uSymm, vNodesPi0, pMap ) && - Sim_SymmsIsCompatibleWithGroup( uSymm, vNodesPi1, pMap ) ) - Vec_IntPushUnique( vSymms, (int)uSymm ); - } -} - -/**Function************************************************************* - - Synopsis [Returns 1 if symmetry is compatible with the group of nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_SymmsIsCompatibleWithNodes( Abc_Ntk_t * pNtk, unsigned uSymm, Vec_Ptr_t * vNodesOther, int * pMap ) -{ - Vec_Int_t * vSymmsNode; - Abc_Obj_t * pNode; - int i, s, Ind1, Ind2, fIsVar1, fIsVar2; - - if ( vNodesOther->nSize == 0 ) - return 1; - - // get the indices of the PI variables - Ind1 = (uSymm & 0xffff); - Ind2 = (uSymm >> 16); - - // go through the nodes - // if they do not belong to a support, it is okay - // if one belongs, the other does not belong, quit - // if they belong, but are not part of symmetry, quit - for ( i = 0; i < vNodesOther->nSize; i++ ) - { - pNode = Abc_ObjRegular(vNodesOther->pArray[i]); - fIsVar1 = Sim_SuppStrHasVar( pNtk->vSupps, pNode, Ind1 ); - fIsVar2 = Sim_SuppStrHasVar( pNtk->vSupps, pNode, Ind2 ); - - if ( !fIsVar1 && !fIsVar2 ) - continue; - if ( fIsVar1 ^ fIsVar2 ) - return 0; - // both belong - // check if there is a symmetry - vSymmsNode = SIM_READ_SYMMS( pNode ); - for ( s = 0; s < vSymmsNode->nSize; s++ ) - if ( uSymm == (unsigned)vSymmsNode->pArray[s] ) - break; - if ( s == vSymmsNode->nSize ) - return 0; - } - return 1; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if symmetry is compatible with the group of PIs.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_SymmsIsCompatibleWithGroup( unsigned uSymm, Vec_Ptr_t * vNodesPi, int * pMap ) -{ - Abc_Obj_t * pNode; - int i, Ind1, Ind2, fHasVar1, fHasVar2; - - if ( vNodesPi->nSize == 0 ) - return 1; - - // get the indices of the PI variables - Ind1 = (uSymm & 0xffff); - Ind2 = (uSymm >> 16); - - // go through the PI nodes - fHasVar1 = fHasVar2 = 0; - for ( i = 0; i < vNodesPi->nSize; i++ ) - { - pNode = Abc_ObjRegular(vNodesPi->pArray[i]); - if ( pMap[pNode->Id] == Ind1 ) - fHasVar1 = 1; - else if ( pMap[pNode->Id] == Ind2 ) - fHasVar2 = 1; - } - return fHasVar1 == fHasVar2; -} - - - -/**Function************************************************************* - - Synopsis [Improvements due to transitivity.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsTrans( Vec_Int_t * vSymms ) -{ - unsigned uSymm, uSymma, uSymmr; - int i, Ind1, Ind2; - int k, Ind1a, Ind2a; - int j; - int nTrans = 0; - - for ( i = 0; i < vSymms->nSize; i++ ) - { - uSymm = (unsigned)vSymms->pArray[i]; - Ind1 = (uSymm & 0xffff); - Ind2 = (uSymm >> 16); - // find other symmetries that have Ind1 - for ( k = i+1; k < vSymms->nSize; k++ ) - { - uSymma = (unsigned)vSymms->pArray[k]; - if ( uSymma == uSymm ) - continue; - Ind1a = (uSymma & 0xffff); - Ind2a = (uSymma >> 16); - if ( Ind1a == Ind1 ) - { - // find the symmetry (Ind2,Ind2a) - if ( Ind2 < Ind2a ) - uSymmr = ((Ind2 << 16) | Ind2a); - else - uSymmr = ((Ind2a << 16) | Ind2); - for ( j = 0; j < vSymms->nSize; j++ ) - if ( uSymmr == (unsigned)vSymms->pArray[j] ) - break; - if ( j == vSymms->nSize ) - nTrans++; - } - } - - } - printf( "Trans = %d.\n", nTrans ); -} - - -/**Function************************************************************* - - Synopsis [Transfers from the vector to the matrix.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_SymmsTransferToMatrix( Extra_BitMat_t * pMatSymm, Vec_Int_t * vSymms, unsigned * pSupport ) -{ - int i, Ind1, Ind2, nInputs; - unsigned uSymm; - // add diagonal elements - nInputs = Extra_BitMatrixReadSize( pMatSymm ); - for ( i = 0; i < nInputs; i++ ) - Extra_BitMatrixInsert1( pMatSymm, i, i ); - // add non-diagonal elements - for ( i = 0; i < vSymms->nSize; i++ ) - { - 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) ) - continue; - Extra_BitMatrixInsert1( pMatSymm, Ind1, Ind2 ); - Extra_BitMatrixInsert2( pMatSymm, Ind1, Ind2 ); - } -} - -/**Function************************************************************* - - Synopsis [Mapping of indices into numbers.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int * Sim_SymmsCreateMap( Abc_Ntk_t * pNtk ) -{ - int * pMap; - Abc_Obj_t * pNode; - int i; - pMap = ALLOC( int, Abc_NtkObjNumMax(pNtk) ); - for ( i = 0; i < Abc_NtkObjNumMax(pNtk); i++ ) - pMap[i] = -1; - Abc_NtkForEachCi( pNtk, pNode, i ) - pMap[pNode->Id] = i; - return pMap; -} - - - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - diff --git a/src/opt/sim/simUtils.c b/src/opt/sim/simUtils.c deleted file mode 100644 index b0660001..00000000 --- a/src/opt/sim/simUtils.c +++ /dev/null @@ -1,711 +0,0 @@ -/**CFile**************************************************************** - - FileName [simUtils.c] - - SystemName [ABC: Logic synthesis and verification system.] - - PackageName [Network and node package.] - - Synopsis [Various simulation utilities.] - - 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 int bit_count[256] = { - 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 -}; - -//////////////////////////////////////////////////////////////////////// -/// FUNCTION DEFINITIONS /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - - Synopsis [Allocates simulation information for all nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Ptr_t * Sim_UtilInfoAlloc( int nSize, int nWords, bool fClean ) -{ - Vec_Ptr_t * vInfo; - int i; - assert( nSize > 0 && nWords > 0 ); - vInfo = Vec_PtrAlloc( nSize ); - vInfo->pArray[0] = ALLOC( unsigned, nSize * nWords ); - if ( fClean ) - memset( vInfo->pArray[0], 0, sizeof(unsigned) * nSize * nWords ); - for ( i = 1; i < nSize; i++ ) - vInfo->pArray[i] = ((unsigned *)vInfo->pArray[i-1]) + nWords; - vInfo->nSize = nSize; - return vInfo; -} - -/**Function************************************************************* - - Synopsis [Allocates simulation information for all nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilInfoFree( Vec_Ptr_t * p ) -{ - free( p->pArray[0] ); - Vec_PtrFree( p ); -} - -/**Function************************************************************* - - Synopsis [Adds the second supp-info the first.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilInfoAdd( unsigned * pInfo1, unsigned * pInfo2, int nWords ) -{ - int w; - for ( w = 0; w < nWords; w++ ) - pInfo1[w] |= pInfo2[w]; -} - -/**Function************************************************************* - - Synopsis [Returns the positions where pInfo2 is 1 while pInfo1 is 0.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilInfoDetectDiffs( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ) -{ - int w, b; - unsigned uMask; - vDiffs->nSize = 0; - for ( w = 0; w < nWords; w++ ) - if ( uMask = (pInfo2[w] ^ pInfo1[w]) ) - for ( b = 0; b < 32; b++ ) - if ( uMask & (1 << b) ) - Vec_IntPush( vDiffs, 32*w + b ); -} - -/**Function************************************************************* - - Synopsis [Returns the positions where pInfo2 is 1 while pInfo1 is 0.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilInfoDetectNews( unsigned * pInfo1, unsigned * pInfo2, int nWords, Vec_Int_t * vDiffs ) -{ - int w, b; - unsigned uMask; - vDiffs->nSize = 0; - for ( w = 0; w < nWords; w++ ) - if ( uMask = (pInfo2[w] & ~pInfo1[w]) ) - for ( b = 0; b < 32; b++ ) - if ( uMask & (1 << b) ) - Vec_IntPush( vDiffs, 32*w + b ); -} - -/**Function************************************************************* - - Synopsis [Flips the simulation info of the node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilInfoFlip( Sim_Man_t * p, Abc_Obj_t * pNode ) -{ - unsigned * pSimInfo1, * pSimInfo2; - int k; - pSimInfo1 = p->vSim0->pArray[pNode->Id]; - pSimInfo2 = p->vSim1->pArray[pNode->Id]; - for ( k = 0; k < p->nSimWords; k++ ) - pSimInfo2[k] = ~pSimInfo1[k]; -} - -/**Function************************************************************* - - Synopsis [Returns 1 if the simulation infos are equal.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -bool Sim_UtilInfoCompare( Sim_Man_t * p, Abc_Obj_t * pNode ) -{ - unsigned * pSimInfo1, * pSimInfo2; - int k; - pSimInfo1 = p->vSim0->pArray[pNode->Id]; - pSimInfo2 = p->vSim1->pArray[pNode->Id]; - for ( k = 0; k < p->nSimWords; k++ ) - if ( pSimInfo2[k] != pSimInfo1[k] ) - return 0; - return 1; -} - -/**Function************************************************************* - - Synopsis [Simulates the internal nodes.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilSimulate( Sim_Man_t * p, bool fType ) -{ - Abc_Obj_t * pNode; - int i; - // simulate the internal nodes - Abc_NtkForEachNode( p->pNtk, pNode, i ) - Sim_UtilSimulateNode( p, pNode, fType, fType, fType ); - // assign simulation info of the CO nodes - Abc_NtkForEachCo( p->pNtk, pNode, i ) - Sim_UtilSimulateNode( p, pNode, fType, fType, fType ); -} - -/**Function************************************************************* - - Synopsis [Simulates one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilSimulateNode( Sim_Man_t * p, Abc_Obj_t * pNode, bool fType, bool fType1, bool fType2 ) -{ - unsigned * pSimmNode, * pSimmNode1, * pSimmNode2; - int k, fComp1, fComp2; - // simulate the internal nodes - if ( Abc_ObjIsNode(pNode) ) - { - if ( fType ) - pSimmNode = p->vSim1->pArray[ pNode->Id ]; - else - pSimmNode = p->vSim0->pArray[ pNode->Id ]; - - if ( fType1 ) - pSimmNode1 = p->vSim1->pArray[ Abc_ObjFaninId0(pNode) ]; - else - pSimmNode1 = p->vSim0->pArray[ Abc_ObjFaninId0(pNode) ]; - - if ( fType2 ) - pSimmNode2 = p->vSim1->pArray[ Abc_ObjFaninId1(pNode) ]; - else - pSimmNode2 = p->vSim0->pArray[ Abc_ObjFaninId1(pNode) ]; - - fComp1 = Abc_ObjFaninC0(pNode); - fComp2 = Abc_ObjFaninC1(pNode); - if ( fComp1 && fComp2 ) - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = ~pSimmNode1[k] & ~pSimmNode2[k]; - else if ( fComp1 && !fComp2 ) - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = ~pSimmNode1[k] & pSimmNode2[k]; - else if ( !fComp1 && fComp2 ) - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = pSimmNode1[k] & ~pSimmNode2[k]; - else // if ( fComp1 && fComp2 ) - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = pSimmNode1[k] & pSimmNode2[k]; - } - else - { - assert( Abc_ObjFaninNum(pNode) == 1 ); - if ( fType ) - pSimmNode = p->vSim1->pArray[ pNode->Id ]; - else - pSimmNode = p->vSim0->pArray[ pNode->Id ]; - - if ( fType1 ) - pSimmNode1 = p->vSim1->pArray[ Abc_ObjFaninId0(pNode) ]; - else - pSimmNode1 = p->vSim0->pArray[ Abc_ObjFaninId0(pNode) ]; - - fComp1 = Abc_ObjFaninC0(pNode); - if ( fComp1 ) - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = ~pSimmNode1[k]; - else - for ( k = 0; k < p->nSimWords; k++ ) - pSimmNode[k] = pSimmNode1[k]; - } -} - -/**Function************************************************************* - - Synopsis [Simulates one node.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilSimulateNodeOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords, int nOffset ) -{ - unsigned * pSimmNode, * pSimmNode1, * pSimmNode2; - int k, fComp1, fComp2; - // simulate the internal nodes - assert( Abc_ObjIsNode(pNode) ); - 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 ) - for ( k = 0; k < nSimWords; k++ ) - pSimmNode[k] = ~pSimmNode1[k] & ~pSimmNode2[k]; - else if ( fComp1 && !fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pSimmNode[k] = ~pSimmNode1[k] & pSimmNode2[k]; - else if ( !fComp1 && fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pSimmNode[k] = pSimmNode1[k] & ~pSimmNode2[k]; - else // if ( fComp1 && fComp2 ) - for ( k = 0; k < nSimWords; k++ ) - pSimmNode[k] = pSimmNode1[k] & pSimmNode2[k]; -} - -/**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 [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_UtilCountSuppSizes( Sim_Man_t * p, int fStruct ) -{ - Abc_Obj_t * pNode, * pNodeCi; - int i, v, Counter; - Counter = 0; - if ( fStruct ) - { - Abc_NtkForEachCo( p->pNtk, pNode, i ) - Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) - Counter += Sim_SuppStrHasVar( p->vSuppStr, pNode, v ); - } - else - { - Abc_NtkForEachCo( p->pNtk, pNode, i ) - Abc_NtkForEachCi( p->pNtk, pNodeCi, v ) - Counter += Sim_SuppFunHasVar( p->vSuppFun, i, v ); - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Counts the number of 1's in the bitstring.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_UtilCountOnes( unsigned * pSimInfo, int nSimWords ) -{ - unsigned char * pBytes; - int nOnes, nBytes, i; - pBytes = (unsigned char *)pSimInfo; - nBytes = 4 * nSimWords; - nOnes = 0; - for ( i = 0; i < nBytes; i++ ) - nOnes += bit_count[ pBytes[i] ]; - 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.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Sim_UtilSetRandom( unsigned * pPatRand, int nSimWords ) -{ - int k; - for ( k = 0; k < nSimWords; k++ ) - pPatRand[k] = SIM_RANDOM_UNSIGNED; -} - -/**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 [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_UtilCountAllPairs( Vec_Ptr_t * vSuppFun, int nSimWords, Vec_Int_t * vCounters ) -{ - unsigned * pSupp; - int Counter, nOnes, nPairs, i; - Counter = 0; - Vec_PtrForEachEntry( vSuppFun, pSupp, i ) - { - nOnes = Sim_UtilCountOnes( pSupp, nSimWords ); - nPairs = nOnes * (nOnes - 1) / 2; - Vec_IntWriteEntry( vCounters, i, nPairs ); - Counter += nPairs; - } - return Counter; -} - -/**Function************************************************************* - - Synopsis [Counts the number of entries in the array of matrices.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_UtilCountPairsOne( Extra_BitMat_t * pMat, Vec_Int_t * vSupport ) -{ - int i, k, Index1, Index2; - int Counter = 0; -// int Counter2; - Vec_IntForEachEntry( vSupport, i, Index1 ) - Vec_IntForEachEntryStart( vSupport, k, Index2, Index1+1 ) - Counter += Extra_BitMatrixLookup1( pMat, i, k ); -// Counter2 = Extra_BitMatrixCountOnesUpper(pMat); -// assert( Counter == Counter2 ); - return Counter; -} - -/**Function************************************************************* - - Synopsis [Counts the number of entries in the array of matrices.] - - Description [] - - SideEffects [] - - 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; -clk = clock(); - p->nPairsSymm = 0; - p->nPairsNonSymm = 0; - for ( i = 0; i < p->nOutputs; i++ ) - { - nPairsTotal = Vec_IntEntry(p->vPairsTotal, i); - nPairsSym = Vec_IntEntry(p->vPairsSym, i); - nPairsNonSym = Vec_IntEntry(p->vPairsNonSym,i); - assert( nPairsTotal >= nPairsSym + nPairsNonSym ); - if ( nPairsTotal == nPairsSym + nPairsNonSym ) - { - p->nPairsSymm += nPairsSym; - p->nPairsNonSymm += nPairsNonSym; - continue; - } - nPairsSym = Sim_UtilCountPairsOne( Vec_PtrEntry(p->vMatrSymms, i), Vec_VecEntry(p->vSupports, i) ); - nPairsNonSym = Sim_UtilCountPairsOne( Vec_PtrEntry(p->vMatrNonSymms,i), Vec_VecEntry(p->vSupports, i) ); - assert( nPairsTotal >= nPairsSym + nPairsNonSym ); - Vec_IntWriteEntry( p->vPairsSym, i, nPairsSym ); - Vec_IntWriteEntry( p->vPairsNonSym, i, nPairsNonSym ); - p->nPairsSymm += nPairsSym; - p->nPairsNonSymm += nPairsNonSym; -// printf( "%d ", nPairsTotal - nPairsSym - nPairsNonSym ); - } -//printf( "\n" ); - p->nPairsRem = p->nPairsTotal-p->nPairsSymm-p->nPairsNonSymm; -p->timeCount += clock() - clk; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Sim_UtilMatrsAreDisjoint( Sym_Man_t * p ) -{ - int i; - for ( i = 0; i < p->nOutputs; i++ ) - if ( !Extra_BitMatrixIsDisjoint( Vec_PtrEntry(p->vMatrSymms,i), Vec_PtrEntry(p->vMatrNonSymms,i) ) ) - return 0; - return 1; -} - -//////////////////////////////////////////////////////////////////////// -/// END OF FILE /// -//////////////////////////////////////////////////////////////////////// - - |