source: vis_dev/vis-2.3/src/ntk/ntkNtk.c @ 40

Last change on this file since 40 was 40, checked in by cecile, 13 years ago

abnormal structure in network

File size: 55.0 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [ntkNtk.c]
4
5  PackageName [ntk]
6
7  Synopsis    [Routines to access the network data structure.]
8
9  Author      [Adnan Aziz, Tom Shiple]
10
11  Copyright   [Copyright (c) 1994-1996 The Regents of the Univ. of California.
12  All rights reserved.
13
14  Permission is hereby granted, without written agreement and without license
15  or royalty fees, to use, copy, modify, and distribute this software and its
16  documentation for any purpose, provided that the above copyright notice and
17  the following two paragraphs appear in all copies of this software.
18
19  IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
20  DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
21  OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
22  CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24  THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
25  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
26  FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN
27  "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
28  MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.]
29
30******************************************************************************/
31
32#include "ntkInt.h"
33#include "mdd.h"
34
35static char rcsid[] UNUSED = "$Id: ntkNtk.c,v 1.23 2010/04/09 23:44:05 fabio Exp $";
36
37/*---------------------------------------------------------------------------*/
38/* Structure declarations                                                    */
39/*---------------------------------------------------------------------------*/
40/**Struct**********************************************************************
41
42  Synopsis    [Structure to store uninterpreted application info.]
43
44  SeeAlso     [Ntk_NetworkAddApplInfo]
45
46******************************************************************************/
47typedef struct ApplInfoStruct {
48  Ntk_ApplInfoFreeFn  freeFn;  /* application function to free data */
49  void               *data;    /* application data */
50} ApplInfo_t;
51
52
53/**AutomaticStart*************************************************************/
54
55/*---------------------------------------------------------------------------*/
56/* Static function prototypes                                                */
57/*---------------------------------------------------------------------------*/
58
59static char * NodeReadNameFromTable(Ntk_Node_t *node, st_table *name2ToName1);
60static Tbl_Table_t * DuplicateTableAndVars(Ntk_Node_t *node, char *name);
61
62/**AutomaticEnd***************************************************************/
63
64
65/*---------------------------------------------------------------------------*/
66/* Definition of exported functions                                          */
67/*---------------------------------------------------------------------------*/
68
69/**Function********************************************************************
70
71  Synopsis    [Returns the name of a network.]
72
73  Description [Returns the name of a network.  Every network must have a name. It
74  is an error to call this function on a NULL network.]
75
76  SideEffects []
77
78  SeeAlso     [Ntk_NetworkAlloc]
79
80******************************************************************************/
81char *
82Ntk_NetworkReadName(
83  Ntk_Network_t * network)
84{
85  return (network->name);
86}
87
88
89/**Function********************************************************************
90
91  Synopsis    [Returns the MDD manager of a network.]
92
93  Description [Returns the MDD manager of a network.  The MDD manager is set
94  by calling Ntk_NetworkSetMddManager.  If the application frees the returned
95  MDD manager, then it should in turn set the network's MDD manager pointer to
96  NULL.  If the pointer is non-NULL when Ntk_NetworkFree is called, then the MDD
97  manager will be freed. It is an error to call this function on a NULL
98  network.]
99
100  SideEffects []
101
102  SeeAlso     [Ntk_NetworkSetMddManager Ntk_NetworkInitializeMddManager]
103
104******************************************************************************/
105mdd_manager *
106Ntk_NetworkReadMddManager(
107  Ntk_Network_t * network)
108{
109  return (network->mddManager);
110}
111
112
113/**Function********************************************************************
114
115  Synopsis    [Sets the MDD manager of a network.]
116
117  Description [Sets the MDD manager of a network.  This could be useful, for
118  example, to force two networks to have the same MDD manager.  However, be
119  careful that in the end the manager is only freed once.]
120
121  SideEffects []
122
123  SeeAlso     [Ntk_NetworkReadMddManager Ntk_NetworkInitializeMddManager]
124
125******************************************************************************/
126void
127Ntk_NetworkSetMddManager(
128  Ntk_Network_t  * network,
129  mdd_manager * mddManager)
130{
131  network->mddManager = mddManager;
132}
133
134/**Function********************************************************************
135
136  Synopsis    [Returns the MAig manager of a network.]
137
138  Description [Returns the MAig manager of a network.  The MAig manager is set
139  by calling Ntk_NetworkSetMAigManager.  If the application frees the returned
140  MAig manager, then it should in turn set the network's MAig manager pointer to
141  NULL.  If the pointer is non-NULL when Ntk_NetworkFree is called, then the MAig
142  manager will be freed. It is an error to call this function on a NULL
143  network.]
144
145  SideEffects []
146
147  SeeAlso     [Ntk_NetworkSetMAigManager Ntk_NetworkInitializeMAigManager]
148
149******************************************************************************/
150mAig_Manager_t *
151Ntk_NetworkReadMAigManager(
152  Ntk_Network_t * network)
153{
154  return (network->mAigManager);
155}
156
157
158/**Function********************************************************************
159
160  Synopsis    [Sets the mAig manager of a network and the netowrk for the
161               mAig manager.]
162
163  Description [Sets the MAig manager of a network.  This could be useful, for
164  example, to force two networks to have the same MAig manager.  However, be
165  careful that in the end the manager is only freed once.]
166
167  SideEffects []
168
169  SeeAlso     [Ntk_NetworkReadMAigManager Ntk_NetworkInitializeMAigManager]
170
171******************************************************************************/
172void
173Ntk_NetworkSetMAigManager(
174  Ntk_Network_t * network,
175  mAig_Manager_t * mAigManager)
176{
177  network->mAigManager = mAigManager;
178}
179
180/**Function********************************************************************
181
182  Synopsis    [Creates and initializes an empty MDD manager for a network.]
183
184  Description [Creates and initializes an empty MDD manager for a
185  network. Sets the MDD manager field of the network, and returns a pointer to
186  the newly created manager.]
187
188  SideEffects []
189
190  SeeAlso     [Ntk_NetworkReadMddManager Ntk_NetworkSetMddManager]
191
192******************************************************************************/
193mdd_manager *
194Ntk_NetworkInitializeMddManager(
195  Ntk_Network_t * network)
196{
197  network->mddManager = mdd_init_empty();
198
199  return (network->mddManager);
200}
201
202
203/**Function********************************************************************
204
205  Synopsis    [Returns the dynamic variable ordering method of a network.]
206
207  Description [Returns the dynamic variable ordering method of a network.  The
208  method is set by calling Ntk_NetworkSetDynamicVarOrderingMethod.  The method
209  is set to BDD_REORDER_NONE when the network is first created.  It is an
210  error to call this function on a NULL network.]
211
212  SideEffects []
213
214  SeeAlso     [Ntk_NetworkSetDynamicVarOrderingMethod]
215
216******************************************************************************/
217bdd_reorder_type_t
218Ntk_NetworkReadDynamicVarOrderingMethod(
219  Ntk_Network_t * network)
220{
221  return (network->dynVarOrdMethod);
222}
223
224
225/**Function********************************************************************
226
227  Synopsis    [Sets the dynamic variable ordering method of a network.]
228
229  Description [Sets the dynamic variable ordering method of a
230  network. Allowable values of dynVarOrdMethod are BDD_REORDER_SIFT,
231  BDD_REORDER_WINDOW, and BDD_REORDER_NONE.]
232
233  SideEffects []
234
235  SeeAlso     [Ntk_NetworkReadDynamicVarOrderingMethod]
236
237******************************************************************************/
238void
239Ntk_NetworkSetDynamicVarOrderingMethod(
240  Ntk_Network_t * network,
241  bdd_reorder_type_t dynVarOrdMethod,
242  bdd_reorder_verbosity_t verbosity)
243{
244  bdd_dynamic_reordering(network->mddManager, dynVarOrdMethod, verbosity);
245  if (bdd_get_package_name() != CUDD) {
246    if (dynVarOrdMethod == BDD_REORDER_SIFT ||
247        dynVarOrdMethod == BDD_REORDER_WINDOW ||
248        dynVarOrdMethod == BDD_REORDER_NONE) {
249      network->dynVarOrdMethod = dynVarOrdMethod;
250    } else
251      network->dynVarOrdMethod = BDD_REORDER_SIFT;
252  } else
253    network->dynVarOrdMethod = dynVarOrdMethod;
254}
255
256
257/**Function********************************************************************
258
259  Synopsis    [Returns the undef field of a network.]
260
261  Description [Returns the undef field of a network.  There is no restriction on
262  how this field is used.  It is an error to call this function on a NULL
263  network.]
264
265  SideEffects []
266
267  SeeAlso     [Ntk_NetworkAlloc Ntk_NetworkSetUndef]
268
269******************************************************************************/
270void *
271Ntk_NetworkReadUndef(
272  Ntk_Network_t * network)
273{
274  return (network->undef);
275}
276
277
278/**Function********************************************************************
279
280  Synopsis    [Sets the undef field of a network.]
281
282  Description [Sets the undef field of a network.  There is no restriction on
283  how this field is used.  It is an error to call this function on a NULL
284  network.]
285
286  SideEffects []
287
288  SeeAlso     [Ntk_NetworkAlloc Ntk_NetworkReadUndef]
289
290******************************************************************************/
291void
292Ntk_NetworkSetUndef(
293  Ntk_Network_t * network,
294  void * value)
295{
296  network->undef = value;
297}
298
299
300/**Function********************************************************************
301
302  Synopsis    [Finds a node in a network by its MDD id.]
303
304  Description [Finds a node in a network by its MDD id.  The MDD id of a node
305  is the MDD id returned by Ntk_NodeReadMddId. If the MDD id doesn't
306  correspond to an existing node in the network, a NULL pointer is returned.
307  Also, if MDD id is equal to NTK_UNASSIGNED_MDD_ID, a NULL pointer is
308  returned.]
309
310  SideEffects []
311
312  SeeAlso     [Ntk_NodeSetMddId Ntk_NodeReadMddId]
313
314******************************************************************************/
315Ntk_Node_t *
316Ntk_NetworkFindNodeByMddId(
317  Ntk_Network_t * network,
318  int             mddId)
319{
320  Ntk_Node_t *node = NIL(Ntk_Node_t);
321
322  if (mddId != NTK_UNASSIGNED_MDD_ID) {
323    st_lookup(network->mddIdToNode, (char *) (long) mddId, &node);
324  }
325
326  return (node);
327}
328
329
330/**Function********************************************************************
331
332  Synopsis    [Finds a node in a network by its actual name.]
333
334  Description [Finds a node in a network by its actual name.  The actual name
335  of a node is the name stored with the node (i.e returned by
336  Ntk_NodeReadName). If the name doesn't correspond to an existing node in the
337  network, a NULL pointer is returned.]
338
339  SideEffects []
340
341  SeeAlso     [Ntk_NetworkReadActualNameFromFormalName Ntk_NodeReadName]
342
343******************************************************************************/
344Ntk_Node_t *
345Ntk_NetworkFindNodeByActualName(
346  Ntk_Network_t * network,
347  char * name)
348{
349  Ntk_Node_t *node = NIL(Ntk_Node_t);
350
351  st_lookup(network->actualNameToNode, name, &node);
352
353  return (node);
354}
355
356
357/**Function********************************************************************
358
359  Synopsis    [Finds a node in a network by its formal name, or actual name.]
360
361  Description [Finds a node in a network by its name.  First, the formal name
362  to actual name table is checked to see if there is an actual name
363  corresponding to the name.  If so, then the node corresponding to the actual
364  name is returned.  If there is no corresponding actual name, then it's
365  assumed that the name is an actual name, and the corresponding node is
366  returned.  If no corresponding node is found, then a NULL pointer is
367  returned.]
368
369  SideEffects []
370
371  SeeAlso     [Ntk_NetworkReadActualNameFromFormalName
372  Ntk_NetworkFindNodeByActualName]
373
374******************************************************************************/
375Ntk_Node_t *
376Ntk_NetworkFindNodeByName(
377  Ntk_Network_t * network,
378  char * name)
379{
380  Ntk_Node_t *node = NIL(Ntk_Node_t);
381  char *actualName = Ntk_NetworkReadActualNameFromFormalName(network, name);
382
383  /*
384   * If there was no actual name corresponding to name in the formal to actual
385   * table, then treat name as an actualName.
386   */
387  if (actualName == NIL(char)) {
388    actualName = name;
389  }
390
391  st_lookup(network->actualNameToNode, actualName, &node);
392
393  return (node);
394}
395
396
397/**Function********************************************************************
398
399  Synopsis    [Returns the actual name corresponding to a formal name.]
400
401  Description [Returns the actual name corresponding to a formal name in a
402  network.  The actual name is unique in a network.  Nodes of a network are
403  identified by their actual names. If the formal name doesn't correspond to
404  an actual name in the network, a NULL pointer is returned.]
405
406  SideEffects []
407
408  SeeAlso     [Ntk_NetworkFindNodeByActualName
409  Ntk_NetworkInsertFormalNameToActualName]
410
411******************************************************************************/
412char *
413Ntk_NetworkReadActualNameFromFormalName(
414  Ntk_Network_t * network,
415  char * formalName)
416{
417  char *actualName = NIL(char);
418
419  st_lookup(network->formalNameToActualName, formalName, &actualName);
420
421  return (actualName);
422}
423
424
425/**Function********************************************************************
426
427  Synopsis    [Creates correspondence from formalName to actualName.]
428
429  Description [Creates correspondence from formalName to actualName. Copies
430  are made of formalName and actualName before storing them.]
431
432  SideEffects []
433
434  SeeAlso     [Ntk_NetworkReadActualNameFromFormalName]
435
436******************************************************************************/
437void
438Ntk_NetworkInsertFormalNameToActualName(
439  Ntk_Network_t * network,
440  char * formalName,
441  char * actualName)
442{
443  char *formalNameCopy = util_strsav(formalName);
444  char *actualNameCopy = util_strsav(actualName);
445
446  st_insert(network->formalNameToActualName, formalNameCopy, actualNameCopy);
447}
448
449
450/**Function********************************************************************
451
452  Synopsis    [Returns the number of nodes of a network.]
453
454  SideEffects []
455
456  SeeAlso     [Ntk_NetworkReadNumPrimaryInputs Ntk_NetworkReadNumLatches]
457
458******************************************************************************/
459int
460Ntk_NetworkReadNumNodes(
461  Ntk_Network_t * network)
462{
463  return (lsLength(network->nodes));
464}
465
466
467/**Function********************************************************************
468
469  Synopsis    [Returns the number of latches of a network.]
470
471  SideEffects []
472
473  SeeAlso     [Ntk_NetworkReadNumNodes Ntk_NetworkReadNumPrimaryInputs]
474
475******************************************************************************/
476int
477Ntk_NetworkReadNumLatches(
478  Ntk_Network_t * network)
479{
480  return (lsLength(network->latches));
481}
482
483
484/**Function********************************************************************
485
486  Synopsis    [Returns the number of combinational inputs of a network.]
487
488  SideEffects []
489
490  SeeAlso     [Ntk_NetworkReadNumNodes Ntk_NetworkReadNumLatches]
491
492******************************************************************************/
493int
494Ntk_NetworkReadNumCombInputs(
495  Ntk_Network_t * network)
496{
497  return (lsLength(network->combInputs));
498}
499
500
501/**Function********************************************************************
502
503  Synopsis    [Returns the number of combinational outputs of a network.]
504
505  SideEffects []
506
507  SeeAlso     [Ntk_NetworkReadCombOutputs Ntk_NetworkReadNumNodes
508  Ntk_NetworkReadNumLatches]
509
510******************************************************************************/
511int
512Ntk_NetworkReadNumCombOutputs(
513  Ntk_Network_t * network)
514{
515  return (lsLength(network->combOutputs));
516}
517
518
519/**Function********************************************************************
520
521  Synopsis    [Returns the number of primary inputs of a network.]
522
523  SideEffects []
524
525  SeeAlso     [Ntk_NetworkReadNumPseudoInputs Ntk_NetworkReadNumInputs]
526
527******************************************************************************/
528int
529Ntk_NetworkReadNumPrimaryInputs(
530  Ntk_Network_t * network)
531{
532  return (lsLength(network->primaryInputs));
533}
534
535
536/**Function********************************************************************
537
538  Synopsis    [Returns the number of pseudo inputs of a network.]
539
540  SideEffects []
541
542  SeeAlso     [Ntk_NetworkReadNumPrimaryInputs Ntk_NetworkReadNumInputs]
543
544******************************************************************************/
545int
546Ntk_NetworkReadNumPseudoInputs(
547  Ntk_Network_t * network)
548{
549  return (lsLength(network->pseudoInputs));
550}
551
552
553/**Function********************************************************************
554
555  Synopsis    [Returns the number of inputs (primary plus pseudo) of a network.]
556
557  SideEffects []
558
559  SeeAlso     [Ntk_NetworkReadNumPrimaryInputs Ntk_NetworkReadNumPseudoInputs]
560
561******************************************************************************/
562int
563Ntk_NetworkReadNumInputs(
564  Ntk_Network_t * network)
565{
566  return (lsLength(network->inputs));
567}
568
569
570/**Function********************************************************************
571
572  Synopsis    [Returns the number of primary outputs of a network.]
573
574  SideEffects []
575
576  SeeAlso     [Ntk_NetworkReadNumNodes Ntk_NetworkReadNumLatches]
577
578******************************************************************************/
579int
580Ntk_NetworkReadNumPrimaryOutputs(
581  Ntk_Network_t * network)
582{
583  return (lsLength(network->primaryOutputs));
584}
585
586
587/**Function********************************************************************
588
589  Synopsis    [Returns the list of nodes of a network.]
590
591  Description [Returns the list of all the nodes of a network.  The application
592  must not free or modify this list in any way.]
593
594  SideEffects []
595
596  SeeAlso     [Ntk_NetworkReadNumNodes]
597
598******************************************************************************/
599lsList
600Ntk_NetworkReadNodes(
601  Ntk_Network_t * network)
602{
603  return (network->nodes);
604}
605
606
607/**Function********************************************************************
608
609  Synopsis    [Returns the list of combinational inputs of a network.]
610
611  Description [Returns the list of combinational inputs of a network.  The
612  application must not free or modify this list in any way.]
613
614  SideEffects []
615
616  SeeAlso     [Ntk_NetworkReadNumCombInputs]
617
618******************************************************************************/
619lsList
620Ntk_NetworkReadCombInputs(
621  Ntk_Network_t * network)
622{
623  return (network->combInputs);
624}
625
626
627/**Function********************************************************************
628
629  Synopsis    [Returns the list of combinational outputs of a network.]
630
631  Description [Returns the list of combinational outputs of a network.  A node
632  can appear at most once in this list (e.g. even if a node serves as the data
633  input for more than one latch, it appears just once in this list). The
634  application must not free or modify this list in any way.]
635
636  SideEffects []
637
638  SeeAlso     [Ntk_NetworkReadNumCombOutputs]
639
640******************************************************************************/
641lsList
642Ntk_NetworkReadCombOutputs(
643  Ntk_Network_t * network)
644{
645  return (network->combOutputs);
646}
647
648
649/**Function********************************************************************
650
651  Synopsis    [Returns the list of latches of a network.]
652
653  Description [Returns the list of latches of a network.  The application must
654  not free or modify this list in any way.]
655
656  SideEffects []
657
658  SeeAlso     [Ntk_NetworkReadNumLatches]
659
660******************************************************************************/
661lsList
662Ntk_NetworkReadLatches(
663  Ntk_Network_t * network)
664{
665  return (network->latches);
666}
667
668
669/**Function********************************************************************
670
671  Synopsis    [Returns the list of primary inputs of a network.]
672
673  Description [Returns the list of primary inputs of a network.  The application
674  must not free or modify this list in any way.]
675
676  SideEffects []
677
678  SeeAlso     [Ntk_NetworkReadNumPrimaryInputs]
679
680******************************************************************************/
681lsList
682Ntk_NetworkReadPrimaryInputs(
683  Ntk_Network_t * network)
684{
685  return (network->primaryInputs);
686}
687
688
689/**Function********************************************************************
690
691  Synopsis    [Returns the list of pseudo inputs of a network.]
692
693  Description [Returns the list of pseudo inputs of a network.  The application
694  must not free or modify this list in any way.]
695
696  SideEffects []
697
698  SeeAlso     [Ntk_NetworkReadNumPseudoInputs]
699
700******************************************************************************/
701lsList
702Ntk_NetworkReadPseudoInputs(
703  Ntk_Network_t * network)
704{
705  return (network->pseudoInputs);
706}
707
708
709/**Function********************************************************************
710
711  Synopsis    [Returns the list of primary and pseudo inputs of a network.]
712
713  Description [Returns the list of primary and pseudo inputs of a network.  The
714  application must not free or modify this list in any way.]
715
716  SideEffects []
717
718  SeeAlso     [Ntk_NetworkReadNumInputs]
719
720******************************************************************************/
721lsList
722Ntk_NetworkReadInputs(
723  Ntk_Network_t * network)
724{
725  return (network->inputs);
726}
727
728
729/**Function********************************************************************
730
731  Synopsis    [Returns the list of primary outputs of a network.]
732
733  Description [Returns the list of primary outputs of a network.  The application
734  must not free or modify this list in any way.]
735
736  SideEffects []
737
738  SeeAlso     [Ntk_NetworkReadNumPrimaryOutputs]
739
740******************************************************************************/
741lsList
742Ntk_NetworkReadPrimaryOutputs(
743  Ntk_Network_t * network)
744{
745  return (network->primaryOutputs);
746}
747
748
749/**Function********************************************************************
750
751  Synopsis    [Associates application specified data with a network.]
752
753  Description [Adds the key/data pair to the network's applInfoTable. Key may
754  be an arbitrary string; to avoid possible conflicts with other applications,
755  key should be prefixed with the application's package name, for example
756  "Pkg_NetworkApplKey".  The contents of data are arbitrary; the network
757  package does not interpret the data. The freeFn is called on data when a
758  network is freed, or when Ntk_NetworkFreeApplInfo is called with the same
759  value of key. The freeFn takes (void *) as its only argument, and returns
760  void.  A copy is made of the string key before it is inserted into
761  applInfoTable.<p>
762
763  If this function is called with a key that already exists in the
764  applInfoTable, then the data for the previous entry is freed using the
765  freeFn, a new entry is created using the freeFn and data supplied as
766  arguments, and TRUE is returned. Otherwise, FALSE is returned.<p>
767
768  WARNING:  This function does not make a copy of data before inserting it
769  into the table.  By calling this function, the application is surrendering
770  responsibility to the network to free the data.  Once this function is
771  called on data, the data should be freed only by calling
772  Ntk_NetworkFreeApplInfo or Ntk_NetworkFree.  In other words, it is an error
773  for the application to explicitly free the data without using one of these
774  two functions. </p>]
775
776  SideEffects []
777
778  SeeAlso     [Ntk_NetworkFreeApplInfo Ntk_NetworkReadApplInfo]
779
780******************************************************************************/
781boolean
782Ntk_NetworkAddApplInfo(
783  Ntk_Network_t * network,
784  char * key,
785  Ntk_ApplInfoFreeFn  freeFn,
786  void * data)
787{
788  ApplInfo_t *applInfo;
789  boolean     status;
790
791  if (st_lookup(network->applInfoTable, key, &applInfo)) {
792    (*applInfo->freeFn)(applInfo->data);
793    status = TRUE;
794  }
795  else {
796    char *keyCopy = util_strsav(key);
797
798    applInfo = ALLOC(ApplInfo_t, 1);
799    st_insert(network->applInfoTable, keyCopy, (char *) applInfo);
800    status = FALSE;
801  }
802
803  applInfo->freeFn = freeFn;
804  applInfo->data   = data;
805  return status;
806}
807
808/**Function********************************************************************
809
810  Synopsis    [Set application specified data with a network.]
811
812  Description [Same as Ntk_NetworkAddApplInfo, but this function simply set
813  the ApplInfo without checking/freeing if there already exists one. Instead,
814  the caller should take care of that case.]
815
816  SeeAlso     [Ntk_NetworkFreeApplInfo Ntk_NetworkAddApplInfo]
817
818  SideEffects [ApplInfo of the argument network is modified]
819
820******************************************************************************/
821boolean
822Ntk_NetworkSetApplInfo(
823  Ntk_Network_t * network,
824  char * key,
825  Ntk_ApplInfoFreeFn  freeFn,
826  void * data)
827{
828  ApplInfo_t *applInfo;
829  boolean     status;
830
831  if (st_lookup(network->applInfoTable, key, &applInfo)) {
832    status = TRUE;
833  }
834  else {
835    char *keyCopy = util_strsav(key);
836
837    applInfo = ALLOC(ApplInfo_t, 1);
838    st_insert(network->applInfoTable, keyCopy, (char *) applInfo);
839    status = FALSE;
840  }
841
842  applInfo->freeFn = freeFn;
843  applInfo->data   = data;
844  return status;
845}
846
847
848/**Function********************************************************************
849
850  Synopsis    [Returns data corresponding to key if it exists, else returns NULL.]
851
852  Description [If data corresponding to key is associated to the network, then
853  returns a pointer to data (as void *).  Otherwise, returns NULL.]
854
855  SideEffects []
856
857  SeeAlso     [Ntk_NetworkAddApplInfo Ntk_NetworkFreeApplInfo]
858
859******************************************************************************/
860void *
861Ntk_NetworkReadApplInfo(
862  Ntk_Network_t * network,
863  char * key)
864{
865  int         status;
866  ApplInfo_t *applInfo;
867
868  status = st_lookup(network->applInfoTable, key, &applInfo);
869  if (status == 1) {
870    return (applInfo->data);
871  }
872  else {
873    return (NIL(void));
874  }
875}
876
877
878/**Function********************************************************************
879
880  Synopsis    [Frees application-specified data from a network.]
881
882  Description [If data corresponding to key exists in the network, then frees
883  the data using the associated free function, removes the key/data pair from
884  the network's applInfoTable, and returns TRUE.  If key does not exist, then
885  the function does nothing and returns FALSE.
886  <p>
887  WARNING: This function should be called only if a corresponding call to
888  Ntk_NetworkAddApplInfo has already been made.</p>]
889
890  SideEffects []
891
892  SeeAlso     [Ntk_NetworkAddApplInfo Ntk_NetworkReadApplInfo]
893
894******************************************************************************/
895boolean
896Ntk_NetworkFreeApplInfo(
897  Ntk_Network_t * network,
898  char * key)
899{
900  int         status;
901  ApplInfo_t *applInfo;
902
903  status = st_lookup(network->applInfoTable, key, &applInfo);
904
905  if (status == 1) {
906    st_delete(network->applInfoTable, &key, &applInfo);
907    (*applInfo->freeFn)(applInfo->data);
908    FREE(key);  /* frees the string contained in the table */
909    FREE(applInfo);
910  }
911
912  return ((status) ? TRUE : FALSE);
913}
914
915
916/**Function********************************************************************
917
918  Synopsis    [Allocates a network with a name.]
919
920  Description [Allocates a network with a name (a copy of name is made
921  first). Name must be non-NULL.  The remaining fields are initialized to
922  empty (e.g. empty lists, empty hash tables) or NULL (mddManager). The
923  dynVarOrdMethod is set to BDD_REORDER_NONE.]
924
925  SideEffects []
926
927  SeeAlso     [Ntk_NetworkFree]
928
929******************************************************************************/
930Ntk_Network_t *
931Ntk_NetworkAlloc(
932  char * name)
933{
934  Ntk_Network_t *network = ALLOC(Ntk_Network_t, 1);
935
936  network->name                   = util_strsav(name);
937  network->nodes                  = lsCreate();
938  network->combInputs             = lsCreate();
939  network->combOutputs            = lsCreate();
940  network->latches                = lsCreate();
941  network->primaryInputs          = lsCreate();
942  network->pseudoInputs           = lsCreate();
943  network->inputs                 = lsCreate();
944  network->primaryOutputs         = lsCreate();
945  network->combOutputsTable       = st_init_table(st_ptrcmp, st_ptrhash);
946  network->mddIdToNode            = st_init_table(st_numcmp, st_numhash);
947  network->actualNameToNode       = st_init_table(strcmp, st_strhash);
948  network->formalNameToActualName = st_init_table(strcmp, st_strhash);
949  network->applInfoTable          = st_init_table(strcmp, st_strhash);
950  network->mddManager             = NIL(mdd_manager);
951  network->mAigManager            = NIL(mAig_Manager_t);
952  network->dynVarOrdMethod        = BDD_REORDER_NONE;
953  network->undef                  = NIL(void);
954
955  return network;
956}
957
958
959/**Function********************************************************************
960
961  Synopsis    [Frees all the memory associated with a network.]
962
963  Description [Calls Ntk_NodeFree on each node of network, and then frees the
964  data local to network, and the network itself.  Also frees the MDD manager
965  of the network, if it is not NULL. If network is NULL, just returns.]
966
967  SideEffects []
968
969  SeeAlso     [Ntk_NetworkAlloc Ntk_NodeFree]
970
971******************************************************************************/
972void
973Ntk_NetworkFree(
974  Ntk_Network_t * network)
975{
976  char *formal;
977  char *actual;
978  char *key;
979  ApplInfo_t *applInfo;
980  Ntk_Node_t *node;
981  lsGen gen;
982  st_generator *stGen;
983
984
985  if (network == NIL(Ntk_Network_t)) {
986    return;
987  }
988
989  FREE(network->name);
990
991  Ntk_NetworkForEachNode(network, gen, node) {
992    Ntk_NodeFree(node);
993  }
994
995  (void) lsDestroy(network->nodes,           (void (*) (lsGeneric)) NULL);
996  (void) lsDestroy(network->combInputs,      (void (*) (lsGeneric)) NULL);
997  (void) lsDestroy(network->combOutputs,     (void (*) (lsGeneric)) NULL);
998  (void) lsDestroy(network->latches,         (void (*) (lsGeneric)) NULL);
999  (void) lsDestroy(network->primaryInputs,   (void (*) (lsGeneric)) NULL);
1000  (void) lsDestroy(network->pseudoInputs,    (void (*) (lsGeneric)) NULL);
1001  (void) lsDestroy(network->inputs,          (void (*) (lsGeneric)) NULL);
1002  (void) lsDestroy(network->primaryOutputs,  (void (*) (lsGeneric)) NULL);
1003  st_free_table(network->combOutputsTable);
1004  st_free_table(network->mddIdToNode);
1005
1006  /*
1007   * The keys in this table are strings representing node names.  The strings
1008   * are owned by the nodes, so we don't free them here.
1009   */
1010  st_free_table(network->actualNameToNode);
1011
1012  /*
1013   * Free all the strings in the formalNameToActualName table before freeing
1014   * the table itself.
1015   */
1016  st_foreach_item(network->formalNameToActualName, stGen, &formal, &actual) {
1017    FREE(formal);
1018    FREE(actual);
1019  }
1020
1021  st_free_table(network->formalNameToActualName);
1022
1023  /*
1024   * Free all the key/applInfo pairs in the applInfoTable, and then free the
1025   * table itself.
1026   */
1027  st_foreach_item(network->applInfoTable, stGen, &key, &applInfo) {
1028    FREE(key);
1029    (*applInfo->freeFn)(applInfo->data);
1030    FREE(applInfo);
1031  }
1032  st_free_table(network->applInfoTable);
1033
1034  if (network->mddManager != NIL(mdd_manager)) {
1035    mdd_quit(network->mddManager);
1036  }
1037
1038  if (network->mAigManager != NIL(mAig_Manager_t)) {
1039    mAig_quit(network->mAigManager);
1040  }
1041  FREE(network);
1042}
1043
1044
1045/**Function********************************************************************
1046
1047  Synopsis    [Callback function to free a network.]
1048
1049  Description [Typecasts data to (Ntk_Network_t *) and then calls
1050  Ntk_NetworkFree.  This function should only be used as a callback for other
1051  applications that don't know the network type, for example the Hrc_Node
1052  ApplInfoTable.]
1053
1054  SideEffects []
1055
1056  SeeAlso     [Ntk_NetworkFree]
1057
1058******************************************************************************/
1059void
1060Ntk_NetworkFreeCallback(
1061  void * data /* an object of type Ntk_Network_t*  type casted to void* */)
1062{
1063  Ntk_NetworkFree((Ntk_Network_t *) data);
1064}
1065
1066
1067/**Function********************************************************************
1068
1069  Synopsis    [Write a network in blif-MV format to a file.]
1070
1071  Description [Work in progress.  Still bogus in one major way:
1072  Equal entries in tables use formal names.]
1073
1074  SideEffects [none]
1075
1076  SeeAlso     [Ntk_NetworkPrint Hrc_ModelWriteBlifMv]
1077
1078******************************************************************************/
1079void
1080Ntk_NetworkWriteBlifMv(
1081  FILE *fp,
1082  Ntk_Network_t *network,
1083  boolean promotePseudo
1084  )
1085{
1086  lsGen gen;
1087  Ntk_Node_t *node;
1088  int i;
1089
1090  (void) fprintf(fp, ".model %s\n", Ntk_NetworkReadName(network));
1091
1092  /* .inputs */
1093  if (Ntk_NetworkReadNumPrimaryInputs(network) != 0) {
1094    (void) fprintf(fp, ".inputs");
1095    Ntk_NetworkForEachPrimaryInput(network, gen, node) {
1096      (void) fprintf(fp, " %s", Ntk_NodeReadName(node));
1097    }
1098    (void) fprintf(fp, "\n");
1099  }
1100
1101  if (promotePseudo && Ntk_NetworkReadNumPseudoInputs(network) != 0) {
1102    (void) fprintf(fp, "# pseudo inputs\n");
1103    (void) fprintf(fp, ".inputs");
1104    Ntk_NetworkForEachPseudoInput(network, gen, node) {
1105      (void) fprintf(fp, " %s", Ntk_NodeReadName(node));
1106    }
1107    (void) fprintf(fp, "\n");
1108  }
1109
1110  /* .outputs */
1111  if (Ntk_NetworkReadNumPrimaryOutputs(network) != 0) {
1112    (void) fprintf(fp, ".outputs");
1113    Ntk_NetworkForEachPrimaryOutput(network, gen, node) {
1114      (void) fprintf(fp, " %s", Ntk_NodeReadName(node));
1115    }
1116    (void) fprintf(fp, "\n");
1117  }
1118
1119  /* .mv .names .latch .reset */
1120  Ntk_NetworkForEachNode(network, gen, node) {
1121    Var_Variable_t *var = Ntk_NodeReadVariable(node);
1122    char *nodeName = Ntk_NodeReadName(node);
1123    boolean is_enum = Var_VariableTestIsEnumerative(var);
1124    int range = Var_VariableReadNumValues(var);
1125
1126    if (Ntk_NodeTestIsShadow(node)) continue;
1127    if (Ntk_NodeTestIsCombinational(node) &&
1128        Ntk_NodeTestIsLatchInitialInput(node)) continue;
1129
1130    if (is_enum) {
1131      if (range != 2) {
1132        /* Boolean enumerative variables need no .mv declaration. */
1133        (void) fprintf(fp, ".mv %s %d\n", nodeName, range);
1134      }
1135    } else {
1136      /* Variable is symbolic. */
1137      (void) fprintf(fp, ".mv %s %d", nodeName, range);
1138      for (i = 0; i < range; i++) {
1139        (void) fprintf(fp, " %s",
1140                       Var_VariableReadSymbolicValueFromIndex(var, i));
1141      }
1142      (void) fprintf(fp, "\n");
1143    }
1144  }
1145
1146  if (!promotePseudo && Ntk_NetworkReadNumPseudoInputs(network) != 0) {
1147    (void) fprintf(fp, "# pseudo inputs start\n");
1148    Ntk_NetworkForEachPseudoInput(network, gen, node) {
1149      Tbl_Table_t *dupTable = DuplicateTableAndVars(node,
1150                                                    Ntk_NodeReadName(node));
1151      Tbl_TableWriteBlifMvToFile(dupTable, 0, fp);
1152      Tbl_TableFree(dupTable);
1153    }
1154    (void) fprintf(fp, "# pseudo inputs end\n");
1155  }
1156
1157  Ntk_NetworkForEachNode(network, gen, node) {
1158
1159    if (Ntk_NodeTestIsShadow(node)) continue;
1160    if (Ntk_NodeTestIsCombinational(node) &&
1161        Ntk_NodeTestIsLatchInitialInput(node)) continue;
1162
1163    if (Ntk_NodeTestIsCombinational(node)) {
1164      Tbl_Table_t *dupTable = DuplicateTableAndVars(node,
1165                                                    Ntk_NodeReadName(node));
1166      Tbl_TableWriteBlifMvToFile(dupTable, 0, fp);
1167      Tbl_TableFree(dupTable);
1168    } else if (Ntk_NodeTestIsLatch(node)) {
1169      Ntk_Node_t *data = Ntk_LatchReadDataInput(node);
1170      Ntk_Node_t *reset = Ntk_LatchReadInitialInput(node);
1171      Tbl_Table_t *dupTable = DuplicateTableAndVars(reset,
1172                                                    Ntk_NodeReadName(node));
1173      (void) fprintf(fp, ".latch %s %s\n", Ntk_NodeReadName(data),
1174                     Ntk_NodeReadName(node));
1175      Tbl_TableWriteBlifMvToFile(dupTable, 1, fp);
1176      Tbl_TableFree(dupTable);
1177    }
1178  }
1179
1180  (void) fprintf(fp, ".end\n");
1181
1182} /* Ntk_NetworkWriteBlifMv */
1183
1184
1185/**Function********************************************************************
1186
1187  Synopsis    [Prints information about a network.]
1188
1189  Description [Prints name of network, and calls Ntk_NodePrint on each node of
1190  network.]
1191
1192  SideEffects []
1193
1194  SeeAlso     [Ntk_NodePrint]
1195
1196******************************************************************************/
1197void
1198Ntk_NetworkPrint(
1199  FILE * fp,
1200  Ntk_Network_t * network,
1201  boolean printIo,
1202  boolean printTableStats)
1203{
1204  Ntk_Node_t *node;
1205  lsGen       gen;
1206
1207  (void) fprintf(fp, "Nodes of network %s:\n", Ntk_NetworkReadName(network));
1208
1209  Ntk_NetworkForEachNode(network, gen, node) {
1210    Ntk_NodePrint(fp, node, printIo, printTableStats);
1211    /*
1212     * It's nice to have a line separating nodes when we print the fanins and
1213     * fanouts or table stats.
1214     */
1215    if (printIo || printTableStats) {
1216      (void) fprintf(fp, "\n");
1217    }
1218  }
1219}
1220
1221
1222/**Function********************************************************************
1223
1224  Synopsis    [Prints statistics about a network.]
1225
1226  Description [Prints the following information about a network: name, number
1227  of combinational nodes, number of primary inputs, number of primary outputs,
1228  number of latches.]
1229
1230  SideEffects []
1231
1232******************************************************************************/
1233void
1234Ntk_NetworkPrintStats(
1235  FILE * fp,
1236  Ntk_Network_t * network)
1237{
1238  lsGen          gen;
1239  Ntk_Node_t     *node;
1240  int            numConstants     = 0;
1241  int            numCombinational = 0;
1242  int            numEdges         = 0;
1243  mdd_manager  *mddMgr;
1244
1245  /*
1246   * Count the number of constants and the number of combinational nodes.
1247   */
1248  Ntk_NetworkForEachNode(network, gen, node) {
1249    numEdges += Ntk_NodeReadNumFanouts(node);
1250    if (Ntk_NodeTestIsConstant(node)) {
1251      numConstants++;
1252    }
1253    if (Ntk_NodeTestIsCombinational(node)) {
1254      numCombinational++;
1255    }
1256  }
1257
1258  mddMgr = Ntk_NetworkReadMddManager(network);
1259
1260  if (mddMgr == NIL(mdd_manager)){
1261     (void) fprintf(fp, "%s  combinational=%d  pi=%d  po=%d  latches=%d  pseudo=%d  const=%d  edges=%d\n",
1262                 Ntk_NetworkReadName(network),
1263                 numCombinational,
1264                 Ntk_NetworkReadNumPrimaryInputs(network),
1265                 Ntk_NetworkReadNumPrimaryOutputs(network),
1266                 Ntk_NetworkReadNumLatches(network),
1267                 Ntk_NetworkReadNumPseudoInputs(network),
1268                 numConstants,
1269                 numEdges
1270                 );
1271  }else{
1272     array_t *bddIdArray;
1273     lsGen gen;
1274     Ntk_Node_t *latch;
1275     int n_boolean_latches;
1276     array_t *mddIdArray = array_alloc(int, 0);
1277
1278     Ntk_NetworkForEachLatch(network, gen, latch){
1279       array_insert_last(int, mddIdArray, Ntk_NodeReadMddId(latch));
1280     }
1281
1282     bddIdArray = mdd_id_array_to_bdd_id_array(mddMgr, mddIdArray);
1283     n_boolean_latches = array_n(bddIdArray);
1284     array_free(mddIdArray);
1285     array_free(bddIdArray);
1286
1287     (void) fprintf(fp, "%s  combinational=%d  pi=%d  po=%d  latches=%d (boolean_latches=%d)  pseudo=%d  const=%d  edges=%d\n",
1288                 Ntk_NetworkReadName(network),
1289                 numCombinational,
1290                 Ntk_NetworkReadNumPrimaryInputs(network),
1291                 Ntk_NetworkReadNumPrimaryOutputs(network),
1292                 Ntk_NetworkReadNumLatches(network),
1293                 n_boolean_latches,
1294                 Ntk_NetworkReadNumPseudoInputs(network),
1295                 numConstants,
1296                 numEdges
1297                 );
1298  }
1299}
1300
1301
1302/**Function********************************************************************
1303
1304  Synopsis    [Duplicates a network.]
1305
1306  Description [Duplicates a network.  The network name and all node names are
1307  preserved.  The new network does not have an MDD manager.  The nodes of the
1308  new network have unassigned MDD ids.  The tables (Tbl_Table_t) of the new
1309  nodes are "soft duplicates" of the original tables in oldNetwork; they
1310  should not be modified.  The application information (ApplInfo) of the new
1311  network is empty.  The formalNameToActualName table of the new network is
1312  empty.]
1313
1314  SideEffects []
1315
1316  SeeAlso     [Ntk_NetworkFree Ntk_NetworkAppendNetwork]
1317
1318******************************************************************************/
1319Ntk_Network_t *
1320Ntk_NetworkDuplicate(
1321  Ntk_Network_t * oldNetwork)
1322{
1323  int            i;
1324  lsGen          gen;
1325  Ntk_Node_t    *oldNode;
1326  Ntk_Node_t    *oldFaninNode;
1327  Ntk_Node_t    *oldOriginNode;
1328  Ntk_Node_t    *newOriginNode;
1329  array_t       *faninNameArray;
1330  Ntk_Network_t *newNetwork = Ntk_NetworkAlloc(Ntk_NetworkReadName(oldNetwork));
1331
1332
1333  /*
1334   * For each node in oldNetwork, create a node in newNetwork.
1335   */
1336  Ntk_NetworkForEachNode(oldNetwork, gen, oldNode) {
1337    (void) Ntk_NodeCreateInNetwork(newNetwork, Ntk_NodeReadName(oldNode),
1338                                   Ntk_NodeReadVariable(oldNode));
1339  }
1340
1341  /*
1342   * For each node in oldNetwork, declare the corresponding node in newNetwork
1343   * using the type of the oldNode.
1344   */
1345  Ntk_NetworkForEachNode(oldNetwork, gen, oldNode) {
1346    char       *nodeName = Ntk_NodeReadName(oldNode);
1347    Ntk_Node_t *newNode  = Ntk_NetworkFindNodeByActualName(newNetwork, nodeName);
1348    assert(newNode != NIL(Ntk_Node_t));
1349
1350    /*
1351     * Handle items that are independent of node type.
1352     */
1353    if (Ntk_NodeTestIsPrimaryOutput(oldNode)) {
1354      Ntk_NodeDeclareAsPrimaryOutput(newNode);
1355    }
1356
1357    switch (oldNode->type) {
1358      case NtkPrimaryInput_c:
1359        Ntk_NodeDeclareAsPrimaryInput(newNode);
1360        break;
1361      case NtkPseudoInput_c:
1362        Ntk_NodeDeclareAsPseudoInput(newNode,
1363                                     Tbl_TableSoftDup(Ntk_NodeReadTable(oldNode)),
1364                                     Ntk_NodeReadOutputIndex(oldNode));
1365        break;
1366      case NtkLatch_c:
1367        Ntk_NodeDeclareAsLatch(newNode,
1368                               Ntk_NodeReadName(Ntk_LatchReadDataInput(oldNode)),
1369                               Ntk_NodeReadName(Ntk_LatchReadInitialInput(oldNode)));
1370        break;
1371      case NtkCombinational_c:
1372        /*
1373         * Create the array of names of the fanins of oldNode.
1374         */
1375        faninNameArray = array_alloc(char *, Ntk_NodeReadNumFanins(oldNode));
1376        Ntk_NodeForEachFanin(oldNode, i, oldFaninNode) {
1377          char *faninName = Ntk_NodeReadName(oldFaninNode);
1378          array_insert(char *, faninNameArray, i, faninName);
1379        }
1380
1381        Ntk_NodeDeclareAsCombinational(newNode,
1382                                       Tbl_TableSoftDup(Ntk_NodeReadTable(oldNode)),
1383                                       faninNameArray,
1384                                       Ntk_NodeReadOutputIndex(oldNode));
1385        array_free(faninNameArray);
1386        break;
1387      case NtkShadow_c:
1388        oldOriginNode = Ntk_ShadowReadOrigin(oldNode);
1389        newOriginNode = Ntk_NetworkFindNodeByActualName(newNetwork,
1390                                                        Ntk_NodeReadName(oldOriginNode));
1391        Ntk_NodeDeclareAsShadow(newNode, newOriginNode);
1392        break;
1393      case NtkUnassigned_c:
1394        fail("Unexpected unassigned node type");
1395        break;
1396      default:
1397        fail("Unexpected type");
1398        break;
1399    }
1400  }
1401
1402  return (newNetwork);
1403}
1404
1405
1406/**Function********************************************************************
1407
1408  Synopsis    [Appends network2 to network1.]
1409
1410  Description [Appends network2 to network1. Network2 is not modified, but
1411  network1 is modified.  Name1ToName2 is a hash table mapping char* keys to
1412  char* values (the table should use st_strhash and strcmp). The set of keys
1413  is an arbitrary subset (including empty set) of the set of names of the
1414  inputs (primary and pseudo) of network2.  The value of each key is the name
1415  of an arbitrary node in network1.<p>
1416
1417  The inputs of network2 can be divided into 3 types: I - those appearing in
1418  name2ToName1 as keys, II - those not appearing in name2ToName1, but which
1419  have nodes with the same names in network1, and III - all other inputs
1420  (i.e. those neither appearing in name2ToName1, nor having nodes of the same
1421  names in network1).  An input of type II could be equivalently specified as a
1422  type I input, where the key and value are the same.  If there are no type I
1423  inputs, an empty symbol table should be provided.<p>
1424
1425  A node of network2 is appended to network1 if it is a type III input, or it
1426  is not an input.  All appended nodes have the string $NTK2 added to the end
1427  of their names.  Inputs of type I or II are not appended to network1.  When
1428  a node of network2 is appended to network1, if there exists a fanin of the
1429  node that is a type I or II input, then that fanin is modified to refer to
1430  the node in network1 corresponding to the type I or II.  The MDD ids of the
1431  appended nodes are unassigned.  The tables of the appended nodes are "soft
1432  duplicates" of the original tables in network2; they should not be
1433  modified.<p>
1434
1435  Note that it is impossible for the set of fanins of a node (originally) in
1436  network1 to be modified.  The only changes that occur to the original nodes
1437  of network1 are that the fanout sets will increase for those nodes
1438  corresponding to type I or II inputs of network2.<p>
1439
1440  The application information of network1 is not modified; the information
1441  should be invalidated by the caller as necessary.  The MDD manager of
1442  network1 is not modified in any way.  The formalNameToActualName table of
1443  network1 is not updated to reflect the addition of the nodes from network2.
1444  Currently, it is assumed that type I and II inputs do not have shadow
1445  nodes.
1446
1447  !!! Chao Says: I have changed all the FindNodeByActualName with
1448                 FindNodeByName, since the later one subsume the former.
1449      replace  Ntk_NetworkFindNodeByActualName(network1, name1);
1450      with     Ntk_NetworkFindNodeByName(network1, name1);
1451  ]
1452
1453  SideEffects [Network1 is modified.]
1454
1455  SeeAlso     [Ntk_NetworkDuplicate Ntk_NetworkFreeApplInfo]
1456
1457******************************************************************************/
1458void
1459Ntk_NetworkAppendNetwork(
1460  Ntk_Network_t * network1,
1461  Ntk_Network_t * network2,
1462  st_table *name2ToName1)
1463{
1464  st_generator *stGen;
1465  lsGen         gen;
1466  Ntk_Node_t   *node1;
1467  Ntk_Node_t   *node2;
1468  char         *name1;
1469  char         *name2;
1470  st_table     *localName2ToName1 = st_init_table(strcmp, st_strhash);
1471
1472
1473  /*
1474   * For each node in network2, create a node in network1 as necessary. The
1475   * undef field of node2 is set to TRUE if a new node is created in network1
1476   * for it; else, it is set to FALSE. localName2ToName1 is a superset of
1477   * name2ToName1; in addition to the contents of name2ToName1, it contains
1478   * the new names (those appended with $NTK2) for those nodes being appended
1479   * to network2, and type II inputs.
1480   */
1481  Ntk_NetworkForEachNode(network2, gen, node2) {
1482    name1 = NIL(char);
1483    name2 = Ntk_NodeReadName(node2);
1484    st_lookup(name2ToName1, name2, &name1);
1485    if (name1 != NIL(char)) {
1486      /*
1487       * Name2 is in name2ToName1 table (type I input).  Hence, we will be
1488       * using the node in network1 corresponding to name1.  Assert that node2
1489       * is in fact an input, that name1 refers to an input node in network1, and
1490       * that node1 and node2 have the same variable domains.
1491       */
1492      Ntk_NodeSetUndef(node2, (void *) FALSE);
1493      st_insert(localName2ToName1, name2, util_strsav(name1));
1494
1495      assert(Ntk_NodeTestIsInput(node2));
1496      node1 = Ntk_NetworkFindNodeByName(network1, name1);
1497      assert(node1 != NIL(Ntk_Node_t));
1498      assert(Var_VariablesTestHaveSameDomain(Ntk_NodeReadVariable(node1),
1499                                             Ntk_NodeReadVariable(node2)));
1500    }
1501    else {
1502      /*
1503       * Name2 is *not* in name2ToName1 table.  There are 2 possibilities: 1)
1504       * a node with name2 already exists in network1, and node2 is an input
1505       * (type II input); in this case, a) add map of name2 to name2 in the
1506       * localName2ToName1, b) assert that node1 is in fact an input, and c)
1507       * don't create a new node in network1; 2) a node with name2 doesn't
1508       * exist in network1, or node2 is not an input (type III inputs and
1509       * non-inputs); in this case, we unconditionally create a new node in
1510       * network1 using name2$NTK2.
1511       */
1512      node1 = Ntk_NetworkFindNodeByName(network1, name2);
1513
1514      if ((node1 != NIL(Ntk_Node_t)) && Ntk_NodeTestIsInput(node2)) {
1515        Ntk_NodeSetUndef(node2, (void *) FALSE);
1516        st_insert(localName2ToName1, name2, util_strsav(name2));
1517      }
1518      else {
1519        char *newName = util_strcat3(name2, "$NTK2", "");
1520        Ntk_NodeSetUndef(node2, (void *) TRUE);
1521        st_insert(localName2ToName1, name2, newName);
1522        (void) Ntk_NodeCreateInNetwork(network1, newName,
1523                                       Ntk_NodeReadVariable(node2));
1524      }
1525    }
1526  }
1527
1528  /*
1529   * For each node in network2 for which a new node was created in network1,
1530   * declare the corresponding node in network1 using the type of the node2.
1531   * (NOTE: this section shares a lot with Ntk_NetworkDuplicate, but is
1532   * sufficiently different that we don't share any code.)
1533   */
1534  Ntk_NetworkForEachNode(network2, gen, node2) {
1535    if (Ntk_NodeReadUndef(node2) == NIL(void)) {
1536      /*
1537       * node2 is superseded by a node in network1.
1538       */
1539      continue;
1540    }
1541
1542    name2 = NodeReadNameFromTable(node2, localName2ToName1);
1543    node1 = Ntk_NetworkFindNodeByName(network1, name2);
1544    assert(node1 != NIL(Ntk_Node_t));
1545
1546    /*
1547     * Handle items that are independent of node type.
1548     */
1549    if (Ntk_NodeTestIsPrimaryOutput(node2)) {
1550      Ntk_NodeDeclareAsPrimaryOutput(node1);
1551    }
1552
1553    switch (node2->type) {
1554      case NtkPrimaryInput_c:
1555        Ntk_NodeDeclareAsPrimaryInput(node1);
1556        break;
1557
1558      case NtkPseudoInput_c:
1559        Ntk_NodeDeclareAsPseudoInput(node1,
1560                                     Tbl_TableSoftDup(Ntk_NodeReadTable(node2)),
1561                                     Ntk_NodeReadOutputIndex(node2));
1562        break;
1563
1564      case NtkLatch_c:
1565      {
1566        char *dataName = NodeReadNameFromTable(Ntk_LatchReadDataInput(node2),
1567                                               localName2ToName1);
1568        char *initName = NodeReadNameFromTable(Ntk_LatchReadInitialInput(node2),
1569                                               localName2ToName1);
1570
1571        Ntk_NodeDeclareAsLatch(node1, dataName, initName);
1572        break;
1573      }
1574
1575      case NtkCombinational_c:
1576      {
1577        int         i;
1578        Ntk_Node_t *faninNode2;
1579        array_t    *faninNameArray;
1580
1581        /*
1582         * Create the array of names of the fanins of node2.
1583         */
1584        faninNameArray = array_alloc(char *, Ntk_NodeReadNumFanins(node2));
1585        Ntk_NodeForEachFanin(node2, i, faninNode2) {
1586          char *faninName = NodeReadNameFromTable(faninNode2, localName2ToName1);
1587          array_insert(char *, faninNameArray, i, faninName);
1588        }
1589
1590        Ntk_NodeDeclareAsCombinational(node1,
1591                                       Tbl_TableSoftDup(Ntk_NodeReadTable(node2)),
1592                                       faninNameArray,
1593                                       Ntk_NodeReadOutputIndex(node2));
1594        array_free(faninNameArray);
1595        break;
1596      }
1597
1598      case NtkShadow_c:
1599      {
1600        char       *originName;
1601        Ntk_Node_t *originNode2;
1602        Ntk_Node_t *originNode1;
1603
1604        originNode2 = Ntk_ShadowReadOrigin(node2);
1605        /*
1606         * Currently, we don't allow a shadow node whose origin in a type I or
1607         * II input.  This is because, what if the corresponding node in
1608         * network1 (of the type I or II input), also has a shadow node?  Then
1609         * we would try to add a shadow node to a node already having a shadow;
1610         * this is illegal.
1611         */
1612        assert((boolean) (long) Ntk_NodeReadUndef(node2));
1613        originName = NodeReadNameFromTable(originNode2, localName2ToName1);
1614        originNode1 = Ntk_NetworkFindNodeByName(network1, originName);
1615
1616        Ntk_NodeDeclareAsShadow(node1, originNode1);
1617        break;
1618      }
1619
1620      case NtkUnassigned_c:
1621        fail("Unexpected unassigned node type");
1622        break;
1623      default:
1624        fail("Unexpected type");
1625        break;
1626    }
1627  }
1628
1629  /*
1630   * Free all the values strings in the localName2ToName1, before freeing
1631   * the table itself.  The keys are not freed.
1632   */
1633  st_foreach_item(localName2ToName1, stGen, &name2, &name1) {
1634    FREE(name1);
1635  }
1636  st_free_table(localName2ToName1);
1637}
1638
1639
1640/**Function********************************************************************
1641
1642  Synopsis [print a description of the topology of the network in dot format]
1643
1644  Description [The format used for the description is <b>dot</b>, a tool for
1645  graph visualization developed at AT&T. It can be obtained from <a
1646  href="http://www.research.att.com/orgs/ssr/book/reuse">
1647  http://www.research.att.com/orgs/ssr/book/reuse</a>. The function
1648  receives as a parameter a file pointer in case the print wants to be
1649  redirected. This function is used by the command routine
1650  CommandPrintNetworkDot.]
1651
1652  SideEffects []
1653
1654******************************************************************************/
1655int
1656Ntk_NetworkPrintDot(
1657  FILE *fp,
1658  Ntk_Network_t *network)
1659{
1660  lsGen       gen;
1661  int i;
1662  Ntk_Node_t *nodePtr;
1663  Ntk_Node_t *fanoutPtr;
1664  time_t      now           = time(0);
1665  struct tm  *nowStructPtr  = localtime(& now);
1666  char       *nowTxt        = asctime(nowStructPtr);
1667  char       *networkName   = Ntk_NetworkReadName(network);
1668
1669  /*
1670   * Write out the header for the output file.
1671   */
1672
1673  (void) fprintf(fp, "# %s\n", Vm_VisReadVersion());
1674  (void) fprintf(fp, "# network name: %s\n", networkName);
1675  (void) fprintf(fp, "# generated: %s", nowTxt);
1676  (void) fprintf(fp, "#\n");
1677
1678  (void) fprintf(fp, "# Network with %d nodes\n",
1679                 Ntk_NetworkReadNumNodes(network));
1680
1681  (void) fprintf(fp, "digraph \"%s\" {\n  rotate=90;\n", networkName);
1682  (void) fprintf(fp, "  margin=0.5;\n  label=\"%s\";\n", networkName);
1683  (void) fprintf(fp, "  size=\"10,7.5\";\n  ratio=\"fill\";\n");
1684
1685  /* Force the inputs and outputs to be printed at the same level in the graph */
1686  (void) fprintf(fp, "  { rank=same; ");
1687  Ntk_NetworkForEachCombInput(network,gen, nodePtr) {
1688    (void) fprintf(fp, "\"%s\"; ", Ntk_NodeReadName(nodePtr));
1689  }
1690  (void) fprintf(fp, "}\n");
1691  (void) fprintf(fp, "  { rank=same; ");
1692  Ntk_NetworkForEachCombOutput(network,gen, nodePtr) {
1693    (void) fprintf(fp, "\"%s\"; ", Ntk_NodeReadName(nodePtr));
1694  }
1695  (void) fprintf(fp, "}\n");
1696
1697  /* Print all the edges */
1698  Ntk_NetworkForEachNode(network, gen, nodePtr) {
1699
1700    if (Ntk_NodeReadNumFanouts(nodePtr) == 0 &&
1701        Ntk_NodeReadNumFanins(nodePtr) == 0) {
1702      /* Print the dot description for a node */
1703      (void) fprintf(fp, \"%s\";\n", Ntk_NodeReadName(nodePtr));
1704    } /* End of if */
1705
1706    /* Print the edges comming out of that node */
1707    Ntk_NodeForEachFanout(nodePtr, i, fanoutPtr) {
1708      (void) fprintf(fp, \"%s\" -> \"%s\";\n", Ntk_NodeReadName(nodePtr),
1709                     Ntk_NodeReadName(fanoutPtr));
1710    }
1711  }
1712
1713  (void) fprintf(fp, "}\n");
1714
1715  return 1;
1716}
1717
1718/*---------------------------------------------------------------------------*/
1719/* Definition of internal functions                                          */
1720/*---------------------------------------------------------------------------*/
1721
1722/*---------------------------------------------------------------------------*/
1723/* Definition of static functions                                            */
1724/*---------------------------------------------------------------------------*/
1725
1726/**Function********************************************************************
1727
1728  Synopsis    [Returns node name from table.]
1729
1730  Description [Given a node, uses the name of the node as key to lookup the
1731  corresponding (new) name for the node.  If the node does not exist as a key
1732  in the table, then fails.  The returned string should not be freed.]
1733
1734  SideEffects []
1735
1736******************************************************************************/
1737static char *
1738NodeReadNameFromTable(
1739  Ntk_Node_t *node,
1740  st_table *name2ToName1)
1741{
1742  char    *name1  = NIL(char);
1743  char    *name2  = Ntk_NodeReadName(node);
1744  boolean  status UNUSED = st_lookup(name2ToName1, name2, &name1);
1745
1746  assert(status);
1747  return name1;
1748}
1749
1750
1751/**Function********************************************************************
1752
1753  Synopsis    [Duplicate a table and corresponding variables.]
1754
1755  Description []
1756
1757  SideEffects []
1758
1759  SeeAlso []
1760
1761******************************************************************************/
1762static Tbl_Table_t *
1763DuplicateTableAndVars(
1764  Ntk_Node_t *node,
1765  char *name
1766  )
1767{
1768  Var_Variable_t *var, *newVar;
1769  Tbl_Table_t *dupTable, *tbl;
1770  int col;
1771  Tbl_Table_t *table = Ntk_NodeReadTable(node);
1772  array_t *split = Tbl_TableSplit(table);
1773  int outIndex = Ntk_NodeReadOutputIndex(node);
1774
1775  arrayForEachItem(Tbl_Table_t *, split, col, tbl) {
1776    if (col == outIndex) {
1777      dupTable = tbl;
1778    } else {
1779      Tbl_TableFree(tbl);
1780    }
1781  }
1782  array_free(split);
1783
1784  Tbl_TableForEachInputVar(dupTable, col, var) {
1785    Ntk_Node_t *fanin = Ntk_NodeReadFaninNode(node, col);
1786    char *newName = Ntk_NodeReadName(fanin);
1787    newVar = Var_VariableDup(var, NIL(Hrc_Node_t));
1788    Var_VariableChangeName(newVar, newName);
1789    Tbl_TableSetVar(dupTable, col, newVar, 0);
1790  }
1791
1792  var = array_fetch(Var_Variable_t *,Tbl_TableReadOutputVars(dupTable), 0);
1793  newVar = Var_VariableDup(var, NIL(Hrc_Node_t));
1794  Var_VariableChangeName(newVar, name);
1795  Tbl_TableSetVar(dupTable, 0, newVar, 1);
1796
1797  return dupTable;
1798
1799} /* DuplicateTableAndVars */
Note: See TracBrowser for help on using the repository browser.