abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
abcCheck.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [abcCheck.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Network and node package.]
8 
9  Synopsis [Consistency checking procedures.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: abcCheck.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "abc.h"
22 #include "base/main/main.h"
23 #include "misc/extra/extraBdd.h"
24 
26 
27 
28 ////////////////////////////////////////////////////////////////////////
29 /// DECLARATIONS ///
30 ////////////////////////////////////////////////////////////////////////
31 
32 static int Abc_NtkCheckNames( Abc_Ntk_t * pNtk );
33 static int Abc_NtkCheckPis( Abc_Ntk_t * pNtk );
34 static int Abc_NtkCheckPos( Abc_Ntk_t * pNtk );
35 //static int Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj );
36 static int Abc_NtkCheckNet( Abc_Ntk_t * pNtk, Abc_Obj_t * pNet );
37 static int Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode );
38 static int Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch );
39 
40 static int Abc_NtkComparePis( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
41 static int Abc_NtkComparePos( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
42 static int Abc_NtkCompareLatches( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb );
43 
44 static inline char * Abc_ObjNameNet( Abc_Obj_t * pObj ) { return (Abc_ObjIsNode(pObj) && Abc_NtkIsNetlist(pObj->pNtk)) ? Abc_ObjName(Abc_ObjFanout0(pObj)) : Abc_ObjName(pObj); }
45 
46 ////////////////////////////////////////////////////////////////////////
47 /// FUNCTION DEFINITIONS ///
48 ////////////////////////////////////////////////////////////////////////
49 
50 /**Function*************************************************************
51 
52  Synopsis [Checks the integrity of the network.]
53 
54  Description []
55 
56  SideEffects []
57 
58  SeeAlso []
59 
60 ***********************************************************************/
61 int Abc_NtkCheck( Abc_Ntk_t * pNtk )
62 {
63  return !Abc_FrameIsFlagEnabled( "check" ) || Abc_NtkDoCheck( pNtk );
64 }
65 
66 /**Function*************************************************************
67 
68  Synopsis [Checks the integrity of the network after reading.]
69 
70  Description []
71 
72  SideEffects []
73 
74  SeeAlso []
75 
76 ***********************************************************************/
78 {
79  return !Abc_FrameIsFlagEnabled( "checkread" ) || Abc_NtkDoCheck( pNtk );
80 }
81 
82 /**Function*************************************************************
83 
84  Synopsis [Checks the integrity of the network.]
85 
86  Description []
87 
88  SideEffects []
89 
90  SeeAlso []
91 
92 ***********************************************************************/
94 {
95  Abc_Obj_t * pObj, * pNet, * pNode;
96  int i;
97 
98  // check network types
99  if ( !Abc_NtkIsNetlist(pNtk) && !Abc_NtkIsLogic(pNtk) && !Abc_NtkIsStrash(pNtk) )
100  {
101  fprintf( stdout, "NetworkCheck: Unknown network type.\n" );
102  return 0;
103  }
104  if ( !Abc_NtkHasSop(pNtk) && !Abc_NtkHasBdd(pNtk) && !Abc_NtkHasAig(pNtk) && !Abc_NtkHasMapping(pNtk) && !Abc_NtkHasBlifMv(pNtk) && !Abc_NtkHasBlackbox(pNtk) )
105  {
106  fprintf( stdout, "NetworkCheck: Unknown functionality type.\n" );
107  return 0;
108  }
109  if ( Abc_NtkHasMapping(pNtk) )
110  {
111  if ( pNtk->pManFunc != Abc_FrameReadLibGen() )
112  {
113  fprintf( stdout, "NetworkCheck: The library of the mapped network is not the global library.\n" );
114  return 0;
115  }
116  }
117 
118  if ( Abc_NtkHasOnlyLatchBoxes(pNtk) )
119  {
120  // check CI/CO numbers
121  if ( Abc_NtkPiNum(pNtk) + Abc_NtkLatchNum(pNtk) != Abc_NtkCiNum(pNtk) )
122  {
123  fprintf( stdout, "NetworkCheck: Number of CIs does not match number of PIs and latches.\n" );
124  fprintf( stdout, "One possible reason is that latches are added twice:\n" );
125  fprintf( stdout, "in procedure Abc_NtkCreateObj() and in the user's code.\n" );
126  return 0;
127  }
128  if ( Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) != Abc_NtkCoNum(pNtk) )
129  {
130  fprintf( stdout, "NetworkCheck: Number of COs does not match number of POs, asserts, and latches.\n" );
131  fprintf( stdout, "One possible reason is that latches are added twice:\n" );
132  fprintf( stdout, "in procedure Abc_NtkCreateObj() and in the user's code.\n" );
133  return 0;
134  }
135  }
136 
137  // check the names
138  if ( !Abc_NtkCheckNames( pNtk ) )
139  return 0;
140 
141  // check PIs and POs
142  Abc_NtkCleanCopy( pNtk );
143  if ( !Abc_NtkCheckPis( pNtk ) )
144  return 0;
145  if ( !Abc_NtkCheckPos( pNtk ) )
146  return 0;
147 
148  if ( Abc_NtkHasBlackbox(pNtk) )
149  return 1;
150 
151  // check the connectivity of objects
152  Abc_NtkForEachObj( pNtk, pObj, i )
153  if ( !Abc_NtkCheckObj( pNtk, pObj ) )
154  return 0;
155 
156  // if it is a netlist change nets and latches
157  if ( Abc_NtkIsNetlist(pNtk) )
158  {
159  if ( Abc_NtkNetNum(pNtk) == 0 )
160  fprintf( stdout, "NetworkCheck: Warning! Netlist has no nets.\n" );
161  // check the nets
162  Abc_NtkForEachNet( pNtk, pNet, i )
163  if ( !Abc_NtkCheckNet( pNtk, pNet ) )
164  return 0;
165  }
166  else
167  {
168  if ( Abc_NtkNetNum(pNtk) != 0 )
169  {
170  fprintf( stdout, "NetworkCheck: A network that is not a netlist has nets.\n" );
171  return 0;
172  }
173  }
174 
175  // check the nodes
176  if ( Abc_NtkIsStrash(pNtk) )
177  Abc_AigCheck( (Abc_Aig_t *)pNtk->pManFunc );
178  else
179  {
180  Abc_NtkForEachNode( pNtk, pNode, i )
181  if ( !Abc_NtkCheckNode( pNtk, pNode ) )
182  return 0;
183  }
184 
185  // check the latches
186  Abc_NtkForEachLatch( pNtk, pNode, i )
187  if ( !Abc_NtkCheckLatch( pNtk, pNode ) )
188  return 0;
189 
190  // finally, check for combinational loops
191 // clk = Abc_Clock();
192  if ( !Abc_NtkIsAcyclic( pNtk ) )
193  {
194  fprintf( stdout, "NetworkCheck: Network contains a combinational loop.\n" );
195  return 0;
196  }
197 // ABC_PRT( "Acyclic ", Abc_Clock() - clk );
198 
199  // check the EXDC network if present
200  if ( pNtk->pExdc )
201  Abc_NtkCheck( pNtk->pExdc );
202 /*
203  // check the hierarchy
204  if ( Abc_NtkIsNetlist(pNtk) && pNtk->tName2Model )
205  {
206  stmm_generator * gen;
207  Abc_Ntk_t * pNtkTemp;
208  char * pName;
209  // check other networks
210  stmm_foreach_item( pNtk->tName2Model, gen, &pName, (char **)&pNtkTemp )
211  {
212  pNtkTemp->fHiePath = pNtkTemp->fHieVisited = 0;
213  if ( !Abc_NtkCheck( pNtkTemp ) )
214  return 0;
215  }
216  // check acyclic dependency of the models
217  if ( !Abc_NtkIsAcyclicHierarchy( pNtk ) )
218  {
219  fprintf( stdout, "NetworkCheck: Network hierarchical dependences contains a cycle.\n" );
220  return 0;
221  }
222  }
223 */
224  return 1;
225 }
226 
227 /**Function*************************************************************
228 
229  Synopsis [Checks the names.]
230 
231  Description []
232 
233  SideEffects []
234 
235  SeeAlso []
236 
237 ***********************************************************************/
239 {
240  Abc_Obj_t * pObj = NULL; // Ensure pObj isn't used uninitialized.
241  Vec_Int_t * vNameIds;
242  char * pName;
243  int i, NameId;
244 
245  if ( Abc_NtkIsNetlist(pNtk) )
246  return 1;
247 
248  // check that each CI/CO has a name
249  Abc_NtkForEachCi( pNtk, pObj, i )
250  {
251  pObj = Abc_ObjFanout0Ntk(pObj);
252  if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) == NULL )
253  {
254  fprintf( stdout, "NetworkCheck: CI with ID %d is in the network but not in the name table.\n", pObj->Id );
255  return 0;
256  }
257  }
258  Abc_NtkForEachCo( pNtk, pObj, i )
259  {
260  pObj = Abc_ObjFanin0Ntk(pObj);
261  if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) == NULL )
262  {
263  fprintf( stdout, "NetworkCheck: CO with ID %d is in the network but not in the name table.\n", pObj->Id );
264  return 0;
265  }
266  }
267 
268  assert(pObj); // pObj should point to something here.
269 
270  // return the array of all IDs, which have names
271  vNameIds = Nm_ManReturnNameIds( pNtk->pManName );
272  // make sure that these IDs correspond to live objects
273  Vec_IntForEachEntry( vNameIds, NameId, i )
274  {
275  if ( Vec_PtrEntry( pNtk->vObjs, NameId ) == NULL )
276  {
277  Vec_IntFree( vNameIds );
278  pName = Nm_ManFindNameById(pObj->pNtk->pManName, NameId);
279  fprintf( stdout, "NetworkCheck: Object with ID %d is deleted but its name \"%s\" remains in the name table.\n", NameId, pName );
280  return 0;
281  }
282  }
283  Vec_IntFree( vNameIds );
284 
285  // make sure the CI names are unique
286  if ( !Abc_NtkCheckUniqueCiNames(pNtk) )
287  return 0;
288 
289  // make sure the CO names are unique
290  if ( !Abc_NtkCheckUniqueCoNames(pNtk) )
291  return 0;
292 
293  // make sure that if a CO has the same name as a CI, they point directly
294  if ( !Abc_NtkCheckUniqueCioNames(pNtk) )
295  return 0;
296 
297  return 1;
298 }
299 
300 
301 /**Function*************************************************************
302 
303  Synopsis [Checks the PIs of the network.]
304 
305  Description []
306 
307  SideEffects []
308 
309  SeeAlso []
310 
311 ***********************************************************************/
313 {
314  Abc_Obj_t * pObj;
315  int i;
316 
317  // check that PIs are indeed PIs
318  Abc_NtkForEachPi( pNtk, pObj, i )
319  {
320  if ( !Abc_ObjIsPi(pObj) )
321  {
322  fprintf( stdout, "NetworkCheck: Object \"%s\" (id=%d) is in the PI list but is not a PI.\n", Abc_ObjName(pObj), pObj->Id );
323  return 0;
324  }
325  if ( pObj->pData )
326  {
327  fprintf( stdout, "NetworkCheck: A PI \"%s\" has a logic function.\n", Abc_ObjName(pObj) );
328  return 0;
329  }
330  if ( Abc_ObjFaninNum(pObj) > 0 )
331  {
332  fprintf( stdout, "NetworkCheck: A PI \"%s\" has fanins.\n", Abc_ObjName(pObj) );
333  return 0;
334  }
335  pObj->pCopy = (Abc_Obj_t *)1;
336  }
337  Abc_NtkForEachObj( pNtk, pObj, i )
338  {
339  if ( pObj->pCopy == NULL && Abc_ObjIsPi(pObj) )
340  {
341  fprintf( stdout, "NetworkCheck: Object \"%s\" (id=%d) is a PI but is not in the PI list.\n", Abc_ObjName(pObj), pObj->Id );
342  return 0;
343  }
344  pObj->pCopy = NULL;
345  }
346  return 1;
347 }
348 
349 /**Function*************************************************************
350 
351  Synopsis [Checks the POs of the network.]
352 
353  Description []
354 
355  SideEffects []
356 
357  SeeAlso []
358 
359 ***********************************************************************/
361 {
362  Abc_Obj_t * pObj;
363  int i;
364 
365  // check that POs are indeed POs
366  Abc_NtkForEachPo( pNtk, pObj, i )
367  {
368  if ( !Abc_ObjIsPo(pObj) )
369  {
370  fprintf( stdout, "NetworkCheck: Net \"%s\" (id=%d) is in the PO list but is not a PO.\n", Abc_ObjName(pObj), pObj->Id );
371  return 0;
372  }
373  if ( pObj->pData )
374  {
375  fprintf( stdout, "NetworkCheck: A PO \"%s\" has a logic function.\n", Abc_ObjName(pObj) );
376  return 0;
377  }
378  if ( Abc_ObjFaninNum(pObj) != 1 )
379  {
380  fprintf( stdout, "NetworkCheck: A PO \"%s\" does not have one fanin (but %d).\n", Abc_ObjName(pObj), Abc_ObjFaninNum(pObj) );
381  return 0;
382  }
383  if ( Abc_ObjFanoutNum(pObj) > 0 )
384  {
385  fprintf( stdout, "NetworkCheck: A PO \"%s\" has %d fanout(s).\n", Abc_ObjName(pObj), Abc_ObjFanoutNum(pObj) );
386  return 0;
387  }
388  pObj->pCopy = (Abc_Obj_t *)1;
389  }
390  Abc_NtkForEachObj( pNtk, pObj, i )
391  {
392  if ( pObj->pCopy == NULL && Abc_ObjIsPo(pObj) )
393  {
394  fprintf( stdout, "NetworkCheck: Net \"%s\" (id=%d) is in a PO but is not in the PO list.\n", Abc_ObjName(pObj), pObj->Id );
395  return 0;
396  }
397  pObj->pCopy = NULL;
398  }
399  return 1;
400 }
401 
402 
403 /**Function*************************************************************
404 
405  Synopsis [Checks the connectivity of the object.]
406 
407  Description []
408 
409  SideEffects []
410 
411  SeeAlso []
412 
413 ***********************************************************************/
414 int Abc_NtkCheckObj( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
415 {
416  Abc_Obj_t * pFanin, * pFanout;
417  int Value = 1;
418  int i, k;
419 
420  // check the network
421  if ( pObj->pNtk != pNtk )
422  {
423  fprintf( stdout, "NetworkCheck: Object \"%s\" does not belong to the network.\n", Abc_ObjName(pObj) );
424  return 0;
425  }
426  // check the object ID
427  if ( pObj->Id < 0 || (int)pObj->Id >= Abc_NtkObjNumMax(pNtk) )
428  {
429  fprintf( stdout, "NetworkCheck: Object \"%s\" has incorrect ID.\n", Abc_ObjName(pObj) );
430  return 0;
431  }
432 
433  if ( !Abc_FrameIsFlagEnabled("checkfio") )
434  return Value;
435 
436  // go through the fanins of the object and make sure fanins have this object as a fanout
437  Abc_ObjForEachFanin( pObj, pFanin, i )
438  {
439  if ( Vec_IntFind( &pFanin->vFanouts, pObj->Id ) == -1 )
440  {
441  fprintf( stdout, "NodeCheck: Object \"%s\" has fanin ", Abc_ObjName(pObj) );
442  fprintf( stdout, "\"%s\" but the fanin does not have it as a fanout.\n", Abc_ObjName(pFanin) );
443  Value = 0;
444  }
445  }
446  // go through the fanouts of the object and make sure fanouts have this object as a fanin
447  Abc_ObjForEachFanout( pObj, pFanout, i )
448  {
449  if ( Vec_IntFind( &pFanout->vFanins, pObj->Id ) == -1 )
450  {
451  fprintf( stdout, "NodeCheck: Object \"%s\" has fanout ", Abc_ObjName(pObj) );
452  fprintf( stdout, "\"%s\" but the fanout does not have it as a fanin.\n", Abc_ObjName(pFanout) );
453  Value = 0;
454  }
455  }
456 
457  // make sure fanins are not duplicated
458  for ( i = 0; i < pObj->vFanins.nSize; i++ )
459  for ( k = i + 1; k < pObj->vFanins.nSize; k++ )
460  if ( pObj->vFanins.pArray[k] == pObj->vFanins.pArray[i] )
461  {
462  printf( "Warning: Node %s has", Abc_ObjName(pObj) );
463  printf( " duplicated fanin %s.\n", Abc_ObjName(Abc_ObjFanin(pObj,k)) );
464  }
465 
466  // save time: do not check large fanout lists
467  if ( pObj->vFanouts.nSize > 100 )
468  return Value;
469 
470  // make sure fanouts are not duplicated
471  for ( i = 0; i < pObj->vFanouts.nSize; i++ )
472  for ( k = i + 1; k < pObj->vFanouts.nSize; k++ )
473  if ( pObj->vFanouts.pArray[k] == pObj->vFanouts.pArray[i] )
474  {
475  printf( "Warning: Node %s has", Abc_ObjName(pObj) );
476  printf( " duplicated fanout %s.\n", Abc_ObjName(Abc_ObjFanout(pObj,k)) );
477  }
478 
479  return Value;
480 }
481 
482 /**Function*************************************************************
483 
484  Synopsis [Checks the integrity of a net.]
485 
486  Description []
487 
488  SideEffects []
489 
490  SeeAlso []
491 
492 ***********************************************************************/
493 int Abc_NtkCheckNet( Abc_Ntk_t * pNtk, Abc_Obj_t * pNet )
494 {
495  if ( Abc_ObjFaninNum(pNet) == 0 )
496  {
497  fprintf( stdout, "NetworkCheck: Net \"%s\" is not driven.\n", Abc_ObjName(pNet) );
498  return 0;
499  }
500  if ( Abc_ObjFaninNum(pNet) > 1 )
501  {
502  fprintf( stdout, "NetworkCheck: Net \"%s\" has more than one driver.\n", Abc_ObjName(pNet) );
503  return 0;
504  }
505  return 1;
506 }
507 
508 /**Function*************************************************************
509 
510  Synopsis [Checks the integrity of a node.]
511 
512  Description []
513 
514  SideEffects []
515 
516  SeeAlso []
517 
518 ***********************************************************************/
519 int Abc_NtkCheckNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode )
520 {
521  // detect internal nodes that do not have nets
522  if ( Abc_NtkIsNetlist(pNtk) && Abc_ObjFanoutNum(pNode) == 0 )
523  {
524  fprintf( stdout, "Node (id = %d) has no net to drive.\n", pNode->Id );
525  return 0;
526  }
527  // the node should have a function assigned unless it is an AIG
528  if ( pNode->pData == NULL )
529  {
530  if ( Abc_ObjIsBarBuf(pNode) )
531  return 1;
532  fprintf( stdout, "NodeCheck: An internal node \"%s\" does not have a logic function.\n", Abc_ObjNameNet(pNode) );
533  return 0;
534  }
535  // the netlist and SOP logic network should have SOPs
536  if ( Abc_NtkHasSop(pNtk) )
537  {
538  if ( !Abc_SopCheck( (char *)pNode->pData, Abc_ObjFaninNum(pNode) ) )
539  {
540  fprintf( stdout, "NodeCheck: SOP check for node \"%s\" has failed.\n", Abc_ObjNameNet(pNode) );
541  return 0;
542  }
543  }
544  else if ( Abc_NtkHasBdd(pNtk) )
545  {
546  int nSuppSize = Cudd_SupportSize((DdManager *)pNtk->pManFunc, (DdNode *)pNode->pData);
547  if ( nSuppSize > Abc_ObjFaninNum(pNode) )
548  {
549  fprintf( stdout, "NodeCheck: BDD of the node \"%s\" has incorrect support size.\n", Abc_ObjNameNet(pNode) );
550  return 0;
551  }
552  }
553  else if ( !Abc_NtkHasMapping(pNtk) && !Abc_NtkHasBlifMv(pNtk) && !Abc_NtkHasAig(pNtk) )
554  {
555  assert( 0 );
556  }
557  return 1;
558 }
559 
560 /**Function*************************************************************
561 
562  Synopsis [Checks the integrity of a latch.]
563 
564  Description []
565 
566  SideEffects []
567 
568  SeeAlso []
569 
570 ***********************************************************************/
571 int Abc_NtkCheckLatch( Abc_Ntk_t * pNtk, Abc_Obj_t * pLatch )
572 {
573  int Value = 1;
574  // check whether the object is a latch
575  if ( !Abc_ObjIsLatch(pLatch) )
576  {
577  fprintf( stdout, "NodeCheck: Latch \"%s\" is in a latch list but is not a latch.\n", Abc_ObjName(pLatch) );
578  Value = 0;
579  }
580  // make sure the latch has a reasonable return value
581  if ( (int)(ABC_PTRINT_T)pLatch->pData < ABC_INIT_ZERO || (int)(ABC_PTRINT_T)pLatch->pData > ABC_INIT_DC )
582  {
583  fprintf( stdout, "NodeCheck: Latch \"%s\" has incorrect reset value (%d).\n",
584  Abc_ObjName(pLatch), (int)(ABC_PTRINT_T)pLatch->pData );
585  Value = 0;
586  }
587  // make sure the latch has only one fanin
588  if ( Abc_ObjFaninNum(pLatch) != 1 )
589  {
590  fprintf( stdout, "NodeCheck: Latch \"%s\" has wrong number (%d) of fanins.\n", Abc_ObjName(pLatch), Abc_ObjFaninNum(pLatch) );
591  Value = 0;
592  }
593  // make sure the latch has only one fanout
594  if ( Abc_ObjFanoutNum(pLatch) != 1 )
595  {
596  fprintf( stdout, "NodeCheck: Latch \"%s\" has wrong number (%d) of fanouts.\n", Abc_ObjName(pLatch), Abc_ObjFanoutNum(pLatch) );
597  Value = 0;
598  }
599  // make sure the latch input has only one fanin
600  if ( Abc_ObjFaninNum(Abc_ObjFanin0(pLatch)) != 1 )
601  {
602  fprintf( stdout, "NodeCheck: Input of latch \"%s\" has wrong number (%d) of fanins.\n",
604  Value = 0;
605  }
606  // make sure the latch input has only one fanout
607  if ( Abc_ObjFanoutNum(Abc_ObjFanin0(pLatch)) != 1 )
608  {
609  fprintf( stdout, "NodeCheck: Input of latch \"%s\" has wrong number (%d) of fanouts.\n",
611  Value = 0;
612  }
613  // make sure the latch output has only one fanin
614  if ( Abc_ObjFaninNum(Abc_ObjFanout0(pLatch)) != 1 )
615  {
616  fprintf( stdout, "NodeCheck: Output of latch \"%s\" has wrong number (%d) of fanins.\n",
618  Value = 0;
619  }
620  return Value;
621 }
622 
623 
624 
625 
626 /**Function*************************************************************
627 
628  Synopsis [Compares the PIs of the two networks.]
629 
630  Description []
631 
632  SideEffects []
633 
634  SeeAlso []
635 
636 ***********************************************************************/
637 int Abc_NtkComparePis( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
638 {
639  Abc_Obj_t * pObj1;
640  int i;
641  if ( Abc_NtkPiNum(pNtk1) != Abc_NtkPiNum(pNtk2) )
642  {
643  printf( "Networks have different number of primary inputs.\n" );
644  return 0;
645  }
646  // for each PI of pNet1 find corresponding PI of pNet2 and reorder them
647  Abc_NtkForEachPi( pNtk1, pObj1, i )
648  {
649  if ( strcmp( Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkPi(pNtk2,i)) ) != 0 )
650  {
651  printf( "Primary input #%d is different in network 1 ( \"%s\") and in network 2 (\"%s\").\n",
652  i, Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkPi(pNtk2,i)) );
653  return 0;
654  }
655  }
656  return 1;
657 }
658 
659 /**Function*************************************************************
660 
661  Synopsis [Compares the POs of the two networks.]
662 
663  Description []
664 
665  SideEffects []
666 
667  SeeAlso []
668 
669 ***********************************************************************/
670 int Abc_NtkComparePos( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
671 {
672  Abc_Obj_t * pObj1;
673  int i;
674  if ( Abc_NtkPoNum(pNtk1) != Abc_NtkPoNum(pNtk2) )
675  {
676  printf( "Networks have different number of primary outputs.\n" );
677  return 0;
678  }
679  // for each PO of pNet1 find corresponding PO of pNet2 and reorder them
680  Abc_NtkForEachPo( pNtk1, pObj1, i )
681  {
682  if ( strcmp( Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkPo(pNtk2,i)) ) != 0 )
683  {
684  printf( "Primary output #%d is different in network 1 ( \"%s\") and in network 2 (\"%s\").\n",
685  i, Abc_ObjName(pObj1), Abc_ObjName(Abc_NtkPo(pNtk2,i)) );
686  return 0;
687  }
688  }
689  return 1;
690 }
691 
692 /**Function*************************************************************
693 
694  Synopsis [Compares the latches of the two networks.]
695 
696  Description []
697 
698  SideEffects []
699 
700  SeeAlso []
701 
702 ***********************************************************************/
703 int Abc_NtkCompareBoxes( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fComb )
704 {
705  Abc_Obj_t * pObj1;
706  int i;
709  if ( !fComb )
710  return 1;
711  if ( Abc_NtkBoxNum(pNtk1) != Abc_NtkBoxNum(pNtk2) )
712  {
713  printf( "Networks have different number of latches.\n" );
714  return 0;
715  }
716  // for each PI of pNet1 find corresponding PI of pNet2 and reorder them
717  Abc_NtkForEachBox( pNtk1, pObj1, i )
718  {
719  if ( strcmp( Abc_ObjName(Abc_ObjFanout0(pObj1)), Abc_ObjName(Abc_ObjFanout0(Abc_NtkBox(pNtk2,i))) ) != 0 )
720  {
721  printf( "Box #%d is different in network 1 ( \"%s\") and in network 2 (\"%s\").\n",
723  return 0;
724  }
725  }
726  return 1;
727 }
728 
729 /**Function*************************************************************
730 
731  Synopsis [Compares the signals of the networks.]
732 
733  Description []
734 
735  SideEffects [Ordering POs by name is a very bad idea! It destroys
736  the natural order of the logic in the circuit.]
737 
738  SeeAlso []
739 
740 ***********************************************************************/
741 int Abc_NtkCompareSignals( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fOnlyPis, int fComb )
742 {
743  Abc_NtkOrderObjsByName( pNtk1, fComb );
744  Abc_NtkOrderObjsByName( pNtk2, fComb );
745  if ( !Abc_NtkComparePis( pNtk1, pNtk2, fComb ) )
746  return 0;
747  if ( !fOnlyPis )
748  {
749  if ( !Abc_NtkCompareBoxes( pNtk1, pNtk2, fComb ) )
750  return 0;
751  if ( !Abc_NtkComparePos( pNtk1, pNtk2, fComb ) )
752  return 0;
753  }
754  return 1;
755 }
756 
757 /**Function*************************************************************
758 
759  Synopsis [Returns 0 if the network hierachy contains a cycle.]
760 
761  Description []
762 
763  SideEffects []
764 
765  SeeAlso []
766 
767 ***********************************************************************/
769 {
770  Abc_Ntk_t * pNtkNext;
771  Abc_Obj_t * pObj;
772  int i;
773  // return if visited
774  if ( pNtk->fHieVisited )
775  return 1;
776  pNtk->fHieVisited = 1;
777  // return if black box
778  if ( Abc_NtkHasBlackbox(pNtk) )
779  return 1;
780  assert( Abc_NtkIsNetlist(pNtk) );
781  // go through all the children networks
782  Abc_NtkForEachBox( pNtk, pObj, i )
783  {
784  if ( Abc_ObjIsLatch(pObj) )
785  continue;
786  pNtkNext = (Abc_Ntk_t *)pObj->pData;
787  assert( pNtkNext != NULL );
788  if ( pNtkNext->fHiePath )
789  return 0;
790  pNtk->fHiePath = 1;
791  if ( !Abc_NtkIsAcyclicHierarchy_rec( pNtkNext ) )
792  return 0;
793  pNtk->fHiePath = 0;
794  }
795  return 1;
796 }
797 
798 /**Function*************************************************************
799 
800  Synopsis [Returns 0 if the network hierachy contains a cycle.]
801 
802  Description []
803 
804  SideEffects []
805 
806  SeeAlso []
807 
808 ***********************************************************************/
810 {
811  Abc_Ntk_t * pTemp;
812  int i, RetValue;
813  assert( Abc_NtkIsNetlist(pNtk) && pNtk->pDesign );
814  // clear the modules
815  Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pTemp, i )
816  pTemp->fHieVisited = pTemp->fHiePath = 0;
817  // traverse
818  pNtk->fHiePath = 1;
819  RetValue = Abc_NtkIsAcyclicHierarchy_rec( pNtk );
820  pNtk->fHiePath = 0;
821  // clear the modules
822  Vec_PtrForEachEntry( Abc_Ntk_t *, pNtk->pDesign->vModules, pTemp, i )
823  pTemp->fHieVisited = pTemp->fHiePath = 0;
824  return RetValue;
825 }
826 
827 /**Function*************************************************************
828 
829  Synopsis [Returns 0 if CI names are repeated.]
830 
831  Description []
832 
833  SideEffects []
834 
835  SeeAlso []
836 
837 ***********************************************************************/
838 int Abc_NtkNamesCompare( char ** pName1, char ** pName2 )
839 {
840  return strcmp( *pName1, *pName2 );
841 }
842 
843 /**Function*************************************************************
844 
845  Synopsis [Returns 0 if CI names are repeated.]
846 
847  Description []
848 
849  SideEffects []
850 
851  SeeAlso []
852 
853 ***********************************************************************/
855 {
856  Vec_Ptr_t * vNames;
857  Abc_Obj_t * pObj;
858  int i, fRetValue = 1;
859  assert( !Abc_NtkIsNetlist(pNtk) );
860  vNames = Vec_PtrAlloc( Abc_NtkCiNum(pNtk) );
861  Abc_NtkForEachCi( pNtk, pObj, i )
862  Vec_PtrPush( vNames, Abc_ObjName(pObj) );
863  Vec_PtrSort( vNames, (int (*)())Abc_NtkNamesCompare );
864  for ( i = 1; i < Abc_NtkCiNum(pNtk); i++ )
865  if ( !strcmp( (const char *)Vec_PtrEntry(vNames,i-1), (const char *)Vec_PtrEntry(vNames,i) ) )
866  {
867  printf( "Abc_NtkCheck: Repeated CI names: %s and %s.\n", (char*)Vec_PtrEntry(vNames,i-1), (char*)Vec_PtrEntry(vNames,i) );
868  fRetValue = 0;
869  }
870  Vec_PtrFree( vNames );
871  return fRetValue;
872 }
873 
874 /**Function*************************************************************
875 
876  Synopsis [Returns 0 if CO names are repeated.]
877 
878  Description []
879 
880  SideEffects []
881 
882  SeeAlso []
883 
884 ***********************************************************************/
886 {
887  Vec_Ptr_t * vNames;
888  Abc_Obj_t * pObj;
889  int i, fRetValue = 1;
890  assert( !Abc_NtkIsNetlist(pNtk) );
891  vNames = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) );
892  Abc_NtkForEachCo( pNtk, pObj, i )
893  Vec_PtrPush( vNames, Abc_ObjName(pObj) );
894  Vec_PtrSort( vNames, (int (*)())Abc_NtkNamesCompare );
895  for ( i = 1; i < Abc_NtkCoNum(pNtk); i++ )
896  {
897 // printf( "%s\n", Vec_PtrEntry(vNames,i) );
898  if ( !strcmp( (const char *)Vec_PtrEntry(vNames,i-1), (const char *)Vec_PtrEntry(vNames,i) ) )
899  {
900  printf( "Abc_NtkCheck: Repeated CO names: %s and %s.\n", (char*)Vec_PtrEntry(vNames,i-1), (char*)Vec_PtrEntry(vNames,i) );
901  fRetValue = 0;
902  }
903  }
904  Vec_PtrFree( vNames );
905  return fRetValue;
906 }
907 
908 /**Function*************************************************************
909 
910  Synopsis [Returns 0 if there is a pair of CI/CO with the same name and logic in between.]
911 
912  Description []
913 
914  SideEffects []
915 
916  SeeAlso []
917 
918 ***********************************************************************/
920 {
921  Abc_Obj_t * pObj, * pObjCi, * pFanin;
922  int i, nCiId, fRetValue = 1;
923  assert( !Abc_NtkIsNetlist(pNtk) );
924  Abc_NtkForEachCo( pNtk, pObj, i )
925  {
927  if ( nCiId == -1 )
928  continue;
929  pObjCi = Abc_NtkObj( pNtk, nCiId );
930  assert( !strcmp( Abc_ObjName(pObj), Abc_ObjName(pObjCi) ) );
931  pFanin = Abc_ObjFanin0(pObj);
932  if ( pFanin != pObjCi )
933  {
934  printf( "Abc_NtkCheck: A CI/CO pair share the name (%s) but do not link directly. The name of the CO fanin is %s.\n",
935  Abc_ObjName(pObj), Abc_ObjName(Abc_ObjFanin0(pObj)) );
936  fRetValue = 0;
937  }
938  }
939  return fRetValue;
940 }
941 
942 ////////////////////////////////////////////////////////////////////////
943 /// END OF FILE ///
944 ////////////////////////////////////////////////////////////////////////
945 
946 
948 
static int Abc_NtkIsStrash(Abc_Ntk_t *pNtk)
Definition: abc.h:251
static int Abc_NtkIsLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:250
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
static int Abc_NtkHasBdd(Abc_Ntk_t *pNtk)
Definition: abc.h:254
ABC_DLL void * Abc_FrameReadLibGen()
Definition: mainFrame.c:56
ABC_DLL int Abc_NtkIsAcyclic(Abc_Ntk_t *pNtk)
Definition: abcDfs.c:1422
static int Abc_NtkHasSop(Abc_Ntk_t *pNtk)
Definition: abc.h:253
ABC_DLL int Abc_SopCheck(char *pSop, int nFanins)
Definition: abcSop.c:823
Nm_Man_t * pManName
Definition: abc.h:160
Definition: cudd.h:278
static int Abc_NtkObjNumMax(Abc_Ntk_t *pNtk)
Definition: abc.h:284
Abc_Ntk_t * pExdc
Definition: abc.h:201
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition: bblif.c:37
static int Abc_NtkIsNetlist(Abc_Ntk_t *pNtk)
Definition: abc.h:249
ABC_DLL int Abc_AigCheck(Abc_Aig_t *pMan)
Definition: abcAig.c:226
static int Abc_ObjIsLatch(Abc_Obj_t *pObj)
Definition: abc.h:356
static int Abc_ObjFanoutNum(Abc_Obj_t *pObj)
Definition: abc.h:365
static int Abc_NtkBoxNum(Abc_Ntk_t *pNtk)
Definition: abc.h:289
static Abc_Obj_t * Abc_ObjFanin0Ntk(Abc_Obj_t *pObj)
Definition: abc.h:375
static int Abc_NtkCheckPos(Abc_Ntk_t *pNtk)
Definition: abcCheck.c:360
static int Abc_ObjFaninNum(Abc_Obj_t *pObj)
Definition: abc.h:364
static int Abc_ObjIsBarBuf(Abc_Obj_t *pObj)
Definition: abc.h:360
static int Abc_NtkHasMapping(Abc_Ntk_t *pNtk)
Definition: abc.h:256
int Abc_NtkCheckUniqueCioNames(Abc_Ntk_t *pNtk)
Definition: abcCheck.c:919
static void Vec_PtrSort(Vec_Ptr_t *p, int(*Vec_PtrSortCompare)()) ___unused
Definition: vecPtr.h:851
static int Abc_NtkLatchNum(Abc_Ntk_t *pNtk)
Definition: abc.h:294
static int Abc_ObjIsPi(Abc_Obj_t *pObj)
Definition: abc.h:347
static int Vec_IntFind(Vec_Int_t *p, int Entry)
Definition: vecInt.h:895
Vec_Int_t vFanins
Definition: abc.h:143
int Abc_NtkNamesCompare(char **pName1, char **pName2)
Definition: abcCheck.c:838
static void Vec_PtrPush(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:606
static int Abc_NtkCiNum(Abc_Ntk_t *pNtk)
Definition: abc.h:287
#define Abc_NtkForEachCo(pNtk, pCo, i)
Definition: abc.h:519
Vec_Ptr_t * vObjs
Definition: abc.h:162
Vec_Int_t * Nm_ManReturnNameIds(Nm_Man_t *p)
Definition: nmApi.c:261
static int Abc_NtkHasBlifMv(Abc_Ntk_t *pNtk)
Definition: abc.h:257
static Abc_Obj_t * Abc_NtkObj(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:314
static Abc_Obj_t * Abc_ObjFanin0(Abc_Obj_t *pObj)
Definition: abc.h:373
static int Abc_NtkCoNum(Abc_Ntk_t *pNtk)
Definition: abc.h:288
DECLARATIONS ///.
Definition: abcAig.c:52
static int Abc_NtkComparePos(Abc_Ntk_t *pNtk1, Abc_Ntk_t *pNtk2, int fComb)
Definition: abcCheck.c:670
static int Abc_NtkComparePis(Abc_Ntk_t *pNtk1, Abc_Ntk_t *pNtk2, int fComb)
Definition: abcCheck.c:637
int strcmp()
int Abc_NtkCheckUniqueCiNames(Abc_Ntk_t *pNtk)
Definition: abcCheck.c:854
void * pManFunc
Definition: abc.h:191
static int Abc_ObjIsNode(Abc_Obj_t *pObj)
Definition: abc.h:355
static int Abc_NtkCompareLatches(Abc_Ntk_t *pNtk1, Abc_Ntk_t *pNtk2, int fComb)
Abc_Obj_t * pCopy
Definition: abc.h:148
int Abc_NtkIsAcyclicHierarchy(Abc_Ntk_t *pNtk)
Definition: abcCheck.c:809
static int Abc_NtkHasBlackbox(Abc_Ntk_t *pNtk)
Definition: abc.h:258
static char * Abc_ObjNameNet(Abc_Obj_t *pObj)
Definition: abcCheck.c:44
int Nm_ManFindIdByNameTwoTypes(Nm_Man_t *p, char *pName, int Type1, int Type2)
Definition: nmApi.c:239
int Abc_NtkCheckUniqueCoNames(Abc_Ntk_t *pNtk)
Definition: abcCheck.c:885
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
char * Nm_ManFindNameById(Nm_Man_t *p, int ObjId)
Definition: nmApi.c:199
int Abc_NtkCheckRead(Abc_Ntk_t *pNtk)
Definition: abcCheck.c:77
static int Abc_NtkCheckNet(Abc_Ntk_t *pNtk, Abc_Obj_t *pNet)
Definition: abcCheck.c:493
#define Abc_NtkForEachNet(pNtk, pNet, i)
Definition: abc.h:458
#define Abc_NtkForEachLatch(pNtk, pObj, i)
Definition: abc.h:497
static Abc_Obj_t * Abc_ObjFanout0Ntk(Abc_Obj_t *pObj)
Definition: abc.h:376
#define Abc_NtkForEachBox(pNtk, pObj, i)
Definition: abc.h:495
static ABC_NAMESPACE_IMPL_START int Abc_NtkCheckNames(Abc_Ntk_t *pNtk)
DECLARATIONS ///.
Definition: abcCheck.c:238
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition: abc.h:461
static Abc_Obj_t * Abc_NtkBox(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:319
int Abc_NtkCheck(Abc_Ntk_t *pNtk)
FUNCTION DEFINITIONS ///.
Definition: abcCheck.c:61
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
Vec_Int_t vFanouts
Definition: abc.h:144
static void * Vec_PtrEntry(Vec_Ptr_t *p, int i)
Definition: vecPtr.h:362
Abc_Ntk_t * pNtk
Definition: abc.h:130
static int Abc_NtkCheckPis(Abc_Ntk_t *pNtk)
Definition: abcCheck.c:312
Definition: abc.h:89
int Abc_NtkCheckObj(Abc_Ntk_t *pNtk, Abc_Obj_t *pObj)
Definition: abcCheck.c:414
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition: abc.h:526
static Abc_Obj_t * Abc_NtkPo(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:316
#define Abc_NtkForEachCi(pNtk, pCi, i)
Definition: abc.h:515
static int Abc_NtkPoNum(Abc_Ntk_t *pNtk)
Definition: abc.h:286
static Vec_Ptr_t * Vec_PtrAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecPtr.h:83
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition: abc.h:524
int Id
Definition: abc.h:132
static int Abc_NtkPiNum(Abc_Ntk_t *pNtk)
Definition: abc.h:285
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition: abcNames.c:48
static int Abc_NtkCheckNode(Abc_Ntk_t *pNtk, Abc_Obj_t *pNode)
Definition: abcCheck.c:519
ABC_DLL int Abc_FrameIsFlagEnabled(char *pFlag)
Definition: mainFrame.c:113
static int Abc_NtkHasOnlyLatchBoxes(Abc_Ntk_t *pNtk)
Definition: abc.h:298
static int Abc_ObjIsPo(Abc_Obj_t *pObj)
Definition: abc.h:348
Definition: abc.h:92
ABC_DLL void Abc_NtkCleanCopy(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:507
Vec_Ptr_t * vModules
Definition: abc.h:223
int Abc_NtkCompareBoxes(Abc_Ntk_t *pNtk1, Abc_Ntk_t *pNtk2, int fComb)
Definition: abcCheck.c:703
#define assert(ex)
Definition: util_old.h:213
static int Abc_NtkHasAig(Abc_Ntk_t *pNtk)
Definition: abc.h:255
int Abc_NtkIsAcyclicHierarchy_rec(Abc_Ntk_t *pNtk)
Definition: abcCheck.c:768
static int Abc_NtkCheckLatch(Abc_Ntk_t *pNtk, Abc_Obj_t *pLatch)
Definition: abcCheck.c:571
static Abc_Obj_t * Abc_NtkPi(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:315
void * pData
Definition: abc.h:145
int Abc_NtkDoCheck(Abc_Ntk_t *pNtk)
Definition: abcCheck.c:93
#define Abc_NtkForEachPo(pNtk, pPo, i)
Definition: abc.h:517
static Abc_Obj_t * Abc_ObjFanout(Abc_Obj_t *pObj, int i)
Definition: abc.h:370
static Abc_Obj_t * Abc_ObjFanin(Abc_Obj_t *pObj, int i)
Definition: abc.h:372
static void Vec_IntFree(Vec_Int_t *p)
Definition: bblif.c:235
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition: vecPtr.h:55
Abc_Des_t * pDesign
Definition: abc.h:180
#define Abc_NtkForEachObj(pNtk, pObj, i)
ITERATORS ///.
Definition: abc.h:446
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition: vecInt.h:54
int Cudd_SupportSize(DdManager *dd, DdNode *f)
Definition: cuddUtil.c:857
int Abc_NtkCompareSignals(Abc_Ntk_t *pNtk1, Abc_Ntk_t *pNtk2, int fOnlyPis, int fComb)
Definition: abcCheck.c:741
ABC_DLL void Abc_NtkOrderObjsByName(Abc_Ntk_t *pNtk, int fComb)
Definition: abcNames.c:335
int fHiePath
Definition: abc.h:183
int fHieVisited
Definition: abc.h:182
static Abc_Obj_t * Abc_ObjFanout0(Abc_Obj_t *pObj)
Definition: abc.h:371
#define Abc_NtkForEachPi(pNtk, pPi, i)
Definition: abc.h:513
static int Abc_NtkNetNum(Abc_Ntk_t *pNtk)
Definition: abc.h:292
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223