1 /**CFile****************************************************************
2 
3   FileName    [decAbc.c]
4 
5   PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
6 
7   Synopsis    [Interface between the decomposition package and ABC network.]
8 
9   Author      [MVSIS Group]
10 
11   Affiliation [UC Berkeley]
12 
13   Date        [Ver. 1.0. Started - February 1, 2003.]
14 
15   Revision    [$Id: decAbc.c,v 1.1 2003/05/22 19:20:05 alanmi Exp $]
16 
17 ***********************************************************************/
18 
19 #include "base/abc/abc.h"
20 #include "aig/ivy/ivy.h"
21 #include "dec.h"
22 
23 ABC_NAMESPACE_IMPL_START
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 ///                        DECLARATIONS                              ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 ////////////////////////////////////////////////////////////////////////
31 ///                     FUNCTION DEFINITIONS                         ///
32 ////////////////////////////////////////////////////////////////////////
33 
34 /**Function*************************************************************
35 
36   Synopsis    [Transforms the decomposition graph into the AIG.]
37 
38   Description [AIG nodes for the fanins should be assigned to pNode->pFunc
39   of the leaves of the graph before calling this procedure.]
40 
41   SideEffects []
42 
43   SeeAlso     []
44 
45 ***********************************************************************/
Dec_GraphToNetwork(Abc_Ntk_t * pNtk,Dec_Graph_t * pGraph)46 Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph )
47 {
48     Abc_Obj_t * pAnd0, * pAnd1;
49     Dec_Node_t * pNode = NULL; // Suppress "might be used uninitialized"
50     int i;
51     // check for constant function
52     if ( Dec_GraphIsConst(pGraph) )
53         return Abc_ObjNotCond( Abc_AigConst1(pNtk), Dec_GraphIsComplement(pGraph) );
54     // check for a literal
55     if ( Dec_GraphIsVar(pGraph) )
56         return Abc_ObjNotCond( (Abc_Obj_t *)Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) );
57     // build the AIG nodes corresponding to the AND gates of the graph
58     Dec_GraphForEachNode( pGraph, pNode, i )
59     {
60         pAnd0 = Abc_ObjNotCond( (Abc_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
61         pAnd1 = Abc_ObjNotCond( (Abc_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
62         pNode->pFunc = Abc_AigAnd( (Abc_Aig_t *)pNtk->pManFunc, pAnd0, pAnd1 );
63     }
64     // complement the result if necessary
65     return Abc_ObjNotCond( (Abc_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) );
66 }
67 
68 /**Function*************************************************************
69 
70   Synopsis    [Transforms the decomposition graph into the AIG.]
71 
72   Description []
73 
74   SideEffects []
75 
76   SeeAlso     []
77 
78 ***********************************************************************/
Dec_SopToAig(Abc_Ntk_t * pNtk,char * pSop,Vec_Ptr_t * vFaninAigs)79 Abc_Obj_t * Dec_SopToAig( Abc_Ntk_t * pNtk, char * pSop, Vec_Ptr_t * vFaninAigs )
80 {
81     Abc_Obj_t * pFunc;
82     Dec_Graph_t * pFForm;
83     Dec_Node_t * pNode;
84     int i;
85     pFForm = Dec_Factor( pSop );
86     Dec_GraphForEachLeaf( pFForm, pNode, i )
87         pNode->pFunc = Vec_PtrEntry( vFaninAigs, i );
88     pFunc = Dec_GraphToNetwork( pNtk, pFForm );
89     Dec_GraphFree( pFForm );
90     return pFunc;
91 }
92 
93 /**Function*************************************************************
94 
95   Synopsis    [Transforms the decomposition graph into the AIG.]
96 
97   Description []
98 
99   SideEffects []
100 
101   SeeAlso     []
102 
103 ***********************************************************************/
Dec_GraphToAig(Abc_Ntk_t * pNtk,Dec_Graph_t * pFForm,Vec_Ptr_t * vFaninAigs)104 Abc_Obj_t * Dec_GraphToAig( Abc_Ntk_t * pNtk, Dec_Graph_t * pFForm, Vec_Ptr_t * vFaninAigs )
105 {
106     Abc_Obj_t * pFunc;
107     Dec_Node_t * pNode;
108     int i;
109     Dec_GraphForEachLeaf( pFForm, pNode, i )
110         pNode->pFunc = Vec_PtrEntry( vFaninAigs, i );
111     pFunc = Dec_GraphToNetwork( pNtk, pFForm );
112     return pFunc;
113 }
114 
115 /**Function*************************************************************
116 
117   Synopsis    [Transforms the decomposition graph into the AIG.]
118 
119   Description [AIG nodes for the fanins should be assigned to pNode->pFunc
120   of the leaves of the graph before calling this procedure.]
121 
122   SideEffects []
123 
124   SeeAlso     []
125 
126 ***********************************************************************/
Dec_GraphToNetworkNoStrash(Abc_Ntk_t * pNtk,Dec_Graph_t * pGraph)127 Abc_Obj_t * Dec_GraphToNetworkNoStrash( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph )
128 {
129     Abc_Obj_t * pAnd, * pAnd0, * pAnd1;
130     Dec_Node_t * pNode = NULL; // Suppress "might be used uninitialized"
131     int i;
132     // check for constant function
133     if ( Dec_GraphIsConst(pGraph) )
134         return Abc_ObjNotCond( Abc_AigConst1(pNtk), Dec_GraphIsComplement(pGraph) );
135     // check for a literal
136     if ( Dec_GraphIsVar(pGraph) )
137         return Abc_ObjNotCond( (Abc_Obj_t *)Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) );
138     // build the AIG nodes corresponding to the AND gates of the graph
139     Dec_GraphForEachNode( pGraph, pNode, i )
140     {
141         pAnd0 = Abc_ObjNotCond( (Abc_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
142         pAnd1 = Abc_ObjNotCond( (Abc_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
143 //        pNode->pFunc = Abc_AigAnd( (Abc_Aig_t *)pNtk->pManFunc, pAnd0, pAnd1 );
144         pAnd = Abc_NtkCreateNode( pNtk );
145         Abc_ObjAddFanin( pAnd, pAnd0 );
146         Abc_ObjAddFanin( pAnd, pAnd1 );
147         pNode->pFunc = pAnd;
148     }
149     // complement the result if necessary
150     return Abc_ObjNotCond( (Abc_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) );
151 }
152 
153 /**Function*************************************************************
154 
155   Synopsis    [Counts the number of new nodes added when using this graph.]
156 
157   Description [AIG nodes for the fanins should be assigned to pNode->pFunc
158   of the leaves of the graph before calling this procedure.
159   Returns -1 if the number of nodes and levels exceeded the given limit or
160   the number of levels exceeded the maximum allowed level.]
161 
162   SideEffects []
163 
164   SeeAlso     []
165 
166 ***********************************************************************/
Dec_GraphToNetworkCount(Abc_Obj_t * pRoot,Dec_Graph_t * pGraph,int NodeMax,int LevelMax)167 int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax )
168 {
169     Abc_Aig_t * pMan = (Abc_Aig_t *)pRoot->pNtk->pManFunc;
170     Dec_Node_t * pNode, * pNode0, * pNode1;
171     Abc_Obj_t * pAnd, * pAnd0, * pAnd1;
172     int i, Counter, LevelNew, LevelOld;
173     // check for constant function or a literal
174     if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) )
175         return 0;
176     // set the levels of the leaves
177     Dec_GraphForEachLeaf( pGraph, pNode, i )
178         pNode->Level = Abc_ObjRegular((Abc_Obj_t *)pNode->pFunc)->Level;
179     // compute the AIG size after adding the internal nodes
180     Counter = 0;
181     Dec_GraphForEachNode( pGraph, pNode, i )
182     {
183         // get the children of this node
184         pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node );
185         pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node );
186         // get the AIG nodes corresponding to the children
187         pAnd0 = (Abc_Obj_t *)pNode0->pFunc;
188         pAnd1 = (Abc_Obj_t *)pNode1->pFunc;
189         if ( pAnd0 && pAnd1 )
190         {
191             // if they are both present, find the resulting node
192             pAnd0 = Abc_ObjNotCond( pAnd0, pNode->eEdge0.fCompl );
193             pAnd1 = Abc_ObjNotCond( pAnd1, pNode->eEdge1.fCompl );
194             pAnd  = Abc_AigAndLookup( pMan, pAnd0, pAnd1 );
195             // return -1 if the node is the same as the original root
196             if ( Abc_ObjRegular(pAnd) == pRoot )
197                 return -1;
198         }
199         else
200             pAnd = NULL;
201         // count the number of added nodes
202         if ( pAnd == NULL || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pAnd)) )
203         {
204             if ( ++Counter > NodeMax )
205                 return -1;
206         }
207         // count the number of new levels
208         LevelNew = 1 + Abc_MaxInt( pNode0->Level, pNode1->Level );
209         if ( pAnd )
210         {
211             if ( Abc_ObjRegular(pAnd) == Abc_AigConst1(pRoot->pNtk) )
212                 LevelNew = 0;
213             else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd0) )
214                 LevelNew = (int)Abc_ObjRegular(pAnd0)->Level;
215             else if ( Abc_ObjRegular(pAnd) == Abc_ObjRegular(pAnd1) )
216                 LevelNew = (int)Abc_ObjRegular(pAnd1)->Level;
217             LevelOld = (int)Abc_ObjRegular(pAnd)->Level;
218 //            assert( LevelNew == LevelOld );
219         }
220         if ( LevelNew > LevelMax )
221             return -1;
222         pNode->pFunc = pAnd;
223         pNode->Level = LevelNew;
224     }
225     return Counter;
226 }
227 
228 
229 /**Function*************************************************************
230 
231   Synopsis    [Replaces MFFC of the node by the new factored form.]
232 
233   Description []
234 
235   SideEffects []
236 
237   SeeAlso     []
238 
239 ***********************************************************************/
Dec_GraphUpdateNetwork(Abc_Obj_t * pRoot,Dec_Graph_t * pGraph,int fUpdateLevel,int nGain)240 void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain )
241 {
242     extern Abc_Obj_t *    Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph );
243     Abc_Obj_t * pRootNew;
244     Abc_Ntk_t * pNtk = pRoot->pNtk;
245     int nNodesNew, nNodesOld;
246     nNodesOld = Abc_NtkNodeNum(pNtk);
247     // create the new structure of nodes
248     pRootNew = Dec_GraphToNetwork( pNtk, pGraph );
249     // remove the old nodes
250     Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pRoot, pRootNew, fUpdateLevel );
251     // compare the gains
252     nNodesNew = Abc_NtkNodeNum(pNtk);
253     //assert( nGain <= nNodesOld - nNodesNew );
254 }
255 
256 
257 /**Function*************************************************************
258 
259   Synopsis    [Transforms the decomposition graph into the AIG.]
260 
261   Description []
262 
263   SideEffects []
264 
265   SeeAlso     []
266 
267 ***********************************************************************/
Dec_GraphToNetworkAig(Hop_Man_t * pMan,Dec_Graph_t * pGraph)268 Hop_Obj_t * Dec_GraphToNetworkAig( Hop_Man_t * pMan, Dec_Graph_t * pGraph )
269 {
270     Dec_Node_t * pNode = NULL; // Suppress "might be used uninitialized"
271     Hop_Obj_t * pAnd0, * pAnd1;
272     int i;
273     // check for constant function
274     if ( Dec_GraphIsConst(pGraph) )
275         return Hop_NotCond( Hop_ManConst1(pMan), Dec_GraphIsComplement(pGraph) );
276     // check for a literal
277     if ( Dec_GraphIsVar(pGraph) )
278         return Hop_NotCond( (Hop_Obj_t *)Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) );
279     // build the AIG nodes corresponding to the AND gates of the graph
280     Dec_GraphForEachNode( pGraph, pNode, i )
281     {
282         pAnd0 = Hop_NotCond( (Hop_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
283         pAnd1 = Hop_NotCond( (Hop_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
284         pNode->pFunc = Hop_And( pMan, pAnd0, pAnd1 );
285     }
286     // complement the result if necessary
287     return Hop_NotCond( (Hop_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) );
288 }
289 
290 /**Function*************************************************************
291 
292   Synopsis    [Strashes one logic node using its SOP.]
293 
294   Description []
295 
296   SideEffects []
297 
298   SeeAlso     []
299 
300 ***********************************************************************/
Dec_GraphFactorSop(Hop_Man_t * pMan,char * pSop)301 Hop_Obj_t * Dec_GraphFactorSop( Hop_Man_t * pMan, char * pSop )
302 {
303     Hop_Obj_t * pFunc;
304     Dec_Graph_t * pFForm;
305     Dec_Node_t * pNode;
306     int i;
307     // perform factoring
308     pFForm = Dec_Factor( pSop );
309     // collect the fanins
310     Dec_GraphForEachLeaf( pFForm, pNode, i )
311         pNode->pFunc = Hop_IthVar( pMan, i );
312     // perform strashing
313     pFunc = Dec_GraphToNetworkAig( pMan, pFForm );
314     Dec_GraphFree( pFForm );
315     return pFunc;
316 }
317 
318 /**Function*************************************************************
319 
320   Synopsis    [Transforms the decomposition graph into the AIG.]
321 
322   Description []
323 
324   SideEffects []
325 
326   SeeAlso     []
327 
328 ***********************************************************************/
Dec_GraphToNetworkIvy(Ivy_Man_t * pMan,Dec_Graph_t * pGraph)329 Ivy_Obj_t * Dec_GraphToNetworkIvy( Ivy_Man_t * pMan, Dec_Graph_t * pGraph )
330 {
331     Dec_Node_t * pNode = NULL; // Suppress "might be used uninitialized"
332     Ivy_Obj_t * pAnd0, * pAnd1;
333     int i;
334     // check for constant function
335     if ( Dec_GraphIsConst(pGraph) )
336         return Ivy_NotCond( Ivy_ManConst1(pMan), Dec_GraphIsComplement(pGraph) );
337     // check for a literal
338     if ( Dec_GraphIsVar(pGraph) )
339         return Ivy_NotCond( (Ivy_Obj_t *)Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) );
340     // build the AIG nodes corresponding to the AND gates of the graph
341     Dec_GraphForEachNode( pGraph, pNode, i )
342     {
343         pAnd0 = Ivy_NotCond( (Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );
344         pAnd1 = Ivy_NotCond( (Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );
345         pNode->pFunc = Ivy_And( pMan, pAnd0, pAnd1 );
346     }
347     // complement the result if necessary
348     return Ivy_NotCond( (Ivy_Obj_t *)pNode->pFunc, Dec_GraphIsComplement(pGraph) );
349 }
350 
351 
352 ////////////////////////////////////////////////////////////////////////
353 ///                       END OF FILE                                ///
354 ////////////////////////////////////////////////////////////////////////
355 
356 
357 ABC_NAMESPACE_IMPL_END
358 
359