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

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

vis2.3

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
1042  FREE(network);
1043}
1044
1045
1046/**Function********************************************************************
1047
1048  Synopsis    [Callback function to free a network.]
1049
1050  Description [Typecasts data to (Ntk_Network_t *) and then calls
1051  Ntk_NetworkFree.  This function should only be used as a callback for other
1052  applications that don't know the network type, for example the Hrc_Node
1053  ApplInfoTable.]
1054
1055  SideEffects []
1056
1057  SeeAlso     [Ntk_NetworkFree]
1058
1059******************************************************************************/
1060void
1061Ntk_NetworkFreeCallback(
1062  void * data /* an object of type Ntk_Network_t*  type casted to void* */)
1063{
1064  Ntk_NetworkFree((Ntk_Network_t *) data);
1065}
1066
1067
1068/**Function********************************************************************
1069
1070  Synopsis    [Write a network in blif-MV format to a file.]
1071
1072  Description [Work in progress.  Still bogus in one major way:
1073  Equal entries in tables use formal names.]
1074
1075  SideEffects [none]
1076
1077  SeeAlso     [Ntk_NetworkPrint Hrc_ModelWriteBlifMv]
1078
1079******************************************************************************/
1080void
1081Ntk_NetworkWriteBlifMv(
1082  FILE *fp,
1083  Ntk_Network_t *network,
1084  boolean promotePseudo
1085  )
1086{
1087  lsGen gen;
1088  Ntk_Node_t *node;
1089  int i;
1090
1091  (void) fprintf(fp, ".model %s\n", Ntk_NetworkReadName(network));
1092
1093  /* .inputs */
1094  if (Ntk_NetworkReadNumPrimaryInputs(network) != 0) {
1095    (void) fprintf(fp, ".inputs");
1096    Ntk_NetworkForEachPrimaryInput(network, gen, node) {
1097      (void) fprintf(fp, " %s", Ntk_NodeReadName(node));
1098    }
1099    (void) fprintf(fp, "\n");
1100  }
1101
1102  if (promotePseudo && Ntk_NetworkReadNumPseudoInputs(network) != 0) {
1103    (void) fprintf(fp, "# pseudo inputs\n");
1104    (void) fprintf(fp, ".inputs");
1105    Ntk_NetworkForEachPseudoInput(network, gen, node) {
1106      (void) fprintf(fp, " %s", Ntk_NodeReadName(node));
1107    }
1108    (void) fprintf(fp, "\n");
1109  }
1110
1111  /* .outputs */
1112  if (Ntk_NetworkReadNumPrimaryOutputs(network) != 0) {
1113    (void) fprintf(fp, ".outputs");
1114    Ntk_NetworkForEachPrimaryOutput(network, gen, node) {
1115      (void) fprintf(fp, " %s", Ntk_NodeReadName(node));
1116    }
1117    (void) fprintf(fp, "\n");
1118  }
1119
1120  /* .mv .names .latch .reset */
1121  Ntk_NetworkForEachNode(network, gen, node) {
1122    Var_Variable_t *var = Ntk_NodeReadVariable(node);
1123    char *nodeName = Ntk_NodeReadName(node);
1124    boolean is_enum = Var_VariableTestIsEnumerative(var);
1125    int range = Var_VariableReadNumValues(var);
1126
1127    if (Ntk_NodeTestIsShadow(node)) continue;
1128    if (Ntk_NodeTestIsCombinational(node) &&
1129        Ntk_NodeTestIsLatchInitialInput(node)) continue;
1130
1131    if (is_enum) {
1132      if (range != 2) {
1133        /* Boolean enumerative variables need no .mv declaration. */
1134        (void) fprintf(fp, ".mv %s %d\n", nodeName, range);
1135      }
1136    } else {
1137      /* Variable is symbolic. */
1138      (void) fprintf(fp, ".mv %s %d", nodeName, range);
1139      for (i = 0; i < range; i++) {
1140        (void) fprintf(fp, " %s",
1141                       Var_VariableReadSymbolicValueFromIndex(var, i));
1142      }
1143      (void) fprintf(fp, "\n");
1144    }
1145  }
1146
1147  if (!promotePseudo && Ntk_NetworkReadNumPseudoInputs(network) != 0) {
1148    (void) fprintf(fp, "# pseudo inputs start\n");
1149    Ntk_NetworkForEachPseudoInput(network, gen, node) {
1150      Tbl_Table_t *dupTable = DuplicateTableAndVars(node,
1151                                                    Ntk_NodeReadName(node));
1152      Tbl_TableWriteBlifMvToFile(dupTable, 0, fp);
1153      Tbl_TableFree(dupTable);
1154    }
1155    (void) fprintf(fp, "# pseudo inputs end\n");
1156  }
1157
1158  Ntk_NetworkForEachNode(network, gen, node) {
1159
1160    if (Ntk_NodeTestIsShadow(node)) continue;
1161    if (Ntk_NodeTestIsCombinational(node) &&
1162        Ntk_NodeTestIsLatchInitialInput(node)) continue;
1163
1164    if (Ntk_NodeTestIsCombinational(node)) {
1165      Tbl_Table_t *dupTable = DuplicateTableAndVars(node,
1166                                                    Ntk_NodeReadName(node));
1167      Tbl_TableWriteBlifMvToFile(dupTable, 0, fp);
1168      Tbl_TableFree(dupTable);
1169    } else if (Ntk_NodeTestIsLatch(node)) {
1170      Ntk_Node_t *data = Ntk_LatchReadDataInput(node);
1171      Ntk_Node_t *reset = Ntk_LatchReadInitialInput(node);
1172      Tbl_Table_t *dupTable = DuplicateTableAndVars(reset,
1173                                                    Ntk_NodeReadName(node));
1174      (void) fprintf(fp, ".latch %s %s\n", Ntk_NodeReadName(data),
1175                     Ntk_NodeReadName(node));
1176      Tbl_TableWriteBlifMvToFile(dupTable, 1, fp);
1177      Tbl_TableFree(dupTable);
1178    }
1179  }
1180
1181  (void) fprintf(fp, ".end\n");
1182
1183} /* Ntk_NetworkWriteBlifMv */
1184
1185
1186/**Function********************************************************************
1187
1188  Synopsis    [Prints information about a network.]
1189
1190  Description [Prints name of network, and calls Ntk_NodePrint on each node of
1191  network.]
1192
1193  SideEffects []
1194
1195  SeeAlso     [Ntk_NodePrint]
1196
1197******************************************************************************/
1198void
1199Ntk_NetworkPrint(
1200  FILE * fp,
1201  Ntk_Network_t * network,
1202  boolean printIo,
1203  boolean printTableStats)
1204{
1205  Ntk_Node_t *node;
1206  lsGen       gen;
1207
1208  (void) fprintf(fp, "Nodes of network %s:\n", Ntk_NetworkReadName(network));
1209
1210  Ntk_NetworkForEachNode(network, gen, node) {
1211    Ntk_NodePrint(fp, node, printIo, printTableStats);
1212    /*
1213     * It's nice to have a line separating nodes when we print the fanins and
1214     * fanouts or table stats.
1215     */
1216    if (printIo || printTableStats) {
1217      (void) fprintf(fp, "\n");
1218    }
1219  }
1220}
1221
1222
1223/**Function********************************************************************
1224
1225  Synopsis    [Prints statistics about a network.]
1226
1227  Description [Prints the following information about a network: name, number
1228  of combinational nodes, number of primary inputs, number of primary outputs,
1229  number of latches.]
1230
1231  SideEffects []
1232
1233******************************************************************************/
1234void
1235Ntk_NetworkPrintStats(
1236  FILE * fp,
1237  Ntk_Network_t * network)
1238{
1239  lsGen          gen;
1240  Ntk_Node_t     *node;
1241  int            numConstants     = 0;
1242  int            numCombinational = 0;
1243  int            numEdges         = 0;
1244  mdd_manager  *mddMgr;
1245
1246  /*
1247   * Count the number of constants and the number of combinational nodes.
1248   */
1249  Ntk_NetworkForEachNode(network, gen, node) {
1250    numEdges += Ntk_NodeReadNumFanouts(node);
1251    if (Ntk_NodeTestIsConstant(node)) {
1252      numConstants++;
1253    }
1254    if (Ntk_NodeTestIsCombinational(node)) {
1255      numCombinational++;
1256    }
1257  }
1258
1259  mddMgr = Ntk_NetworkReadMddManager(network);
1260
1261  if (mddMgr == NIL(mdd_manager)){
1262     (void) fprintf(fp, "%s  combinational=%d  pi=%d  po=%d  latches=%d  pseudo=%d  const=%d  edges=%d\n",
1263                 Ntk_NetworkReadName(network),
1264                 numCombinational,
1265                 Ntk_NetworkReadNumPrimaryInputs(network),
1266                 Ntk_NetworkReadNumPrimaryOutputs(network),
1267                 Ntk_NetworkReadNumLatches(network),
1268                 Ntk_NetworkReadNumPseudoInputs(network),
1269                 numConstants,
1270                 numEdges
1271                 );
1272  }else{
1273     array_t *bddIdArray;
1274     lsGen gen;
1275     Ntk_Node_t *latch;
1276     int n_boolean_latches;
1277     array_t *mddIdArray = array_alloc(int, 0);
1278
1279     Ntk_NetworkForEachLatch(network, gen, latch){
1280       array_insert_last(int, mddIdArray, Ntk_NodeReadMddId(latch));
1281     }
1282
1283     bddIdArray = mdd_id_array_to_bdd_id_array(mddMgr, mddIdArray);
1284     n_boolean_latches = array_n(bddIdArray);
1285     array_free(mddIdArray);
1286     array_free(bddIdArray);
1287
1288     (void) fprintf(fp, "%s  combinational=%d  pi=%d  po=%d  latches=%d (boolean_latches=%d)  pseudo=%d  const=%d  edges=%d\n",
1289                 Ntk_NetworkReadName(network),
1290                 numCombinational,
1291                 Ntk_NetworkReadNumPrimaryInputs(network),
1292                 Ntk_NetworkReadNumPrimaryOutputs(network),
1293                 Ntk_NetworkReadNumLatches(network),
1294                 n_boolean_latches,
1295                 Ntk_NetworkReadNumPseudoInputs(network),
1296                 numConstants,
1297                 numEdges
1298                 );
1299  }
1300}
1301
1302
1303/**Function********************************************************************
1304
1305  Synopsis    [Duplicates a network.]
1306
1307  Description [Duplicates a network.  The network name and all node names are
1308  preserved.  The new network does not have an MDD manager.  The nodes of the
1309  new network have unassigned MDD ids.  The tables (Tbl_Table_t) of the new
1310  nodes are "soft duplicates" of the original tables in oldNetwork; they
1311  should not be modified.  The application information (ApplInfo) of the new
1312  network is empty.  The formalNameToActualName table of the new network is
1313  empty.]
1314
1315  SideEffects []
1316
1317  SeeAlso     [Ntk_NetworkFree Ntk_NetworkAppendNetwork]
1318
1319******************************************************************************/
1320Ntk_Network_t *
1321Ntk_NetworkDuplicate(
1322  Ntk_Network_t * oldNetwork)
1323{
1324  int            i;
1325  lsGen          gen;
1326  Ntk_Node_t    *oldNode;
1327  Ntk_Node_t    *oldFaninNode;
1328  Ntk_Node_t    *oldOriginNode;
1329  Ntk_Node_t    *newOriginNode;
1330  array_t       *faninNameArray;
1331  Ntk_Network_t *newNetwork = Ntk_NetworkAlloc(Ntk_NetworkReadName(oldNetwork));
1332
1333
1334  /*
1335   * For each node in oldNetwork, create a node in newNetwork.
1336   */
1337  Ntk_NetworkForEachNode(oldNetwork, gen, oldNode) {
1338    (void) Ntk_NodeCreateInNetwork(newNetwork, Ntk_NodeReadName(oldNode),
1339                                   Ntk_NodeReadVariable(oldNode));
1340  }
1341
1342  /*
1343   * For each node in oldNetwork, declare the corresponding node in newNetwork
1344   * using the type of the oldNode.
1345   */
1346  Ntk_NetworkForEachNode(oldNetwork, gen, oldNode) {
1347    char       *nodeName = Ntk_NodeReadName(oldNode);
1348    Ntk_Node_t *newNode  = Ntk_NetworkFindNodeByActualName(newNetwork, nodeName);
1349    assert(newNode != NIL(Ntk_Node_t));
1350
1351    /*
1352     * Handle items that are independent of node type.
1353     */
1354    if (Ntk_NodeTestIsPrimaryOutput(oldNode)) {
1355      Ntk_NodeDeclareAsPrimaryOutput(newNode);
1356    }
1357
1358    switch (oldNode->type) {
1359      case NtkPrimaryInput_c:
1360        Ntk_NodeDeclareAsPrimaryInput(newNode);
1361        break;
1362      case NtkPseudoInput_c:
1363        Ntk_NodeDeclareAsPseudoInput(newNode,
1364                                     Tbl_TableSoftDup(Ntk_NodeReadTable(oldNode)),
1365                                     Ntk_NodeReadOutputIndex(oldNode));
1366        break;
1367      case NtkLatch_c:
1368        Ntk_NodeDeclareAsLatch(newNode,
1369                               Ntk_NodeReadName(Ntk_LatchReadDataInput(oldNode)),
1370                               Ntk_NodeReadName(Ntk_LatchReadInitialInput(oldNode)));
1371        break;
1372      case NtkCombinational_c:
1373        /*
1374         * Create the array of names of the fanins of oldNode.
1375         */
1376        faninNameArray = array_alloc(char *, Ntk_NodeReadNumFanins(oldNode));
1377        Ntk_NodeForEachFanin(oldNode, i, oldFaninNode) {
1378          char *faninName = Ntk_NodeReadName(oldFaninNode);
1379          array_insert(char *, faninNameArray, i, faninName);
1380        }
1381
1382        Ntk_NodeDeclareAsCombinational(newNode,
1383                                       Tbl_TableSoftDup(Ntk_NodeReadTable(oldNode)),
1384                                       faninNameArray,
1385                                       Ntk_NodeReadOutputIndex(oldNode));
1386        array_free(faninNameArray);
1387        break;
1388      case NtkShadow_c:
1389        oldOriginNode = Ntk_ShadowReadOrigin(oldNode);
1390        newOriginNode = Ntk_NetworkFindNodeByActualName(newNetwork,
1391                                                        Ntk_NodeReadName(oldOriginNode));
1392        Ntk_NodeDeclareAsShadow(newNode, newOriginNode);
1393        break;
1394      case NtkUnassigned_c:
1395        fail("Unexpected unassigned node type");
1396        break;
1397      default:
1398        fail("Unexpected type");
1399        break;
1400    }
1401  }
1402
1403  return (newNetwork);
1404}
1405
1406
1407/**Function********************************************************************
1408
1409  Synopsis    [Appends network2 to network1.]
1410
1411  Description [Appends network2 to network1. Network2 is not modified, but
1412  network1 is modified.  Name1ToName2 is a hash table mapping char* keys to
1413  char* values (the table should use st_strhash and strcmp). The set of keys
1414  is an arbitrary subset (including empty set) of the set of names of the
1415  inputs (primary and pseudo) of network2.  The value of each key is the name
1416  of an arbitrary node in network1.<p>
1417
1418  The inputs of network2 can be divided into 3 types: I - those appearing in
1419  name2ToName1 as keys, II - those not appearing in name2ToName1, but which
1420  have nodes with the same names in network1, and III - all other inputs
1421  (i.e. those neither appearing in name2ToName1, nor having nodes of the same
1422  names in network1).  An input of type II could be equivalently specified as a
1423  type I input, where the key and value are the same.  If there are no type I
1424  inputs, an empty symbol table should be provided.<p>
1425
1426  A node of network2 is appended to network1 if it is a type III input, or it
1427  is not an input.  All appended nodes have the string $NTK2 added to the end
1428  of their names.  Inputs of type I or II are not appended to network1.  When
1429  a node of network2 is appended to network1, if there exists a fanin of the
1430  node that is a type I or II input, then that fanin is modified to refer to
1431  the node in network1 corresponding to the type I or II.  The MDD ids of the
1432  appended nodes are unassigned.  The tables of the appended nodes are "soft
1433  duplicates" of the original tables in network2; they should not be
1434  modified.<p>
1435
1436  Note that it is impossible for the set of fanins of a node (originally) in
1437  network1 to be modified.  The only changes that occur to the original nodes
1438  of network1 are that the fanout sets will increase for those nodes
1439  corresponding to type I or II inputs of network2.<p>
1440
1441  The application information of network1 is not modified; the information
1442  should be invalidated by the caller as necessary.  The MDD manager of
1443  network1 is not modified in any way.  The formalNameToActualName table of
1444  network1 is not updated to reflect the addition of the nodes from network2.
1445  Currently, it is assumed that type I and II inputs do not have shadow
1446  nodes.
1447
1448  !!! Chao Says: I have changed all the FindNodeByActualName with
1449                 FindNodeByName, since the later one subsume the former.
1450      replace  Ntk_NetworkFindNodeByActualName(network1, name1);
1451      with     Ntk_NetworkFindNodeByName(network1, name1);
1452  ]
1453
1454  SideEffects [Network1 is modified.]
1455
1456  SeeAlso     [Ntk_NetworkDuplicate Ntk_NetworkFreeApplInfo]
1457
1458******************************************************************************/
1459void
1460Ntk_NetworkAppendNetwork(
1461  Ntk_Network_t * network1,
1462  Ntk_Network_t * network2,
1463  st_table *name2ToName1)
1464{
1465  st_generator *stGen;
1466  lsGen         gen;
1467  Ntk_Node_t   *node1;
1468  Ntk_Node_t   *node2;
1469  char         *name1;
1470  char         *name2;
1471  st_table     *localName2ToName1 = st_init_table(strcmp, st_strhash);
1472
1473
1474  /*
1475   * For each node in network2, create a node in network1 as necessary. The
1476   * undef field of node2 is set to TRUE if a new node is created in network1
1477   * for it; else, it is set to FALSE. localName2ToName1 is a superset of
1478   * name2ToName1; in addition to the contents of name2ToName1, it contains
1479   * the new names (those appended with $NTK2) for those nodes being appended
1480   * to network2, and type II inputs.
1481   */
1482  Ntk_NetworkForEachNode(network2, gen, node2) {
1483    name1 = NIL(char);
1484    name2 = Ntk_NodeReadName(node2);
1485    st_lookup(name2ToName1, name2, &name1);
1486    if (name1 != NIL(char)) {
1487      /*
1488       * Name2 is in name2ToName1 table (type I input).  Hence, we will be
1489       * using the node in network1 corresponding to name1.  Assert that node2
1490       * is in fact an input, that name1 refers to an input node in network1, and
1491       * that node1 and node2 have the same variable domains.
1492       */
1493      Ntk_NodeSetUndef(node2, (void *) FALSE);
1494      st_insert(localName2ToName1, name2, util_strsav(name1));
1495
1496      assert(Ntk_NodeTestIsInput(node2));
1497      node1 = Ntk_NetworkFindNodeByName(network1, name1);
1498      assert(node1 != NIL(Ntk_Node_t));
1499      assert(Var_VariablesTestHaveSameDomain(Ntk_NodeReadVariable(node1),
1500                                             Ntk_NodeReadVariable(node2)));
1501    }
1502    else {
1503      /*
1504       * Name2 is *not* in name2ToName1 table.  There are 2 possibilities: 1)
1505       * a node with name2 already exists in network1, and node2 is an input
1506       * (type II input); in this case, a) add map of name2 to name2 in the
1507       * localName2ToName1, b) assert that node1 is in fact an input, and c)
1508       * don't create a new node in network1; 2) a node with name2 doesn't
1509       * exist in network1, or node2 is not an input (type III inputs and
1510       * non-inputs); in this case, we unconditionally create a new node in
1511       * network1 using name2$NTK2.
1512       */
1513      node1 = Ntk_NetworkFindNodeByName(network1, name2);
1514
1515      if ((node1 != NIL(Ntk_Node_t)) && Ntk_NodeTestIsInput(node2)) {
1516        Ntk_NodeSetUndef(node2, (void *) FALSE);
1517        st_insert(localName2ToName1, name2, util_strsav(name2));
1518      }
1519      else {
1520        char *newName = util_strcat3(name2, "$NTK2", "");
1521        Ntk_NodeSetUndef(node2, (void *) TRUE);
1522        st_insert(localName2ToName1, name2, newName);
1523        (void) Ntk_NodeCreateInNetwork(network1, newName,
1524                                       Ntk_NodeReadVariable(node2));
1525      }
1526    }
1527  }
1528
1529  /*
1530   * For each node in network2 for which a new node was created in network1,
1531   * declare the corresponding node in network1 using the type of the node2.
1532   * (NOTE: this section shares a lot with Ntk_NetworkDuplicate, but is
1533   * sufficiently different that we don't share any code.)
1534   */
1535  Ntk_NetworkForEachNode(network2, gen, node2) {
1536    if (Ntk_NodeReadUndef(node2) == NIL(void)) {
1537      /*
1538       * node2 is superseded by a node in network1.
1539       */
1540      continue;
1541    }
1542
1543    name2 = NodeReadNameFromTable(node2, localName2ToName1);
1544    node1 = Ntk_NetworkFindNodeByName(network1, name2);
1545    assert(node1 != NIL(Ntk_Node_t));
1546
1547    /*
1548     * Handle items that are independent of node type.
1549     */
1550    if (Ntk_NodeTestIsPrimaryOutput(node2)) {
1551      Ntk_NodeDeclareAsPrimaryOutput(node1);
1552    }
1553
1554    switch (node2->type) {
1555      case NtkPrimaryInput_c:
1556        Ntk_NodeDeclareAsPrimaryInput(node1);
1557        break;
1558
1559      case NtkPseudoInput_c:
1560        Ntk_NodeDeclareAsPseudoInput(node1,
1561                                     Tbl_TableSoftDup(Ntk_NodeReadTable(node2)),
1562                                     Ntk_NodeReadOutputIndex(node2));
1563        break;
1564
1565      case NtkLatch_c:
1566      {
1567        char *dataName = NodeReadNameFromTable(Ntk_LatchReadDataInput(node2),
1568                                               localName2ToName1);
1569        char *initName = NodeReadNameFromTable(Ntk_LatchReadInitialInput(node2),
1570                                               localName2ToName1);
1571
1572        Ntk_NodeDeclareAsLatch(node1, dataName, initName);
1573        break;
1574      }
1575
1576      case NtkCombinational_c:
1577      {
1578        int         i;
1579        Ntk_Node_t *faninNode2;
1580        array_t    *faninNameArray;
1581
1582        /*
1583         * Create the array of names of the fanins of node2.
1584         */
1585        faninNameArray = array_alloc(char *, Ntk_NodeReadNumFanins(node2));
1586        Ntk_NodeForEachFanin(node2, i, faninNode2) {
1587          char *faninName = NodeReadNameFromTable(faninNode2, localName2ToName1);
1588          array_insert(char *, faninNameArray, i, faninName);
1589        }
1590
1591        Ntk_NodeDeclareAsCombinational(node1,
1592                                       Tbl_TableSoftDup(Ntk_NodeReadTable(node2)),
1593                                       faninNameArray,
1594                                       Ntk_NodeReadOutputIndex(node2));
1595        array_free(faninNameArray);
1596        break;
1597      }
1598
1599      case NtkShadow_c:
1600      {
1601        char       *originName;
1602        Ntk_Node_t *originNode2;
1603        Ntk_Node_t *originNode1;
1604
1605        originNode2 = Ntk_ShadowReadOrigin(node2);
1606        /*
1607         * Currently, we don't allow a shadow node whose origin in a type I or
1608         * II input.  This is because, what if the corresponding node in
1609         * network1 (of the type I or II input), also has a shadow node?  Then
1610         * we would try to add a shadow node to a node already having a shadow;
1611         * this is illegal.
1612         */
1613        assert((boolean) (long) Ntk_NodeReadUndef(node2));
1614        originName = NodeReadNameFromTable(originNode2, localName2ToName1);
1615        originNode1 = Ntk_NetworkFindNodeByName(network1, originName);
1616
1617        Ntk_NodeDeclareAsShadow(node1, originNode1);
1618        break;
1619      }
1620
1621      case NtkUnassigned_c:
1622        fail("Unexpected unassigned node type");
1623        break;
1624      default:
1625        fail("Unexpected type");
1626        break;
1627    }
1628  }
1629
1630  /*
1631   * Free all the values strings in the localName2ToName1, before freeing
1632   * the table itself.  The keys are not freed.
1633   */
1634  st_foreach_item(localName2ToName1, stGen, &name2, &name1) {
1635    FREE(name1);
1636  }
1637  st_free_table(localName2ToName1);
1638}
1639
1640
1641/**Function********************************************************************
1642
1643  Synopsis [print a description of the topology of the network in dot format]
1644
1645  Description [The format used for the description is <b>dot</b>, a tool for
1646  graph visualization developed at AT&T. It can be obtained from <a
1647  href="http://www.research.att.com/orgs/ssr/book/reuse">
1648  http://www.research.att.com/orgs/ssr/book/reuse</a>. The function
1649  receives as a parameter a file pointer in case the print wants to be
1650  redirected. This function is used by the command routine
1651  CommandPrintNetworkDot.]
1652
1653  SideEffects []
1654
1655******************************************************************************/
1656int
1657Ntk_NetworkPrintDot(
1658  FILE *fp,
1659  Ntk_Network_t *network)
1660{
1661  lsGen       gen;
1662  int i;
1663  Ntk_Node_t *nodePtr;
1664  Ntk_Node_t *fanoutPtr;
1665  time_t      now           = time(0);
1666  struct tm  *nowStructPtr  = localtime(& now);
1667  char       *nowTxt        = asctime(nowStructPtr);
1668  char       *networkName   = Ntk_NetworkReadName(network);
1669
1670  /*
1671   * Write out the header for the output file.
1672   */
1673
1674  (void) fprintf(fp, "# %s\n", Vm_VisReadVersion());
1675  (void) fprintf(fp, "# network name: %s\n", networkName);
1676  (void) fprintf(fp, "# generated: %s", nowTxt);
1677  (void) fprintf(fp, "#\n");
1678
1679  (void) fprintf(fp, "# Network with %d nodes\n",
1680                 Ntk_NetworkReadNumNodes(network));
1681
1682  (void) fprintf(fp, "digraph \"%s\" {\n  rotate=90;\n", networkName);
1683  (void) fprintf(fp, "  margin=0.5;\n  label=\"%s\";\n", networkName);
1684  (void) fprintf(fp, "  size=\"10,7.5\";\n  ratio=\"fill\";\n");
1685
1686  /* Force the inputs and outputs to be printed at the same level in the graph */
1687  (void) fprintf(fp, "  { rank=same; ");
1688  Ntk_NetworkForEachCombInput(network,gen, nodePtr) {
1689    (void) fprintf(fp, "\"%s\"; ", Ntk_NodeReadName(nodePtr));
1690  }
1691  (void) fprintf(fp, "}\n");
1692  (void) fprintf(fp, "  { rank=same; ");
1693  Ntk_NetworkForEachCombOutput(network,gen, nodePtr) {
1694    (void) fprintf(fp, "\"%s\"; ", Ntk_NodeReadName(nodePtr));
1695  }
1696  (void) fprintf(fp, "}\n");
1697
1698  /* Print all the edges */
1699  Ntk_NetworkForEachNode(network, gen, nodePtr) {
1700
1701    if (Ntk_NodeReadNumFanouts(nodePtr) == 0 &&
1702        Ntk_NodeReadNumFanins(nodePtr) == 0) {
1703      /* Print the dot description for a node */
1704      (void) fprintf(fp, \"%s\";\n", Ntk_NodeReadName(nodePtr));
1705    } /* End of if */
1706
1707    /* Print the edges comming out of that node */
1708    Ntk_NodeForEachFanout(nodePtr, i, fanoutPtr) {
1709      (void) fprintf(fp, \"%s\" -> \"%s\";\n", Ntk_NodeReadName(nodePtr),
1710                     Ntk_NodeReadName(fanoutPtr));
1711    }
1712  }
1713
1714  (void) fprintf(fp, "}\n");
1715
1716  return 1;
1717}
1718
1719/*---------------------------------------------------------------------------*/
1720/* Definition of internal functions                                          */
1721/*---------------------------------------------------------------------------*/
1722
1723/*---------------------------------------------------------------------------*/
1724/* Definition of static functions                                            */
1725/*---------------------------------------------------------------------------*/
1726
1727/**Function********************************************************************
1728
1729  Synopsis    [Returns node name from table.]
1730
1731  Description [Given a node, uses the name of the node as key to lookup the
1732  corresponding (new) name for the node.  If the node does not exist as a key
1733  in the table, then fails.  The returned string should not be freed.]
1734
1735  SideEffects []
1736
1737******************************************************************************/
1738static char *
1739NodeReadNameFromTable(
1740  Ntk_Node_t *node,
1741  st_table *name2ToName1)
1742{
1743  char    *name1  = NIL(char);
1744  char    *name2  = Ntk_NodeReadName(node);
1745  boolean  status UNUSED = st_lookup(name2ToName1, name2, &name1);
1746
1747  assert(status);
1748  return name1;
1749}
1750
1751
1752/**Function********************************************************************
1753
1754  Synopsis    [Duplicate a table and corresponding variables.]
1755
1756  Description []
1757
1758  SideEffects []
1759
1760  SeeAlso []
1761
1762******************************************************************************/
1763static Tbl_Table_t *
1764DuplicateTableAndVars(
1765  Ntk_Node_t *node,
1766  char *name
1767  )
1768{
1769  Var_Variable_t *var, *newVar;
1770  Tbl_Table_t *dupTable, *tbl;
1771  int col;
1772  Tbl_Table_t *table = Ntk_NodeReadTable(node);
1773  array_t *split = Tbl_TableSplit(table);
1774  int outIndex = Ntk_NodeReadOutputIndex(node);
1775
1776  arrayForEachItem(Tbl_Table_t *, split, col, tbl) {
1777    if (col == outIndex) {
1778      dupTable = tbl;
1779    } else {
1780      Tbl_TableFree(tbl);
1781    }
1782  }
1783  array_free(split);
1784
1785  Tbl_TableForEachInputVar(dupTable, col, var) {
1786    Ntk_Node_t *fanin = Ntk_NodeReadFaninNode(node, col);
1787    char *newName = Ntk_NodeReadName(fanin);
1788    newVar = Var_VariableDup(var, NIL(Hrc_Node_t));
1789    Var_VariableChangeName(newVar, newName);
1790    Tbl_TableSetVar(dupTable, col, newVar, 0);
1791  }
1792
1793  var = array_fetch(Var_Variable_t *,Tbl_TableReadOutputVars(dupTable), 0);
1794  newVar = Var_VariableDup(var, NIL(Hrc_Node_t));
1795  Var_VariableChangeName(newVar, name);
1796  Tbl_TableSetVar(dupTable, 0, newVar, 1);
1797
1798  return dupTable;
1799
1800} /* DuplicateTableAndVars */
Note: See TracBrowser for help on using the repository browser.