1 /**CFile****************************************************************
2
3 FileName [amapUniq.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [Technology mapper for standard cells.]
8
9 Synopsis [Checks if the structural node already exists.]
10
11 Author [Alan Mishchenko]
12
13 Affiliation [UC Berkeley]
14
15 Date [Ver. 1.0. Started - June 20, 2005.]
16
17 Revision [$Id: amapUniq.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18
19 ***********************************************************************/
20
21 #include "amapInt.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 [Checks if the entry exists and returns value.]
37
38 Description []
39
40 SideEffects []
41
42 SeeAlso []
43
44 ***********************************************************************/
Vec_IntCheckWithMask(Vec_Int_t * p,int Entry)45 static inline int Vec_IntCheckWithMask( Vec_Int_t * p, int Entry )
46 {
47 int i;
48 for ( i = 0; i < p->nSize; i++ )
49 if ( (0xffff & p->pArray[i]) == (0xffff & Entry) )
50 return p->pArray[i] >> 16;
51 return -1;
52 }
53
54 /**Function*************************************************************
55
56 Synopsis [Pushes entry in the natural order.]
57
58 Description []
59
60 SideEffects []
61
62 SeeAlso []
63
64 ***********************************************************************/
Vec_IntPushOrderWithMask(Vec_Int_t * p,int Entry)65 static inline void Vec_IntPushOrderWithMask( Vec_Int_t * p, int Entry )
66 {
67 int i;
68 if ( p->nSize == p->nCap )
69 Vec_IntGrow( p, 2 * p->nCap );
70 p->nSize++;
71 for ( i = p->nSize-2; i >= 0; i-- )
72 if ( (0xffff & p->pArray[i]) > (0xffff & Entry) )
73 p->pArray[i+1] = p->pArray[i];
74 else
75 break;
76 p->pArray[i+1] = Entry;
77 }
78
79 /**Function*************************************************************
80
81 Synopsis []
82
83 Description []
84
85 SideEffects []
86
87 SeeAlso []
88
89 ***********************************************************************/
Amap_LibFindNode(Amap_Lib_t * pLib,int iFan0,int iFan1,int fXor)90 int Amap_LibFindNode( Amap_Lib_t * pLib, int iFan0, int iFan1, int fXor )
91 {
92 if ( fXor )
93 return Vec_IntCheckWithMask( (Vec_Int_t *)Vec_PtrEntry(pLib->vRulesX, iFan0), iFan1 );
94 else
95 return Vec_IntCheckWithMask( (Vec_Int_t *)Vec_PtrEntry(pLib->vRules, iFan0), iFan1 );
96 }
97
98 /**Function*************************************************************
99
100 Synopsis [Checks if the three-argument rule exist.]
101
102 Description []
103
104 SideEffects []
105
106 SeeAlso []
107
108 ***********************************************************************/
Amap_LibFindMux(Amap_Lib_t * p,int iFan0,int iFan1,int iFan2)109 int Amap_LibFindMux( Amap_Lib_t * p, int iFan0, int iFan1, int iFan2 )
110 {
111 int x;
112 for ( x = 0; x < Vec_IntSize(p->vRules3); x += 4 )
113 {
114 if ( Vec_IntEntry(p->vRules3, x) == iFan0 &&
115 Vec_IntEntry(p->vRules3, x+1) == iFan1 &&
116 Vec_IntEntry(p->vRules3, x+2) == iFan2 )
117 {
118 return Vec_IntEntry(p->vRules3, x+3);
119 }
120 }
121 return -1;
122 }
123
124 /**Function*************************************************************
125
126 Synopsis [Creates a new node.]
127
128 Description []
129
130 SideEffects []
131
132 SeeAlso []
133
134 ***********************************************************************/
Amap_LibCreateObj(Amap_Lib_t * p)135 Amap_Nod_t * Amap_LibCreateObj( Amap_Lib_t * p )
136 {
137 Amap_Nod_t * pNode;
138 if ( p->nNodes == p->nNodesAlloc )
139 {
140 p->pNodes = ABC_REALLOC( Amap_Nod_t, p->pNodes, 2*p->nNodesAlloc );
141 p->nNodesAlloc *= 2;
142 }
143 pNode = Amap_LibNod( p, p->nNodes );
144 memset( pNode, 0, sizeof(Amap_Nod_t) );
145 pNode->Id = p->nNodes++;
146 Vec_PtrPush( p->vRules, Vec_IntAlloc(8) );
147 Vec_PtrPush( p->vRules, Vec_IntAlloc(8) );
148 Vec_PtrPush( p->vRulesX, Vec_IntAlloc(8) );
149 Vec_PtrPush( p->vRulesX, Vec_IntAlloc(8) );
150 return pNode;
151 }
152
153 /**Function*************************************************************
154
155 Synopsis [Creates a new node.]
156
157 Description []
158
159 SideEffects []
160
161 SeeAlso []
162
163 ***********************************************************************/
Amap_LibCreateVar(Amap_Lib_t * p)164 int Amap_LibCreateVar( Amap_Lib_t * p )
165 {
166 Amap_Nod_t * pNode;
167 // start the manager
168 assert( p->pNodes == NULL );
169 p->nNodesAlloc = 256;
170 p->pNodes = ABC_ALLOC( Amap_Nod_t, p->nNodesAlloc );
171 // create the first node
172 pNode = Amap_LibCreateObj( p );
173 p->pNodes->Type = AMAP_OBJ_PI;
174 p->pNodes->nSuppSize = 1;
175 return 0;
176 }
177
178 /**Function*************************************************************
179
180 Synopsis [Creates a new node.]
181
182 Description []
183
184 SideEffects []
185
186 SeeAlso []
187
188 ***********************************************************************/
Amap_LibCreateNode(Amap_Lib_t * p,int iFan0,int iFan1,int fXor)189 int Amap_LibCreateNode( Amap_Lib_t * p, int iFan0, int iFan1, int fXor )
190 {
191 Amap_Nod_t * pNode;
192 int iFan;
193 if ( iFan0 < iFan1 )
194 {
195 iFan = iFan0;
196 iFan0 = iFan1;
197 iFan1 = iFan;
198 }
199 pNode = Amap_LibCreateObj( p );
200 pNode->Type = fXor? AMAP_OBJ_XOR : AMAP_OBJ_AND;
201 pNode->nSuppSize = p->pNodes[Abc_Lit2Var(iFan0)].nSuppSize + p->pNodes[Abc_Lit2Var(iFan1)].nSuppSize;
202 pNode->iFan0 = iFan0;
203 pNode->iFan1 = iFan1;
204 if ( p->fVerbose )
205 printf( "Creating node %5d %c : iFan0 = %5d%c iFan1 = %5d%c\n",
206 pNode->Id, (fXor?'x':' '),
207 Abc_Lit2Var(iFan0), (Abc_LitIsCompl(iFan0)?'-':'+'),
208 Abc_Lit2Var(iFan1), (Abc_LitIsCompl(iFan1)?'-':'+') );
209
210 if ( fXor )
211 {
212 if ( iFan0 == iFan1 )
213 Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRulesX, iFan0), (pNode->Id << 16) | iFan1 );
214 else
215 {
216 Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRulesX, iFan0), (pNode->Id << 16) | iFan1 );
217 Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRulesX, iFan1), (pNode->Id << 16) | iFan0 );
218 }
219 }
220 else
221 {
222 if ( iFan0 == iFan1 )
223 Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRules, iFan0), (pNode->Id << 16) | iFan1 );
224 else
225 {
226 Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRules, iFan0), (pNode->Id << 16) | iFan1 );
227 Vec_IntPushOrderWithMask( (Vec_Int_t *)Vec_PtrEntry(p->vRules, iFan1), (pNode->Id << 16) | iFan0 );
228 }
229 }
230 return pNode->Id;
231 }
232
233 /**Function*************************************************************
234
235 Synopsis [Creates a new node.]
236
237 Description []
238
239 SideEffects []
240
241 SeeAlso []
242
243 ***********************************************************************/
Amap_LibCreateMux(Amap_Lib_t * p,int iFan0,int iFan1,int iFan2)244 int Amap_LibCreateMux( Amap_Lib_t * p, int iFan0, int iFan1, int iFan2 )
245 {
246 Amap_Nod_t * pNode;
247 pNode = Amap_LibCreateObj( p );
248 pNode->Type = AMAP_OBJ_MUX;
249 pNode->nSuppSize = p->pNodes[Abc_Lit2Var(iFan0)].nSuppSize + p->pNodes[Abc_Lit2Var(iFan1)].nSuppSize + p->pNodes[Abc_Lit2Var(iFan2)].nSuppSize;
250 pNode->iFan0 = iFan0;
251 pNode->iFan1 = iFan1;
252 pNode->iFan2 = iFan2;
253 if ( p->fVerbose )
254 printf( "Creating node %5d %c : iFan0 = %5d%c iFan1 = %5d%c iFan2 = %5d%c\n",
255 pNode->Id, 'm',
256 Abc_Lit2Var(iFan0), (Abc_LitIsCompl(iFan0)?'-':'+'),
257 Abc_Lit2Var(iFan1), (Abc_LitIsCompl(iFan1)?'-':'+'),
258 Abc_Lit2Var(iFan2), (Abc_LitIsCompl(iFan2)?'-':'+') );
259
260 Vec_IntPush( p->vRules3, iFan0 );
261 Vec_IntPush( p->vRules3, iFan1 );
262 Vec_IntPush( p->vRules3, iFan2 );
263 Vec_IntPush( p->vRules3, pNode->Id );
264 return pNode->Id;
265 }
266
267 /**Function*************************************************************
268
269 Synopsis [Allocates triangular lookup table.]
270
271 Description []
272
273 SideEffects []
274
275 SeeAlso []
276
277 ***********************************************************************/
Amap_LibLookupTableAlloc(Vec_Ptr_t * vVec,int fVerbose)278 int ** Amap_LibLookupTableAlloc( Vec_Ptr_t * vVec, int fVerbose )
279 {
280 Vec_Int_t * vOne;
281 int ** pRes, * pBuffer;
282 int i, k, nTotal, nSize, nEntries, Value;
283 // count the total size
284 nEntries = nSize = Vec_PtrSize( vVec );
285 Vec_PtrForEachEntry( Vec_Int_t *, vVec, vOne, i )
286 nEntries += Vec_IntSize(vOne);
287 pBuffer = ABC_ALLOC( int, nSize * sizeof(void *) + nEntries );
288 pRes = (int **)pBuffer;
289 pRes[0] = pBuffer + nSize * sizeof(void *);
290 nTotal = 0;
291 Vec_PtrForEachEntry( Vec_Int_t *, vVec, vOne, i )
292 {
293 pRes[i] = pRes[0] + nTotal;
294 nTotal += Vec_IntSize(vOne) + 1;
295 if ( fVerbose )
296 printf( "%d : ", i );
297 Vec_IntForEachEntry( vOne, Value, k )
298 {
299 pRes[i][k] = Value;
300 if ( fVerbose )
301 printf( "%d(%d) ", Value&0xffff, Value>>16 );
302 }
303 if ( fVerbose )
304 printf( "\n" );
305 pRes[i][k] = 0;
306 }
307 assert( nTotal == nEntries );
308 return pRes;
309 }
310
311 ////////////////////////////////////////////////////////////////////////
312 /// END OF FILE ///
313 ////////////////////////////////////////////////////////////////////////
314
315
316 ABC_NAMESPACE_IMPL_END
317
318