mirror of https://github.com/YosysHQ/abc.git
354 lines
12 KiB
C
354 lines
12 KiB
C
/**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 = NULL; // Suppress "might be used uninitialized"
|
|
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 []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Abc_Obj_t * Dec_SopToAig( Abc_Ntk_t * pNtk, char * pSop, Vec_Ptr_t * vFaninAigs )
|
|
{
|
|
Abc_Obj_t * pFunc;
|
|
Dec_Graph_t * pFForm;
|
|
Dec_Node_t * pNode;
|
|
int i;
|
|
pFForm = Dec_Factor( pSop );
|
|
Dec_GraphForEachLeaf( pFForm, pNode, i )
|
|
pNode->pFunc = Vec_PtrEntry( vFaninAigs, i );
|
|
pFunc = Dec_GraphToNetwork( pNtk, pFForm );
|
|
Dec_GraphFree( pFForm );
|
|
return pFunc;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Transforms the decomposition graph into the AIG.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Abc_Obj_t * Dec_GraphToAig( Abc_Ntk_t * pNtk, Dec_Graph_t * pFForm, Vec_Ptr_t * vFaninAigs )
|
|
{
|
|
Abc_Obj_t * pFunc;
|
|
Dec_Node_t * pNode;
|
|
int i;
|
|
Dec_GraphForEachLeaf( pFForm, pNode, i )
|
|
pNode->pFunc = Vec_PtrEntry( vFaninAigs, i );
|
|
pFunc = Dec_GraphToNetwork( pNtk, pFForm );
|
|
return pFunc;
|
|
}
|
|
|
|
/**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 = NULL; // Suppress "might be used uninitialized"
|
|
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 )
|
|
{
|
|
extern Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph );
|
|
Abc_Obj_t * pRootNew;
|
|
Abc_Ntk_t * pNtk = pRoot->pNtk;
|
|
int nNodesNew, nNodesOld;
|
|
nNodesOld = Abc_NtkNodeNum(pNtk);
|
|
// create the new structure of nodes
|
|
pRootNew = Dec_GraphToNetwork( pNtk, pGraph );
|
|
// 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 = NULL; // Suppress "might be used uninitialized"
|
|
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 = NULL; // Suppress "might be used uninitialized"
|
|
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 ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|