| /**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 "base/abc/abc.h" |
| #include "aig/ivy/ivy.h" |
| #include "dec.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// 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( (Abc_Obj_t *)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( (Abc_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); |
| pAnd1 = Abc_ObjNotCond( (Abc_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); |
| pNode->pFunc = Abc_AigAnd( (Abc_Aig_t *)pNtk->pManFunc, pAnd0, pAnd1 ); |
| } |
| // complement the result if necessary |
| return Abc_ObjNotCond( (Abc_Obj_t *)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( (Abc_Obj_t *)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( (Abc_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); |
| pAnd1 = Abc_ObjNotCond( (Abc_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); |
| // pNode->pFunc = Abc_AigAnd( (Abc_Aig_t *)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( (Abc_Obj_t *)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 = (Abc_Aig_t *)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((Abc_Obj_t *)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 = (Abc_Obj_t *)pNode0->pFunc; |
| pAnd1 = (Abc_Obj_t *)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_MaxInt( 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, int 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( (Abc_Aig_t *)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( (Hop_Obj_t *)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( (Hop_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); |
| pAnd1 = Hop_NotCond( (Hop_Obj_t *)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( (Hop_Obj_t *)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( (Ivy_Obj_t *)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( (Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); |
| pAnd1 = Ivy_NotCond( (Ivy_Obj_t *)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( (Ivy_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) ); |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |