mirror of https://github.com/YosysHQ/abc.git
701 lines
21 KiB
C
701 lines
21 KiB
C
/**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 "base/abc/abc.h"
|
|
#include "opt/cut/cut.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// 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;
|
|
|
|
static Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
|
|
static int Abc_NtkComputeArea( Abc_Ntk_t * pNtk, Cut_Man_t * p );
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_NtkCutsSubtractFanunt( Abc_Ntk_t * pNtk )
|
|
{
|
|
Abc_Obj_t * pObj, * pFan0, * pFan1, * pFanC;
|
|
int i, Counter = 0;
|
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
|
{
|
|
if ( !Abc_NodeIsMuxType(pObj) )
|
|
continue;
|
|
pFanC = Abc_NodeRecognizeMux( pObj, &pFan1, &pFan0 );
|
|
pFanC = Abc_ObjRegular(pFanC);
|
|
pFan0 = Abc_ObjRegular(pFan0);
|
|
assert( pFanC->vFanouts.nSize > 1 );
|
|
pFanC->vFanouts.nSize--;
|
|
Counter++;
|
|
if ( Abc_NodeIsExorType(pObj) )
|
|
{
|
|
assert( pFan0->vFanouts.nSize > 1 );
|
|
pFan0->vFanouts.nSize--;
|
|
Counter++;
|
|
}
|
|
}
|
|
printf("Substracted %d fanouts\n", Counter );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_NtkCutsAddFanunt( Abc_Ntk_t * pNtk )
|
|
{
|
|
Abc_Obj_t * pObj, * pFan0, * pFan1, * pFanC;
|
|
int i, Counter = 0;
|
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
|
{
|
|
if ( !Abc_NodeIsMuxType(pObj) )
|
|
continue;
|
|
pFanC = Abc_NodeRecognizeMux( pObj, &pFan1, &pFan0 );
|
|
pFanC = Abc_ObjRegular(pFanC);
|
|
pFan0 = Abc_ObjRegular(pFan0);
|
|
pFanC->vFanouts.nSize++;
|
|
Counter++;
|
|
if ( Abc_NodeIsExorType(pObj) )
|
|
{
|
|
pFan0->vFanouts.nSize++;
|
|
Counter++;
|
|
}
|
|
}
|
|
printf("Added %d fanouts\n", Counter );
|
|
}
|
|
|
|
/**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;
|
|
Cut_Cut_t * pList;
|
|
Abc_Obj_t * pObj, * pNode;
|
|
Vec_Ptr_t * vNodes;
|
|
Vec_Int_t * vChoices;
|
|
int i;
|
|
abctime clk = Abc_Clock();
|
|
|
|
extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk );
|
|
extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk );
|
|
|
|
if ( pParams->fAdjust )
|
|
Abc_NtkCutsSubtractFanunt( 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( Abc_Obj_t *, 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
|
|
pList = (Cut_Cut_t *)Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree );
|
|
if ( pParams->fNpnSave && pList )
|
|
{
|
|
extern void Npn_ManSaveOne( unsigned * puTruth, int nVars );
|
|
Cut_Cut_t * pCut;
|
|
for ( pCut = pList; pCut; pCut = pCut->pNext )
|
|
if ( pCut->nLeaves >= 4 )
|
|
Npn_ManSaveOne( Cut_CutReadTruth(pCut), pCut->nLeaves );
|
|
}
|
|
// 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 = (Abc_Obj_t *)pNode->pData )
|
|
Vec_IntPush( vChoices, pNode->Id );
|
|
Cut_NodeUnionCuts( p, vChoices );
|
|
}
|
|
}
|
|
Extra_ProgressBarStop( pProgress );
|
|
Vec_PtrFree( vNodes );
|
|
Vec_IntFree( vChoices );
|
|
Cut_ManPrintStats( p );
|
|
ABC_PRT( "TOTAL", Abc_Clock() - clk );
|
|
// printf( "Area = %d.\n", Abc_NtkComputeArea( pNtk, p ) );
|
|
//Abc_NtkPrintCuts( p, pNtk, 0 );
|
|
// Cut_ManPrintStatsToFile( p, pNtk->pSpec, Abc_Clock() - clk );
|
|
|
|
// temporary printout of stats
|
|
if ( nTotal )
|
|
printf( "Total cuts = %d. Good cuts = %d. Ratio = %5.2f\n", nTotal, nGood, ((double)nGood)/nTotal );
|
|
if ( pParams->fAdjust )
|
|
Abc_NtkCutsAddFanunt( pNtk );
|
|
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 = Abc_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( Abc_Obj_t *, 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 );
|
|
//ABC_PRT( "Total", Abc_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;
|
|
abctime clk = Abc_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 )
|
|
{
|
|
Cut_ManPrintStats( p );
|
|
ABC_PRT( "TOTAL ", Abc_Clock() - clk );
|
|
printf( "Converged after %d iterations.\n", nIters );
|
|
}
|
|
//Abc_NtkPrintCuts( p, pNtk, 1 );
|
|
return p;
|
|
*/
|
|
return NULL;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes area.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Abc_NtkComputeArea( Abc_Ntk_t * pNtk, Cut_Man_t * p )
|
|
{
|
|
Abc_Obj_t * pObj;
|
|
int Counter, i;
|
|
Counter = 0;
|
|
Abc_NtkForEachCo( pNtk, pObj, i )
|
|
Counter += Cut_ManMappingArea_rec( p, Abc_ObjFaninId0(pObj) );
|
|
return Counter;
|
|
}
|
|
|
|
/**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( (Cut_Man_t *)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((Cut_Man_t *)p);
|
|
if ( pParams->fLocal )
|
|
{
|
|
Vec_Int_t * vNodeAttrs = Cut_ManReadNodeAttrs((Cut_Man_t *)p);
|
|
fDagNode = Vec_IntEntry( vNodeAttrs, pObj->Id );
|
|
if ( fDagNode ) Cut_ManIncrementDagNodes( (Cut_Man_t *)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( (Cut_Man_t *)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( (Cut_Man_t *)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( (Cut_Man_t *)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_Cut_t * pList;
|
|
Abc_Obj_t * pObj;
|
|
int i;
|
|
printf( "Cuts of the network:\n" );
|
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
|
{
|
|
pList = (Cut_Cut_t *)Abc_NodeReadCuts( (Cut_Man_t *)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_Cut_t * pList;
|
|
Abc_Obj_t * pObj;
|
|
pObj = Abc_NtkObj( pNtk, 2 * Abc_NtkObjNum(pNtk) / 3 );
|
|
pList = (Cut_Cut_t *)Abc_NodeReadCuts( (Cut_Man_t *)p, pObj );
|
|
printf( "Node %s:\n", Abc_ObjName(pObj) );
|
|
Cut_CutPrintList( pList, fSeq );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Assigns global attributes randomly.]
|
|
|
|
Description [Old code.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
|
|
{
|
|
Vec_Int_t * vAttrs;
|
|
// Vec_Ptr_t * vNodes;
|
|
Abc_Obj_t * pObj;//, * pTemp;
|
|
int i;//, k;
|
|
int nNodesTotal = 0, nMffcsTotal = 0;
|
|
extern Vec_Ptr_t * Abc_NodeMffcInsideCollect( Abc_Obj_t * pNode );
|
|
|
|
vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
|
|
// Abc_NtkForEachCi( pNtk, pObj, i )
|
|
// Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
|
|
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
|
{
|
|
if ( Abc_ObjIsNode(pObj) )
|
|
nNodesTotal++;
|
|
if ( Abc_ObjIsCo(pObj) && Abc_ObjIsNode(Abc_ObjFanin0(pObj)) )
|
|
nMffcsTotal += Abc_NodeMffcSize( Abc_ObjFanin0(pObj) );
|
|
// if ( Abc_ObjIsNode(pObj) && (rand() % 4 == 0) )
|
|
// if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) )
|
|
if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) )
|
|
{
|
|
int nMffc = Abc_NodeMffcSize(pObj);
|
|
nMffcsTotal += Abc_NodeMffcSize(pObj);
|
|
// printf( "%d ", nMffc );
|
|
|
|
if ( nMffc > 2 || Abc_ObjFanoutNum(pObj) > 8 )
|
|
Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
|
}
|
|
}
|
|
/*
|
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
|
{
|
|
if ( Vec_IntEntry( vAttrs, pObj->Id ) )
|
|
{
|
|
vNodes = Abc_NodeMffcInsideCollect( pObj );
|
|
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pTemp, k )
|
|
if ( pTemp != pObj )
|
|
Vec_IntWriteEntry( vAttrs, pTemp->Id, 0 );
|
|
Vec_PtrFree( vNodes );
|
|
}
|
|
}
|
|
*/
|
|
printf( "Total nodes = %d. Total MFFC nodes = %d.\n", nNodesTotal, nMffcsTotal );
|
|
return vAttrs;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Assigns global attributes randomly.]
|
|
|
|
Description [Old code.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Abc_NtkSubDagSize_rec( Abc_Obj_t * pObj, Vec_Int_t * vAttrs )
|
|
{
|
|
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
|
return 0;
|
|
Abc_NodeSetTravIdCurrent(pObj);
|
|
if ( Vec_IntEntry( vAttrs, pObj->Id ) )
|
|
return 0;
|
|
if ( Abc_ObjIsCi(pObj) )
|
|
return 1;
|
|
assert( Abc_ObjFaninNum(pObj) == 2 );
|
|
return 1 + Abc_NtkSubDagSize_rec(Abc_ObjFanin0(pObj), vAttrs) +
|
|
Abc_NtkSubDagSize_rec(Abc_ObjFanin1(pObj), vAttrs);
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Assigns global attributes randomly.]
|
|
|
|
Description [Old code.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Vec_Int_t * Abc_NtkGetNodeAttributes2( Abc_Ntk_t * pNtk )
|
|
{
|
|
Vec_Int_t * vAttrs;
|
|
Abc_Obj_t * pObj;
|
|
int i, nSize;
|
|
assert( Abc_NtkIsDfsOrdered(pNtk) );
|
|
vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
|
|
Abc_NtkForEachObj( pNtk, pObj, i )
|
|
{
|
|
// skip no-nodes and nodes without fanouts
|
|
if ( pObj->Id == 0 || !(Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj)) )
|
|
continue;
|
|
// the node has more than one fanout - count its sub-DAG size
|
|
Abc_NtkIncrementTravId( pNtk );
|
|
nSize = Abc_NtkSubDagSize_rec( pObj, vAttrs );
|
|
if ( nSize > 15 )
|
|
Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
|
|
}
|
|
return vAttrs;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|