Main Page | Class List | File List | Class Members | File Members

net.c

Go to the documentation of this file.
00001 
00015 extern "C" {
00016 
00017 #include "tarski.h"
00018 #define BUFFER_SIZE 128
00019 #define DEFAULT_MEM_SIZE 8
00020 
00023 /*---------------------------------------------------------------------------*/
00024 /* Static function prototypes                                                */
00025 /*---------------------------------------------------------------------------*/
00026 
00027   static int setNodeType (Net_t * net, Fnode * aFormula,
00028                           st_table * nodeToTypeHash);
00029   static Fnode *createBryantNode (array_t * BryantNodeArray, array_t * uArray,
00030                                   array_t * vArray, int i);
00031   static Fnode *createBryantNodeIteratively (array_t * eqChecks,
00032                                              array_t * vArray, int i);
00033   static Fnode *computeEqNode (Fnode * u_i, Fnode * u_j);
00034   static Fnode *createEqNodeFromLists (Fnode * aList, Fnode * bList);
00035   static int swapNodes (Net_t * net, Fnode * A, Fnode * B);
00036   static Fnode *getUnfoldedNode (Net_t * net, Fnode * formula, int depth,
00037                                  array_t * processedTableArray,
00038                                  array_t * newprocessedTableArray);
00039   static Fnode *getUnfoldedNode2 (Net_t * net, Fnode * formula, int depth,
00040                                   array_t * newprocessedTableArray);
00041   static int updateFanoutArray (Net_t * net, Fnode * formula,
00042                                 Fnode * parent_formula,
00043                                 st_table * processedNodes);
00044   static Fnode *createReadUsingWrite (Net_t * net, char *readUifName,
00045                                       Fnode * formula, Fnode * readAddress,
00046                                       st_table * writeTable,
00047                                       st_table * processedNodes);
00048   static void Net_AnalyzeMemory (Net_t * net, FILE * fptr, Fnode * aFormula);
00049   static void Net_AnalyzeUIF (Net_t * net, FILE * fptr, Fnode * aFormula,
00050                               st_table * uifToNumInputs,
00051                               st_table * uifComponentHash);
00052   static void Net_InstantiateMemory (Net_t * net, FILE * fptr,
00053                                      Fnode * aFormula,
00054                                      st_table * nodeToNameHash,
00055                                      st_table * processedNodes,
00056                                      st_table * uifInstantiateHash,
00057                                      st_table * uifToNumInputs,
00058                                      int vector_width);
00059   static void Net_InstantiateUIF (Net_t * net, FILE * fptr, Fnode * aFormula,
00060                                   st_table * uifToNumInputs,
00061                                   st_table * nodeToNameHash,
00062                                   st_table * processedNodes,
00063                                   st_table * uifInstantiateHash,
00064                                   int vector_width);
00065   static int Net_PrintFormulaInt (Net_t * net, Fnode * formula,
00066                                   st_table * processedNodes, FILE * fptr);
00067   static int Net_PrintVHDLInt (Net_t * net, FILE * fptr, 
00068                                int vector_width, char *entity_name);
00069 
00073 /*---------------------------------------------------------------------------*/
00074 /* Definition of exported functions                                          */
00075 /*---------------------------------------------------------------------------*/
00076 
00084   Fnode *Net_NameToNode (Net_t * net, char *name)
00085   {
00086     Fnode *node;
00087     if (name == NIL (char))
00088       {
00089         printf ("Passed in a bad argument to Net_NameToNode\n");
00090         assert (0);
00091       }
00092     if (!st_lookup (net->nameToNodeHash, (char *) name, (char **) &node))
00093       {
00094         return nil;
00095       }
00096     return node;
00097   }
00098 
00099 
00106   Net_t *Net_CreateFromFormula (Fnode * aFormula)
00107   {
00108     Net_t *net = (Net_t *) malloc (sizeof (Net_t));
00109     int i;
00110     // todo - get rid of this hacked decl, put
00111     // in the header files
00112     extern int node_cmp ();
00113     extern int node_hash ();
00114     array_t *aFormulas = array_alloc (Fnode *, 0);
00115     array_insert_last (Fnode *, aFormulas, aFormula);
00116 
00117     net->numNodes = 0;
00118     net->formulas = aFormulas;
00119     net->allNodes = array_alloc (Fnode *, 0);
00120     net->PIs = array_alloc (Fnode *, 0);
00121     net->constants = array_alloc (Fnode *, 0);
00122     net->nameToNodeHash =
00123       st_init_table ((int (*)()) strcmp, (int (*)()) st_strhash);
00124     net->nodeToFanoutArray =
00125       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
00126     net->nodeToId =
00127       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
00128     net->UIFs = 
00129       st_init_table ((int (*)()) strcmp, (int (*)()) st_strhash);
00130     net->memToSizeHash = 
00131       st_init_table ((int (*)()) strcmp, (int (*)()) st_strhash);
00132 
00133     st_table *processedNodes =
00134       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
00135     for (i = 0; i < array_n (aFormulas); i++)
00136       {
00137         Fnode *instance = array_fetch (Fnode *, aFormulas, i);
00138         Net_PopulateFields (net, instance, nil, processedNodes);
00139       }
00140     st_free_table (processedNodes);
00141     return net;
00142   }
00143 
00150   Net_t *Net_CreateFromFormulaArray (array_t * aFormulas)
00151   {
00152     Net_t *net = (Net_t *) malloc (sizeof (Net_t));
00153     int i;
00154     // todo - get rid of this hacked decl, put
00155     // in the header files
00156     extern int node_cmp ();
00157     extern int node_hash ();
00158 
00159     net->numNodes = 0;
00160     net->formulas = aFormulas;
00161     net->allNodes = array_alloc (Fnode *, 0);
00162     net->PIs = array_alloc (Fnode *, 0);
00163     net->constants = array_alloc (Fnode *, 0);
00164     net->nameToNodeHash =
00165       st_init_table ((int (*)()) strcmp, (int (*)()) st_strhash);
00166     net->nodeToFanoutArray =
00167       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
00168     net->nodeToId =
00169       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
00170     net->UIFs = 
00171       st_init_table ((int (*)()) strcmp, (int (*)()) st_strhash);
00172     net->memToSizeHash =
00173       st_init_table ((int (*)()) strcmp, (int (*)()) st_strhash);
00174 
00175     st_table *processedNodes =
00176       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
00177     for (i = 0; i < array_n (aFormulas); i++)
00178       {
00179         Fnode *instance = array_fetch (Fnode *, aFormulas, i);
00180         Net_PopulateFields (net, instance, nil, processedNodes);
00181       }
00182     st_free_table (processedNodes);
00183     return net;
00184   }
00185 
00192   int Net_FreeNet (Net_t * net)
00193   {
00194     array_free (net->allNodes);
00195     array_free (net->PIs);
00196     array_free (net->constants);
00197     st_free_table (net->nameToNodeHash);
00198     Fnode *node;
00199     array_t *array;
00200     st_generator *stGen;
00201     st_foreach_item (net->nodeToFanoutArray, stGen, (char **) &node,
00202                      (char **) &array)
00203     {
00204       array_free (array);
00205     }
00206     st_free_table (net->nodeToFanoutArray);
00207     st_free_table (net->nodeToId);
00208     st_free_table (net->UIFs);
00209     st_free_table (net->memToSizeHash);
00210 
00211     free (net);
00212 
00213     return 1;
00214   }
00215 
00225   int
00226     Net_PopulateFields (Net_t * net,
00227                         Fnode * aFormula,
00228                         Fnode * parentFormula, st_table * processedNodes)
00229   {
00230 
00231     if (aFormula == nil)
00232       {
00233         return 0;
00234       }
00235     //printf("calling netpopulatefields with formula = %X, parent = %X\n", aFormula, parentFormula);
00236     assert (aFormula->type <= ScalarConst_c);
00237     // need to update the fanouts even if we've seen this 
00238     // node before, since the edge is fresh
00239     array_t *fanoutArray;
00240     if (!st_lookup
00241         (net->nodeToFanoutArray, (char *) aFormula, (char **) &fanoutArray))
00242       {
00243         fanoutArray = array_alloc (Fnode *, 0);
00244         st_insert (net->nodeToFanoutArray, (char *) aFormula,
00245                    (char *) fanoutArray);
00246       }
00247     // the initial call is made with the root formula, and nil for its 
00248     // parent so we need to check this
00249     if (parentFormula != nil)
00250       {
00251         array_insert_last (Fnode *, fanoutArray, parentFormula);
00252       }
00253     if (aFormula->type == Func_c)
00254       {
00255         //printf("It is a UIF %X with name %s\n", aFormula, (char *) aFormula->lchild);
00256         if (parentFormula != nil)
00257           {
00258             //printf("adding node %X with type %d to the fanout array\n", parentFormula, parentFormula->type);
00259           }
00260       }
00261     if (st_lookup (processedNodes, (char *) aFormula, (char **) 0))
00262       {
00263         //printf("already in processedNodes\n");
00264         return 0;
00265       }
00266     //printf("inserting aFormula = %X into processedNodes\n", aFormula);
00267     st_insert (processedNodes, (char *) aFormula, (char *) 0);
00268 
00269     st_insert (net->nodeToId, (char *) aFormula, (char *) net->numNodes);
00270     net->numNodes++;
00271     array_insert_last (Fnode *, net->allNodes, aFormula);
00272     if ((aFormula->type == ScalarPI_c) || (aFormula->type == BooleanPI_c))
00273       {
00274         array_insert_last (Fnode *, net->PIs, aFormula);
00275       }
00276     else if (aFormula->type == ScalarConst_c)
00277       {
00278         array_insert_last (Fnode *, net->constants, aFormula);
00279       }
00280     if ((aFormula->type == ScalarPI_c) ||
00281         (aFormula->type == BooleanPI_c) ||
00282         (aFormula->type == InternalScalarVar_c) ||
00283         (aFormula->type == InternalBooleanVar_c) ||
00284         //   ( aFormula->type == UnaryFunc_c ) || 
00285         //   ( aFormula->type == Func_c ) || 
00286         (aFormula->type == Assign_c))
00287       {
00288         if (st_lookup
00289             (net->nameToNodeHash, (char *) aFormula->lchild, (char **) 0))
00290           {
00291             printf ("Error - have already seen this name %s\n",
00292                     (char *) aFormula->lchild);
00293             assert (0);
00294           }
00295         st_insert (net->nameToNodeHash, (char *) aFormula->lchild,
00296                    (char *) aFormula);
00297       }
00298 
00299 
00300     // some nodes have a char * on the lchild so we can't use
00301     // the nil test from the beginning to avoid them
00302 /*
00303   if ( !( ( aFormula->type == ScalarPI_c ) || 
00304           ( aFormula->type == BooleanPI_c ) || 
00305           ( aFormula->type == InternalScalarVar_c ) || 
00306           ( aFormula->type == InternalBooleanVar_c ) || 
00307           ( aFormula->type == UnaryFunc_c ) || 
00308           ( aFormula->type == Func_c ) || 
00309           ( aFormula->type == BooleanReg_c ) ||
00310           ( aFormula->type == ScalarReg_c ) ||
00311           ( aFormula->type == ScalarConst_c ) ||
00312           ( aFormula->type == Assign_c ) ) ) {
00313     Net_PopulateFields( net, (F) aFormula->lchild, (F) aFormula, processedNodes );
00314   }
00315 */
00316     if (Node_HasLeftChildNode ((Fnode *) aFormula))
00317       {
00318         //printf("looking at the left child\n");
00319         Net_PopulateFields (net, (Fnode *) aFormula->lchild,
00320                             (Fnode *) aFormula, processedNodes);
00321       }
00322     if (Node_HasRightChildNode ((Fnode *) aFormula))
00323       {
00324         //printf("looking at the right child\n");
00325         Net_PopulateFields (net, (Fnode *) aFormula->rchild,
00326                             (Fnode *) aFormula, processedNodes);
00327       }
00328 
00329     // HM: we will try to add the UIFs in topological order so that nothing gets messed up (0910)
00330     if ((aFormula->type == UnaryFunc_c) || (aFormula->type == Func_c))
00331       {
00332         array_t *instancesArray;
00333         if (st_lookup
00334             (net->UIFs, (char *) aFormula->lchild, (char **) &instancesArray))
00335           {
00336             array_insert_last (Fnode *, instancesArray, aFormula);
00337           }
00338         else
00339           {
00340             instancesArray = array_alloc (Fnode *, 0);
00341             array_insert_last (Fnode *, instancesArray, aFormula);
00342             st_insert (net->UIFs, (char *) aFormula->lchild,
00343                        (char *) instancesArray);
00344           }
00345       }
00346 
00347     return 0;
00348   }
00349 
00350 
00383   int Net_DoBryantReduction (Net_t * net)
00384   {
00385     char *uifName;
00386     st_generator *stGen;
00387     array_t *uifNodeInstantiations;
00388     int i;
00389     Fnode *instance;
00390     st_table *uifBryantNodeArray =
00391       st_init_table ((int (*)()) strcmp, (int (*)()) st_strhash);
00392     st_foreach_item (net->UIFs, stGen, (char **) &uifName,
00393                      (char **) &uifNodeInstantiations)
00394     {
00395       array_t *uArray = array_alloc (F, 0);
00396       array_t *vArray = array_alloc (F, 0);
00397       //printf("uif name is %s and number of instantiations is %d\n", uifName, array_n(uifNodeInstantiations));
00398       for (i = 0; i < array_n (uifNodeInstantiations); i++)
00399         {
00400           instance = array_fetch (Fnode *, uifNodeInstantiations, i);
00401           array_insert_last (Fnode *, uArray, (Fnode *) instance->rchild);
00402           char suffix[100];
00403           sprintf (suffix, "%d", i);
00404           char *vNodeName =
00405             util_strcat3 ((char *) instance->lchild, "_", suffix);
00406           Fnode *vNode = new_node (ScalarPI_c, (Fnode *) vNodeName, nil);
00407           array_insert_last (Fnode *, vArray, vNode);
00408         }
00409       // uArray contains the inputs to the UIF (which could be a Func_c of a UnaryFunc_c;
00410       // for the former, the corresponding entries in uArray are scalars, the latter,
00411       // the entries are List_c
00412       // 
00413       // vArray contains the fresh PIs, and the node names are <UIF name>_0, <UIF name>_1, etc.
00414 
00415       array_t *bryantNodeArray = array_alloc (Fnode *, 0);
00416       for (i = 0; i < array_n (uifNodeInstantiations); i++)
00417         {
00418           instance = array_fetch (Fnode *, uifNodeInstantiations, i);
00419           createBryantNode (bryantNodeArray, uArray, vArray, i);
00420           /*swapNodes( net, instance, bryantNode ); */
00421         }
00422       st_insert (uifBryantNodeArray, (char *) uifName,
00423                  (char *) bryantNodeArray);
00424     }
00425 
00426     st_table *processedNodes =
00427       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
00428     st_foreach_item (net->UIFs, stGen, (char **) &uifName,
00429                      (char **) &uifNodeInstantiations)
00430     {
00431       array_t *swapNodeArray;
00432       Fnode *swapNode;
00433       if (st_lookup
00434           (uifBryantNodeArray, (char *) uifName, (char **) &swapNodeArray))
00435         {
00436           for (i = 0; i < array_n (swapNodeArray); i++)
00437             {
00438               swapNode = array_fetch (Fnode *, swapNodeArray, i);
00439               updateFanoutArray (net, swapNode, nil, processedNodes);
00440             }
00441         }
00442     }
00443     st_foreach_item (net->UIFs, stGen, (char **) &uifName,
00444                      (char **) &uifNodeInstantiations)
00445     {
00446       array_t *swapNodeArray;
00447       Fnode *swapNode;
00448       if (st_lookup
00449           (uifBryantNodeArray, (char *) uifName, (char **) &swapNodeArray))
00450         {
00451           for (i = 0; i < array_n (uifNodeInstantiations); i++)
00452             {
00453               instance = array_fetch (Fnode *, uifNodeInstantiations, i);
00454               swapNode = array_fetch (Fnode *, swapNodeArray, i);
00455               swapNodes (net, instance, swapNode);
00456             }
00457         }
00458     }
00459 
00460     return 1;
00461   }
00462 
00470   int setNodeType (Net_t * net, Fnode * aFormula, st_table * nodeToTypeHash)
00471   {
00472 
00473     int type_id = -1, lchild_type = -1, rchild_type = -1, control_type = -1;
00474     assert (net != NIL (Net_t));
00475     assert (nodeToTypeHash != NIL (st_table));
00476     Fnode *uif_input = nil;
00477     if (aFormula == nil)
00478       {
00479         // Neither scalar nor boolean 
00480         return -1;
00481       }
00482     if (st_lookup (nodeToTypeHash, (char *) aFormula, (char **) &type_id))
00483       {
00484         return type_id;
00485       }
00486     // switch on type 
00487     switch (aFormula->type)
00488       {
00489       case List_c:
00490       case Pair_c:
00491         // undefined type (return val 0)
00492         type_id = 0;
00493         break;
00494       case Undef_c:
00495         // undefined type (return val 0)
00496         type_id = 0;
00497         break;
00498       case ScalarPI_c:
00499       case InternalScalarVar_c:
00500       case ScalarConst_c:
00501         // scalar type
00502         type_id = 2;
00503         break;
00504       case ScalarReg_c:
00505         // scalar type
00506         type_id = 2;
00507         // need to set nodetoTypeHash because of cycles
00508         st_insert (nodeToTypeHash, (char *) aFormula, (char *) type_id);
00509         setNodeType (net, (Fnode *) Reg_InitFunc (aFormula), nodeToTypeHash);
00510         setNodeType (net, (Fnode *) Reg_NsFunc (aFormula), nodeToTypeHash);
00511         break;
00512       case BooleanPI_c:
00513       case InternalBooleanVar_c:
00514       case TRUE_c:
00515       case FALSE_c:
00516         // boolean type
00517         type_id = 1;
00518         break;
00519       case Iff_c:
00520       case Equal_c:
00521         // boolean type
00522         type_id = 1;
00523         setNodeType (net, (Fnode *) aFormula->lchild, nodeToTypeHash);
00524         setNodeType (net, (Fnode *) aFormula->rchild, nodeToTypeHash);
00525         break;
00526       case BooleanReg_c:
00527         //boolean type
00528         type_id = 1;
00529         // need to set nodetoTypeHash because of cycles
00530         st_insert (nodeToTypeHash, (char *) aFormula, (char *) type_id);
00531         setNodeType (net, (Fnode *) Reg_InitFunc (aFormula), nodeToTypeHash);
00532         setNodeType (net, (Fnode *) Reg_NsFunc (aFormula), nodeToTypeHash);
00533         break;
00534       case Not_c:
00535         // boolean type
00536         type_id = 1;
00537         setNodeType (net, (Fnode *) aFormula->lchild, nodeToTypeHash);
00538         break;
00539       case And_c:
00540       case Or_c:
00541         // The type depends on type of children
00542         lchild_type = setNodeType (net,
00543                                    (Fnode *) aFormula->lchild,
00544                                    nodeToTypeHash);
00545         assert ((lchild_type != -1) && (lchild_type > 0));
00546         rchild_type = setNodeType (net,
00547                                    (Fnode *) aFormula->rchild,
00548                                    nodeToTypeHash);
00549         assert ((rchild_type != -1) && (rchild_type > 0));
00550         assert (lchild_type == rchild_type);
00551         type_id = lchild_type;
00552         break;
00553       case Mux_c:
00554         control_type = setNodeType (net,
00555                                     (Fnode *) aFormula->lchild,
00556                                     nodeToTypeHash);
00557         lchild_type = setNodeType (net,
00558                                    (Fnode *) Mux_ThenInput (aFormula),
00559                                    nodeToTypeHash);
00560         assert ((lchild_type != -1) && (lchild_type > 0));
00561         rchild_type = setNodeType (net,
00562                                    (Fnode *) Mux_ElseInput (aFormula),
00563                                    nodeToTypeHash);
00564         assert ((rchild_type != -1) && (rchild_type > 0));
00565         assert (lchild_type == rchild_type);
00566         type_id = lchild_type;
00567         break;
00568       case Assign_c:
00569         lchild_type = setNodeType (net,
00570                                    (Fnode *) aFormula->lchild,
00571                                    nodeToTypeHash);
00572         assert ((lchild_type != -1) && (lchild_type > 0));
00573         type_id = lchild_type;
00574         break;
00575       case UnaryFunc_c:
00576       case Func_c:
00577         // undefined type
00578         //type_id = 0;
00579         // just set the type to scalar
00580         uif_input = aFormula->rchild;
00581         while (uif_input != nil)
00582           {
00583             assert (uif_input->lchild != nil);
00584             setNodeType (net, (Fnode *) uif_input->lchild, nodeToTypeHash);
00585             uif_input = uif_input->rchild;
00586           }
00587         type_id = 2;
00588         break;
00589       default:
00590         printf ("Panic, encountered unknown type of node in setNodeType\n");
00591         assert (0);
00592       }
00593     assert (type_id != -1);
00594     //insert type_id into nodeToTypeHash
00595     st_insert (nodeToTypeHash, (char *) aFormula, (char *) type_id);
00596     return type_id;
00597   }
00598 
00599 
00606   int
00607     Node_PrintVHDL (Net_t * net,
00608                     Fnode * formula,
00609                     FILE * fptr,
00610                     st_table * nodeToNameHash,
00611                     st_table * processedNodes,
00612                     st_table * uifInstantiateHash,
00613                     st_table * uifToNumInputs, int vector_width)
00614   {
00615     int id;
00616     char *name;
00617     char *lname;
00618     char *rname;
00619     char nodename[BUFFER_SIZE];
00620     assert (fptr);
00621     if (formula == nil)
00622       {
00623         return 0;
00624       }
00625     if (!st_lookup (net->nodeToId, (char *) formula, (char **) &id))
00626       {
00627         // assuming that it's a string so returning
00628         return 0;
00629       }
00630     if (st_lookup (processedNodes, (char *) formula, (char **) 0))
00631       {
00632         return 0;
00633       }
00634     st_insert (processedNodes, (char *) formula, (char *) 0);
00635     st_lookup (nodeToNameHash, (char *) formula, (char **) &name);
00636     sprintf (nodename, "Net_%d", id);
00637     Operator_t type = formula->type;
00638     switch (type)
00639       {
00640       case List_c:
00641       case Pair_c:
00642         // we should never try and print VHDL here
00643         assert (0);
00644         break;
00645       case Undef_c:
00646         // we should never try and print VHDL here
00647         assert (0);
00648         break;
00649       case ScalarPI_c:
00650       case BooleanPI_c:
00651       case InternalScalarVar_c:
00652       case InternalBooleanVar_c:
00653       case ScalarConst_c:
00654         // nothing to print
00655         break;
00656       case And_c:
00657         st_lookup (nodeToNameHash, (char *) formula->lchild,
00658                    (char **) &lname);
00659         st_lookup (nodeToNameHash, (char *) formula->rchild,
00660                    (char **) &rname);
00661         fprintf (fptr, "%s <= %s and %s;\n", name, lname, rname);
00662         Node_PrintVHDL (net, (Fnode *) formula->lchild, fptr, nodeToNameHash,
00663                         processedNodes, uifInstantiateHash, uifToNumInputs,
00664                         vector_width);
00665         Node_PrintVHDL (net, (Fnode *) formula->rchild, fptr, nodeToNameHash,
00666                         processedNodes, uifInstantiateHash, uifToNumInputs,
00667                         vector_width);
00668         break;
00669       case Or_c:
00670         st_lookup (nodeToNameHash, (char *) formula->lchild,
00671                    (char **) &lname);
00672         st_lookup (nodeToNameHash, (char *) formula->rchild,
00673                    (char **) &rname);
00674         fprintf (fptr, "%s <= %s or %s;\n", name, lname, rname);
00675         Node_PrintVHDL (net, (Fnode *) formula->lchild, fptr, nodeToNameHash,
00676                         processedNodes, uifInstantiateHash, uifToNumInputs,
00677                         vector_width);
00678         Node_PrintVHDL (net, (Fnode *) formula->rchild, fptr, nodeToNameHash,
00679                         processedNodes, uifInstantiateHash, uifToNumInputs,
00680                         vector_width);
00681         break;
00682       case Iff_c:
00683         st_lookup (nodeToNameHash, (char *) formula->lchild,
00684                    (char **) &lname);
00685         st_lookup (nodeToNameHash, (char *) formula->rchild,
00686                    (char **) &rname);
00687         fprintf (fptr, "%s <= '1' when %s = %s else '0';\n", name, lname,
00688                  rname);
00689         Node_PrintVHDL (net, (Fnode *) formula->lchild, fptr, nodeToNameHash,
00690                         processedNodes, uifInstantiateHash, uifToNumInputs,
00691                         vector_width);
00692         Node_PrintVHDL (net, (Fnode *) formula->rchild, fptr, nodeToNameHash,
00693                         processedNodes, uifInstantiateHash, uifToNumInputs,
00694                         vector_width);
00695         break;
00696       case Equal_c:
00697         st_lookup (nodeToNameHash, (char *) formula->lchild,
00698                    (char **) &lname);
00699         st_lookup (nodeToNameHash, (char *) formula->rchild,
00700                    (char **) &rname);
00701         fprintf (fptr, "%s <= '1' when %s = %s else '0';\n", name, lname,
00702                  rname);
00703         Node_PrintVHDL (net, (Fnode *) formula->lchild, fptr, nodeToNameHash,
00704                         processedNodes, uifInstantiateHash, uifToNumInputs,
00705                         vector_width);
00706         Node_PrintVHDL (net, (Fnode *) formula->rchild, fptr, nodeToNameHash,
00707                         processedNodes, uifInstantiateHash, uifToNumInputs,
00708                         vector_width);
00709         break;
00710       case ScalarReg_c:
00711         if (strstr ((char *) formula->lchild, "mem@") != NULL)
00712           {
00713             Net_InstantiateMemory (net, fptr, formula, nodeToNameHash,
00714                                    processedNodes, uifInstantiateHash,
00715                                    uifToNumInputs, vector_width);
00716             Node_PrintVHDL (net, (Fnode *) Reg_InitFunc (formula), fptr,
00717                             nodeToNameHash, processedNodes,
00718                             uifInstantiateHash, uifToNumInputs, vector_width);
00719           }
00720         else
00721           {
00722             st_lookup (nodeToNameHash, (char *) Reg_InitFunc (formula),
00723                        (char **) &lname);
00724             st_lookup (nodeToNameHash, (char *) Reg_NsFunc (formula),
00725                        (char **) &rname);
00726             // first setup the wrapper
00727             fprintf (fptr, "%s <= %s when dummy_init_val = '0' else %s;\n",
00728                      name, lname, nodename);
00729             // now setup the process
00730             fprintf (fptr,
00731                      "process(dummy_clock) begin\nif(dummy_clock = '1') then\n %s <= %s;\nend if;\nend process;\n",
00732                      nodename, rname);
00733             Node_PrintVHDL (net, (Fnode *) Reg_InitFunc (formula), fptr,
00734                             nodeToNameHash, processedNodes,
00735                             uifInstantiateHash, uifToNumInputs, vector_width);
00736             Node_PrintVHDL (net, (Fnode *) Reg_NsFunc (formula), fptr,
00737                             nodeToNameHash, processedNodes,
00738                             uifInstantiateHash, uifToNumInputs, vector_width);
00739           }
00740         break;
00741       case BooleanReg_c:
00742         st_lookup (nodeToNameHash, (char *) Reg_InitFunc (formula),
00743                    (char **) &lname);
00744         st_lookup (nodeToNameHash, (char *) Reg_NsFunc (formula),
00745                    (char **) &rname);
00746         // first setup the wrapper
00747         fprintf (fptr, "%s <= %s when dummy_init_val = '0' else %s;\n", name,
00748                  lname, nodename);
00749         // now setup the process
00750         fprintf (fptr,
00751                  "process(dummy_clock) begin\nif(dummy_clock = '1') then\n %s <= %s;\nend if;\nend process;\n",
00752                  nodename, rname);
00753         Node_PrintVHDL (net, (Fnode *) Reg_InitFunc (formula), fptr,
00754                         nodeToNameHash, processedNodes, uifInstantiateHash,
00755                         uifToNumInputs, vector_width);
00756         Node_PrintVHDL (net, (Fnode *) Reg_NsFunc (formula), fptr,
00757                         nodeToNameHash, processedNodes, uifInstantiateHash,
00758                         uifToNumInputs, vector_width);
00759         break;
00760       case Not_c:
00761         st_lookup (nodeToNameHash, (char *) formula->lchild,
00762                    (char **) &lname);
00763         fprintf (fptr, "%s <= NOT %s;\n", name, lname);
00764         Node_PrintVHDL (net, (Fnode *) formula->lchild, fptr, nodeToNameHash,
00765                         processedNodes, uifInstantiateHash, uifToNumInputs,
00766                         vector_width);
00767         break;
00768       case Mux_c:
00769         st_lookup (nodeToNameHash, (char *) Mux_ThenInput (formula),
00770                    (char **) &lname);
00771         st_lookup (nodeToNameHash, (char *) Mux_ElseInput (formula),
00772                    (char **) &rname);
00773         char *control_name;
00774         st_lookup (nodeToNameHash, (char *) formula->lchild,
00775                    (char **) &control_name);
00776         fprintf (fptr, "%s <= %s when %s = '1' else %s;\n", name, lname,
00777                  control_name, rname);
00778         Node_PrintVHDL (net, (Fnode *) formula->lchild, fptr, nodeToNameHash,
00779                         processedNodes, uifInstantiateHash, uifToNumInputs,
00780                         vector_width);
00781         Node_PrintVHDL (net, (Fnode *) Mux_ThenInput (formula), fptr,
00782                         nodeToNameHash, processedNodes, uifInstantiateHash,
00783                         uifToNumInputs, vector_width);
00784         Node_PrintVHDL (net, (Fnode *) Mux_ElseInput (formula), fptr,
00785                         nodeToNameHash, processedNodes, uifInstantiateHash,
00786                         uifToNumInputs, vector_width);
00787         break;
00788       case Assign_c:
00789         st_lookup (nodeToNameHash, (char *) formula->lchild,
00790                    (char **) &lname);
00791         fprintf (fptr, "%s <= %s;\n", name, lname);
00792         Node_PrintVHDL (net, (Fnode *) formula->lchild, fptr, nodeToNameHash,
00793                         processedNodes, uifInstantiateHash, uifToNumInputs,
00794                         vector_width);
00795         break;
00796       case UnaryFunc_c:
00797         /*assert(0); */
00798         if (strstr ((char *) formula->lchild, "mem@") == NULL)
00799           {
00800             Net_InstantiateUIF (net, fptr, formula, uifToNumInputs,
00801                                 nodeToNameHash, processedNodes,
00802                                 uifInstantiateHash, vector_width);
00803           }
00804         else
00805           {
00806             Node_PrintVHDL (net, Func_FirstArg (formula), fptr,
00807                             nodeToNameHash, processedNodes,
00808                             uifInstantiateHash, uifToNumInputs, vector_width);
00809           }
00810         break;
00811       case TRUE_c:
00812       case FALSE_c:
00813         // nothing to do
00814         break;
00815       case Func_c:
00816         /*assert(0); */
00817         if (strstr ((char *) formula->lchild, "mem@") == NULL)
00818           {
00819             Net_InstantiateUIF (net, fptr, formula, uifToNumInputs,
00820                                 nodeToNameHash, processedNodes,
00821                                 uifInstantiateHash, vector_width);
00822           }
00823         else
00824           {
00825             Node_PrintVHDL (net, Func_FirstArg (formula), fptr,
00826                             nodeToNameHash, processedNodes,
00827                             uifInstantiateHash, uifToNumInputs, vector_width);
00828           }
00829         break;
00830       default:
00831         printf ("Panic, encountered unknown type of node in print\n");
00832         assert (0);
00833       }
00834     fflush (fptr);
00835     return 0;
00836   }
00837 
00838 
00845   int Net_NodeGetId (Net_t * net, Fnode * formula)
00846   {
00847     int id;
00848     if (formula == nil)
00849       {
00850         return -1;
00851       }
00852     if (!st_lookup (net->nodeToId, (char *) formula, (char **) &id))
00853       {
00854         printf ("# What are you looking for???\n");
00855         return -1;
00856       }
00857     return id;
00858   }
00859 
00865   int Net_ConstrainInput (Net_t * net, char *input, Fnode * const_formula)
00866   {
00867 
00868     Fnode *formula = nil;
00869     assert (input != NULL);
00870     assert (const_formula != nil);
00871 
00872     formula = Net_NameToNode (net, input);
00873     if (formula == nil)
00874       {
00875         printf("was not able to find the node to constrain\n");
00876         return 0;
00877       }
00878     st_table *processedNodes =
00879       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
00880     // first update fanout array
00881     updateFanoutArray (net, const_formula, nil, processedNodes);
00882     // Now we will swap formula and const_formula
00883     swapNodes (net, formula, const_formula);
00884     printf("was able to find the node to constrain\n");
00885     return 0;
00886   }
00887 
00893   int Net_UnConstrainInput (Net_t * net, char *input, Fnode * const_formula)
00894   {
00895 
00896     Fnode *formula = nil;
00897     assert (input != NULL);
00898     assert (const_formula != nil);
00899 
00900     formula = Net_NameToNode (net, input);
00901     if (formula == nil)
00902       {
00903         return 0;
00904       }
00905     // Now we will swap formula and const_formula
00906     swapNodes (net, const_formula, formula);
00907     return 0;
00908   }
00909 
00917   Net_t* Net_ReplaceWritewithRead(Net_t *net,
00918                                  char *writeUifName,
00919                                  char *readUifName,
00920                                  int output_index) 
00921   {
00922     // First generate a random read address
00923     F readAddress = si("read_address");
00924     char *new_writeUifName = (char *) malloc (sizeof(char)*(strlen(writeUifName) + 2));
00925     strcpy(new_writeUifName, writeUifName);
00926 
00927     char *new_readUifName = (char *) malloc (sizeof(char)*(strlen(readUifName) + 2));
00928     strcpy(new_readUifName, readUifName);
00929 
00930     AddReadatEnd(net, readAddress.raw, new_readUifName, output_index);
00931     Net_t *new_net = Net_CreateFromFormula(array_fetch(Fnode *, net->formulas, 0));
00932     Net_FreeNet(net);
00933     
00934     Net_t *newer_net = NULL;
00935     // Now call the ReplaceWritewithRead till all writes have been replaced
00936     while(st_lookup(new_net->UIFs, new_writeUifName, (char **)0)) {
00937       ReplaceWritewithRead(new_net, new_writeUifName, new_readUifName);
00938       newer_net = Net_CreateFromFormula(array_fetch(Fnode*, new_net->formulas, 0));
00939       Net_FreeNet(new_net);
00940       new_net = newer_net;
00941     }
00942     return new_net;
00943   }    
00944 
00950 Fnode* Net_AccessOutput (Net_t *net,
00951                          int output_index) 
00952 {
00953   
00954   return array_fetch(Fnode *, net->formulas, output_index);
00955 }
00956 
00964 int Net_PrintVHDL (Net_t * net, int vector_width, char *fileName, char *entity_name)  
00965 {
00966   FILE *fptr = fopen(fileName, "w");
00967   Net_PrintVHDLInt(net, fptr, vector_width, entity_name);
00968   fclose(fptr);
00969   return 1;
00970 }
00971 
00978 int Net_SetMemSize (Net_t *net, char *memName, int memSize) 
00979 {
00980   
00981   assert(net != NIL (Net_t));
00982   assert(net->memToSizeHash != NIL (st_table));
00983   
00984   char *new_memName = (char *) malloc(sizeof(char)*strlen(memName));
00985   strcpy(new_memName, memName);
00986   // insert into the Hash
00987   st_insert(net->memToSizeHash, (char *) new_memName, (char *) memSize);
00988   return 1;
00989 }
00990 
00998 int Net_AnalyzeScalarBitWidth (Net_t *net) 
00999 {
01000   assert(net != NIL (Net_t));
01001   int i = 0, num_scalars = 0;
01002   double bit_width = 0.0;
01003   Fnode *instance = NIL (Fnode);
01004   
01005   for (i = 0; i < array_n (net->PIs); i++)
01006     {
01007       instance = array_fetch (Fnode *, net->PIs, i);
01008       if( instance->type == ScalarPI_c ) {
01009         num_scalars ++;
01010       }
01011     }
01012   
01013   printf("number of scalar inputs is %d\n", num_scalars);
01014   bit_width = (double) log(num_scalars) / (double) log(2);
01015   bit_width = ceil(bit_width);
01016   printf("bit width is %d\n", (int) bit_width);
01017   return (int) bit_width;
01018 }
01019 
01026 array_t *node_array_tfe (array_t * input_array, int N)
01027 {
01028   int i, j;
01029   array_t *result_array = array_alloc (Fnode *, 0);
01030   assert (N > 0);
01031   Net_t *net = Net_CreateFromFormulaArray (input_array);
01032   array_t *processedTableArray = array_alloc (st_table *, 0);
01033   array_t *newprocessedTableArray = array_alloc (st_table *, 0);
01034   for (i = 0; i < N; i++)
01035     {
01036       char suffix[100];
01037       sprintf (suffix, "_%d", i);
01038       st_table *processedTable =
01039         st_init_table ((int (*)()) st_ptrcmp, (int (*)()) st_ptrhash);
01040       array_insert_last (st_table *, processedTableArray, processedTable);
01041       st_table *newprocessedTable =
01042         st_init_table ((int (*)()) st_ptrcmp, (int (*)()) st_ptrhash);
01043       array_insert_last (st_table *, newprocessedTableArray,
01044                          newprocessedTable);
01045       for (j = 0; j < array_n (input_array); j++)
01046         {
01047           Fnode *formula = array_fetch (Fnode *, input_array, j);
01048           node_dup (net, formula, suffix, processedTable);
01049         }
01050     }
01051   for (j = 0; j < array_n (input_array); j++)
01052     {
01053       Fnode *formula = array_fetch (Fnode *, input_array, j);
01054       Fnode *result =
01055         getUnfoldedNode (net, formula, (N - 1), processedTableArray,
01056                          newprocessedTableArray);
01057       array_insert_last (Fnode *, result_array, result);
01058     }
01059   return result_array;
01060 }
01061 
01062 
01069   Fnode *node_tfe (Fnode * formula, int N)
01070   {
01071     Fnode *result;
01072     assert (N > 0);
01073     int i;
01074     Net_t *net = Net_CreateFromFormula (formula);
01075     //array_t *formulaArray = array_alloc( Fnode * , 0 );
01076     //HM: we will have an array of processedtables, each processedtable
01077     //stores the mapping of the original node to unfolded node, i.e X to X_N
01078     //array_t *processedTableArray = array_alloc(st_table *, 0);
01079     array_t *newprocessedTableArray = array_alloc (st_table *, 0);
01080 
01081     for (i = 0; i < N; i++)
01082       {
01083         char suffix[100];
01084         sprintf (suffix, "_%d", i);
01085         //st_table *processedTable = st_init_table( (int (*)()) st_ptrcmp, (int (*)()) st_ptrhash );
01086         //array_insert_last(st_table *, processedTableArray, processedTable);
01087         st_table *newprocessedTable =
01088           st_init_table ((int (*)()) st_ptrcmp, (int (*)()) st_ptrhash);
01089         array_insert_last (st_table *, newprocessedTableArray,
01090                            newprocessedTable);
01091         //Fnode * stepI = node_dup( net, formula, suffix, processedTable );
01092         //array_insert_last( Fnode * , formulaArray, stepI );
01093       }
01094 
01095     // We now call the new function getUnfoldedNode2
01096     //result = getUnfoldedNode(net, formula, (N-1), processedTableArray, newprocessedTableArray);
01097     result = getUnfoldedNode2 (net, formula, (N - 1), newprocessedTableArray);
01098     return result;
01099   }
01100 
01105   int Net_PrintFormula (Net_t * net, Fnode * formula, char *filename)
01106   {
01107     st_table *processedTable =
01108       st_init_table ((int (*)()) st_ptrcmp, (int (*)()) st_ptrhash);
01109     if(filename) {
01110       FILE *fptr = fopen (filename, "w");
01111       Net_PrintFormulaInt (net, formula, processedTable, fptr);
01112       fclose (fptr);
01113     }
01114     else {
01115       Net_PrintFormulaInt (net, formula, processedTable, stdout);
01116     }
01117     st_free_table (processedTable);
01118     return 0;
01119   }
01120 
01121 
01122 /*---------------------------------------------------------------------------*/
01123 /* Definition of static functions                                            */
01124 /*---------------------------------------------------------------------------*/
01125 
01138   static Fnode *createBryantNode (array_t * BryantNodeArray,
01139                                   array_t * uArray, array_t * vArray, int i)
01140   {
01141     int j;
01142     Fnode *u_i = array_fetch (Fnode *, uArray, i);
01143     array_t *eqChecks = array_alloc (Fnode *, 0);
01144     for (j = 0; j < i; j++)
01145       {
01146         Fnode *u_j = array_fetch (Fnode *, uArray, j);
01147         Fnode *eqNode = computeEqNode (u_i, u_j);
01148         array_insert_last (Fnode *, eqChecks, eqNode);
01149       }
01150     Fnode *bryantNode = createBryantNodeIteratively (eqChecks, vArray, i);
01151     array_insert_last (Fnode *, BryantNodeArray, bryantNode);
01152     return bryantNode;
01153   }
01154 
01155 
01162   static Fnode *createBryantNodeIteratively (array_t * eqChecks,
01163                                              array_t * vArray, int i)
01164   {
01165     if (i == 0)
01166       {
01167         // there's no muxes, so use the fresh input
01168         Fnode *result = array_fetch (Fnode *, vArray, 0);
01169         return result;
01170       }
01171 
01172     // recall i goes from 0 to n-1 
01173     // we need i muxes, so allocate them now
01174     array_t *muxes = array_alloc (Fnode *, 0);
01175     int j;
01176     // AA: is there a danger that by registering before the node is
01177     // fully ready we're doing some damage?
01178 
01179     // HM: Not sure why this code is here? Commenting it out for now 09/01
01180     //Fnode*  tmpMux;
01181     //Fnode*  elseInput = array_fetch( Fnode *, vArray, i );
01182     //for( j = i-1 ; j >= 0; j-- ) {
01183     //Fnode*  control = array_fetch( Fnode * , eqChecks, j ); 
01184     //Fnode*  BryantNode_j = array_fetch( Fnode * , vArray, j );
01185     //Fnode *aPair = *BryantNode_j % elseInput;
01186     //tmpMux = new_node( Mux_c, control, aPair );
01187     //elseInput = (Fnode*) tmpMux;
01188     //}
01189     //return tmpMux;
01190 
01191     for (j = 0; j < i; j++)
01192       {
01193         // set control inputs to the muxes
01194         // the first mux in the array is the one closest to the output
01195         Fnode *control = array_fetch (Fnode *, eqChecks, j);
01196         Fnode *v_j = array_fetch (Fnode *, vArray, j);
01197         Fnode *mux = new_node_raw (Mux_c, nil, nil);
01198         // the right child consists of a list of length two
01199         // with the data input to the mux, first is the IF match
01200         mux->lchild = control;
01201         //mux->rchild = new_node_raw( Pair_c, BryantNode_j, nil );
01202         mux->rchild = new_node_raw (Pair_c, v_j, nil);
01203         // we can't set the ELSE match, because it's coming from the next mux,
01204         // which we haven't allocated yet.
01205         array_insert_last (Fnode *, muxes, mux);
01206       }
01207 
01208     // now we set the ELSE branches for the first i-1 muxes (the i-th one is special,
01209     // since it takes the fresh variable v_i as its ELSE branch
01210     for (j = 0; j < i - 1; j++)
01211       {
01212         Fnode *mux_j = array_fetch (Fnode *, muxes, j);
01213         Fnode *mux_j_plus_1 = array_fetch (Fnode *, muxes, j + 1);
01214         ((Fnode *) mux_j->rchild)->rchild = mux_j_plus_1;
01215       }
01216     // now set the last mux ELSE input to the fresh var v_i
01217     Fnode *v_i = array_fetch (Fnode *, vArray, i);
01218     Fnode *mux_i_minus_1 = array_fetch (Fnode *, muxes, i - 1);
01219     // Fnode * elseNode = new_node( List_c, v_i, nil );
01220     Fnode *elseNode = v_i;
01221     ((Fnode *) mux_i_minus_1->rchild)->rchild = elseNode;
01222 
01223     // HM: registering of muxes was causing bad memory accesses; commenting out 09/01
01224     // now register the muxes
01225     //for ( j = 0; j < i-1; j++ ) {
01226     //Fnode * mux_j = array_fetch( Fnode * , muxes, j );
01227     // we should prob normalize the children of mux_j too, but
01228     // that's not going to get us any minimization here so skipping it
01229     //Fnode * reg_mux_j = node_register( mux_j );
01230     //array_insert( Fnode * , muxes, j, reg_mux_j );
01231     //}
01232 
01233 
01234     // the result is the first mux
01235     Fnode *result = array_fetch (Fnode *, muxes, 0);
01236 
01237     return result;
01238   }
01239 
01248   static Fnode *computeEqNode (Fnode * u_i, Fnode * u_j)
01249   {
01250     Fnode *eqNode;
01251 
01252     if (u_i->type != List_c)
01253       {
01254         eqNode = new_node (Equal_c, u_i, u_j);
01255       }
01256     else
01257       {
01258         eqNode = createEqNodeFromLists (u_i, u_j);
01259       }
01260     return eqNode;
01261   }
01262 
01270   static Fnode *createEqNodeFromLists (Fnode * aList, Fnode * bList)
01271   {
01272     Fnode *aNode = new_node (Equal_c, car (aList), car (bList));
01273     if (cdr (aList) == nil)
01274       {
01275         return aNode;
01276       }
01277     else
01278       {
01279         Fnode *restEqNode = createEqNodeFromLists (cdr (aList), cdr (bList));
01280         Fnode *result = new_node (And_c, aNode, restEqNode);
01281         return result;
01282       }
01283     return nil;                 // should never get here
01284   }
01285 
01286 
01295   static int swapNodes (Net_t * net, Fnode * A, Fnode * B)
01296   {
01297     int i;
01298     array_t *newOutputArray = array_alloc (Fnode *, 0);
01299     for (i = 0; i < array_n (net->formulas); i++)
01300       {
01301         Fnode *net_formula = array_fetch (Fnode *, net->formulas, i);
01302         if (A == net_formula)
01303           {
01304             // need to update the root of net
01305             array_insert_last (Fnode *, newOutputArray, B);
01306           }
01307         else
01308           {
01309             array_insert_last (Fnode *, newOutputArray, net_formula);
01310           }
01311       }
01312     net->formulas = newOutputArray;
01313     array_t *fanoutArray, *BfanoutArray;
01314     st_lookup (net->nodeToFanoutArray, (char *) A, (char **) &fanoutArray);
01315     st_lookup (net->nodeToFanoutArray, (char *) B, (char **) &BfanoutArray);
01316     for (i = 0; i < array_n (fanoutArray); i++)
01317       {
01318         Fnode *fanoutNode = array_fetch (Fnode *, fanoutArray, i);
01319         if ((fanoutNode->lchild == A) || (fanoutNode->rchild == A))
01320           {
01321             if (fanoutNode->lchild == A)
01322               {
01323                 fanoutNode->lchild = B;
01324               }
01325             // dont do an else since both the fanins of fanout node may be A
01326             if (fanoutNode->rchild == A)
01327               {
01328                 fanoutNode->rchild = B;
01329               }
01330             // We need to update B's fanout array
01331             array_insert_last (Fnode *, BfanoutArray, fanoutNode);
01332           }
01333       }
01334     return 1;
01335   }
01336 
01337 
01344   static Fnode *getUnfoldedNode (Net_t * net,
01345                                  Fnode * formula,
01346                                  int depth,
01347                                  array_t * processedTableArray,
01348                                  array_t * newprocessedTableArray)
01349   {
01350     Fnode *result;
01351     char suf[100];
01352     sprintf (suf, "_%d", depth);
01353     st_table *processedTable =
01354       array_fetch (st_table *, processedTableArray, depth);
01355     st_table *newprocessedTable =
01356       array_fetch (st_table *, newprocessedTableArray, depth);
01357     // return nil if formula itself is nil
01358     if (formula == nil)
01359       {
01360         return nil;
01361       }
01362     if (st_lookup (newprocessedTable, (char *) formula, (char **) &result))
01363       {
01364         return result;
01365       }
01366 
01367     // if it is a string, let us get unfolded string name 
01368     if (!st_lookup (net->nodeToId, (char *) formula, (char **) 0))
01369       {
01370         // must be a string if it's not nil and not a formula
01371         // use rs to preserve canonicity
01372         char *newName = (char *) rs (util_strcat ((char *) formula, suf));
01373         return (Fnode *) newName;
01374       }
01375     // if the formula is a register
01376     if ((formula->type == ScalarReg_c) || (formula->type == BooleanReg_c))
01377       {
01378         /* if depth is 0, we will get unfolded node for initial value node
01379          * else, we will get unfolded node for next state node */
01380         if (depth == 0)
01381           {
01382             result =
01383               getUnfoldedNode (net, Reg_InitFunc (formula), depth,
01384                                processedTableArray, newprocessedTableArray);
01385           }
01386         else
01387           {
01388             result =
01389               getUnfoldedNode (net, Reg_NsFunc (formula), (depth - 1),
01390                                processedTableArray, newprocessedTableArray);
01391           }
01392       }
01393     else
01394       {
01395         if (!st_lookup (processedTable, (char *) formula, (char **) &result))
01396           {
01397             assert (0);
01398             return nil;
01399           }
01400         // result corresponds to unfolded node at depth "depth" 
01401         // We would have to connect its inputs carefully though
01402         if ((formula->type == UnaryFunc_c) ||
01403             (formula->type == Func_c) || (formula->type == ScalarConst_c))
01404           {
01405             /* Need not modify their names */
01406           }
01407         else
01408           {
01409             Fnode *lchild =
01410               getUnfoldedNode (net, (Fnode *) formula->lchild, depth,
01411                                processedTableArray, newprocessedTableArray);
01412             result->lchild = lchild;
01413           }
01414         Fnode *rchild =
01415           getUnfoldedNode (net, (Fnode *) formula->rchild, depth,
01416                            processedTableArray, newprocessedTableArray);
01417         result->rchild = rchild;
01418       }
01419     st_insert (newprocessedTable, (char *) formula, (char *) result);
01420     return result;
01421   }
01422 
01428   static int
01429     updateFanoutArray (Net_t * net,
01430                        Fnode * aFormula,
01431                        Fnode * parentFormula, st_table * processedNodes)
01432   {
01433 
01434     if (aFormula == nil)
01435       {
01436         return 0;
01437       }
01438     assert (aFormula->type <= ScalarConst_c);
01439     // need to update the fanouts even if we've seen this 
01440     // node before, since the edge is fresh
01441     array_t *fanoutArray;
01442     if (!st_lookup
01443         (net->nodeToFanoutArray, (char *) aFormula, (char **) &fanoutArray))
01444       {
01445         fanoutArray = array_alloc (Fnode *, 0);
01446         st_insert (net->nodeToFanoutArray, (char *) aFormula,
01447                    (char *) fanoutArray);
01448       }
01449     // the initial call is made with the root formula, and nil for its 
01450     // parent so we need to check this
01451     if (parentFormula != nil)
01452       {
01453         array_insert_last (Fnode *, fanoutArray, parentFormula);
01454       }
01455     if (st_lookup (processedNodes, (char *) aFormula, (char **) 0))
01456       {
01457         return 0;
01458       }
01459     st_insert (processedNodes, (char *) aFormula, (char *) 0);
01460 
01461     if (Node_HasLeftChildNode ((Fnode *) aFormula))
01462       {
01463         updateFanoutArray (net, (Fnode *) aFormula->lchild,
01464                            (Fnode *) aFormula, processedNodes);
01465       }
01466     if (Node_HasRightChildNode ((Fnode *) aFormula))
01467       {
01468         updateFanoutArray (net, (Fnode *) aFormula->rchild,
01469                            (Fnode *) aFormula, processedNodes);
01470       }
01471     return 0;
01472   }
01473 
01478   static void Net_AnalyzeMemory (Net_t * net, FILE * fptr, Fnode * aFormula)
01479   {
01480     assert (aFormula != nil);
01481 
01482     Fnode *nextState = nil;
01483     nextState = (Fnode *) Reg_NsFunc (aFormula);
01484     assert (nextState != nil);
01485     assert (nextState->type == Mux_c);
01486     Fnode *thenInput = (Fnode *) Mux_ThenInput (nextState);
01487     Fnode *elseInput = (Fnode *) Mux_ElseInput (nextState);
01488     assert ((thenInput->type == Func_c) || (elseInput->type == Func_c));
01489 
01490     // Now we need to analyze the number of read ports
01491     array_t *fanoutArray;
01492     int num_read_ports = 0, i = 0, j = 0, num_write_ports = 0;
01493     st_lookup (net->nodeToFanoutArray, (char *) aFormula,
01494                (char **) &fanoutArray);
01495     //printf("number of fanout nodes is %d\n", array_n(fanoutArray));
01496     for (i = 0; i < array_n (fanoutArray); i++)
01497       {
01498         Fnode *fanoutNode = array_fetch (Fnode *, fanoutArray, i);
01499         if (fanoutNode->type == List_c)
01500           {
01501             array_t *fanoutArray2;
01502             //printf("The fanout node is a list\n");
01503             st_lookup (net->nodeToFanoutArray, (char *) fanoutNode,
01504                        (char **) &fanoutArray2);
01505             for (j = 0; j < array_n (fanoutArray2); j++)
01506               {
01507                 Fnode *fanoutNode2 = array_fetch (Fnode *, fanoutArray2, j);
01508                 if (fanoutNode2->type == Func_c)
01509                   {
01510                     //printf("the list fanouts to a func %s\n", (char *) fanoutNode2->lchild);
01511                     if (strstr ((char *) fanoutNode2->lchild, "mem@") != NULL)
01512                       {
01513                         num_read_ports++;
01514                       }
01515                     else if (strstr ((char *) fanoutNode2->lchild, "mem#") !=
01516                              NULL)
01517                       {
01518                         num_write_ports++;
01519                       }
01520                   }
01521               }
01522           }
01523       }
01524     assert (num_read_ports <= 8);
01525     assert (num_write_ports <= 2);
01526 
01527     fprintf (fptr, "component memory_model generic (\n");
01528     fprintf (fptr, "width: integer;\n");
01529     fprintf (fptr, "addrtotal : integer);\n");
01530     fprintf (fptr, "PORT (\n");
01531     fprintf (fptr,
01532              "            initial_value : in std_ulogic_vector (0 to width-1);\n");
01533     fprintf (fptr, "            write_enable1 : in std_ulogic;\n");
01534     fprintf (fptr,
01535              "            write_address1 : in std_ulogic_vector(0 to width-1);\n");
01536     fprintf (fptr,
01537              "            write_data1 : in std_ulogic_vector (0 to width-1);\n");
01538     fprintf (fptr, "            write_enable2 : in std_ulogic;\n");
01539     fprintf (fptr,
01540              "            write_address2 : in std_ulogic_vector (0 to width-1);\n");
01541     fprintf (fptr,
01542              "            write_data2 : in std_ulogic_vector (0 to width-1);\n");
01543     fprintf (fptr,
01544              "            read_address1 : in std_ulogic_vector (0 to width-1);\n");
01545     fprintf (fptr,
01546              "            read_data1 : out std_ulogic_vector(0 to width-1);\n");
01547     fprintf (fptr,
01548              "            read_address2 : in std_ulogic_vector (0 to width-1);\n");
01549     fprintf (fptr,
01550              "            read_data2 : out std_ulogic_vector(0 to width-1);\n");
01551     fprintf (fptr,
01552              "            read_address3 : in std_ulogic_vector (0 to width-1);\n");
01553     fprintf (fptr,
01554              "            read_data3 : out std_ulogic_vector(0 to width-1);\n");
01555     fprintf (fptr,
01556              "            read_address4 : in std_ulogic_vector (0 to width-1);\n");
01557     fprintf (fptr,
01558              "            read_data4 : out std_ulogic_vector(0 to width-1);\n");
01559     fprintf (fptr,
01560              "            read_address5 : in std_ulogic_vector (0 to width-1);\n");
01561     fprintf (fptr,
01562              "            read_data5 : out std_ulogic_vector(0 to width-1);\n");
01563     fprintf (fptr,
01564              "            read_address6 : in std_ulogic_vector (0 to width-1);\n");
01565     fprintf (fptr,
01566              "            read_data6 : out std_ulogic_vector(0 to width-1);\n");
01567     fprintf (fptr,
01568              "            read_address7 : in std_ulogic_vector (0 to width-1);\n");
01569     fprintf (fptr,
01570              "            read_data7 : out std_ulogic_vector(0 to width-1);\n");
01571     fprintf (fptr,
01572              "            read_address8 : in std_ulogic_vector (0 to width-1);\n");
01573     fprintf (fptr,
01574              "            read_data8 : out std_ulogic_vector(0 to width-1)\n");
01575     fprintf (fptr, "                                   );\n");
01576     fprintf (fptr, "end component;\n");
01577     return;
01578   }
01579 
01585   static void
01586     Net_InstantiateMemory (Net_t * net,
01587                            FILE * fptr,
01588                            Fnode * aFormula,
01589                            st_table * nodeToNameHash,
01590                            st_table * processedNodes,
01591                            st_table * uifInstantiateHash,
01592                            st_table * uifToNumInputs, int vector_width)
01593   {
01594     assert (aFormula != nil);
01595     assert (nodeToNameHash != NIL (st_table));
01596     assert (processedNodes != NIL (st_table));
01597     assert (uifInstantiateHash != NIL (st_table));
01598     assert (uifToNumInputs != NIL (st_table));
01599 
01600     int invert_ctrl_input1 = 0, invert_ctrl_input2 = 0, memsize = 0;
01601     
01602     Fnode *nextState = nil;
01603     Fnode *writeDataNode1 = nil, *writeAddressNode1 = nil, *writeDataNode2 =
01604       nil, *writeAddressNode2 = nil;
01605     char *readaddress1, *readdata1, *readaddress2, *readdata2, *readaddress3,
01606       *readdata3, *readaddress4, *readdata4, *readaddress5, *readdata5;
01607     char *readaddress6, *readdata6, *readaddress7, *readdata7, *readaddress8,
01608       *readdata8;
01609     char *writeenable1, *writeaddress1, *writedata1, *writeenable2,
01610       *writeaddress2, *writedata2;
01611     char *memory_name = (char *) alloca (512), *print_mem_name = NULL;
01612     Fnode *initState = nil;
01613     char *initname;
01614     initState = (Fnode *) Reg_InitFunc (aFormula);
01615     assert (initState != nil);
01616     st_lookup (nodeToNameHash, (char *) initState, (char **) &initname);
01617 
01618     // Now we need to analyze the number of read  and write ports
01619     array_t *fanoutArray;
01620     array_t *readPortArray = array_alloc (Fnode *, 0);
01621     int num_read_ports = 0, i = 0, j = 0, num_write_ports = 0;
01622     st_lookup (net->nodeToFanoutArray, (char *) aFormula,
01623                (char **) &fanoutArray);
01624     for (i = 0; i < array_n (fanoutArray); i++)
01625       {
01626         Fnode *fanoutNode = array_fetch (Fnode *, fanoutArray, i);
01627         if (fanoutNode->type == List_c)
01628           {
01629             array_t *fanoutArray2;
01630             st_lookup (net->nodeToFanoutArray, (char *) fanoutNode,
01631                        (char **) &fanoutArray2);
01632             for (j = 0; j < array_n (fanoutArray2); j++)
01633               {
01634                 Fnode *fanoutNode2 = array_fetch (Fnode *, fanoutArray2, j);
01635                 if (fanoutNode2->type == Func_c)
01636                   {
01637                     if (strstr ((char *) fanoutNode2->lchild, "mem@") != NULL)
01638                       {
01639                         array_insert_last (Fnode *, readPortArray,
01640                                            fanoutNode2);
01641                         num_read_ports++;
01642                       }
01643                     else if (strstr ((char *) fanoutNode2->lchild, "mem#") !=
01644                              NULL)
01645                       {
01646                         num_write_ports++;
01647                       }
01648                   }
01649               }
01650           }
01651       }
01652 
01653     nextState = (Fnode *) Reg_NsFunc (aFormula);
01654     assert (nextState != nil);
01655     assert (nextState->type == Mux_c);
01656     Fnode *thenInput = (Fnode *) Mux_ThenInput (nextState);
01657     Fnode *elseInput = (Fnode *) Mux_ElseInput (nextState);
01658     Fnode *ctrlInput = nextState->lchild;
01659     Fnode *secondThenInput = nil, *secondElseInput = nil, *secondCtrlInput =
01660       nil;
01661     assert ((thenInput->type == Func_c) || (elseInput->type == Func_c));
01662 
01663     st_lookup (nodeToNameHash, (char *) ctrlInput, (char **) &writeenable1);
01664 
01665     if (thenInput->type == Func_c)
01666       {
01667         invert_ctrl_input1 = 0;
01668         assert (strstr ((char *) thenInput->lchild, "mem#") != NULL);
01669         writeAddressNode1 = Func_SecondArg (thenInput);
01670         writeDataNode1 = Func_ThirdArg (thenInput);
01671         st_lookup (nodeToNameHash, (char *) Func_SecondArg (thenInput),
01672                    (char **) &writeaddress1);
01673         st_lookup (nodeToNameHash, (char *) Func_ThirdArg (thenInput),
01674                    (char **) &writedata1);
01675         if (num_write_ports == 2)
01676           {
01677             assert (elseInput->type == Mux_c);
01678             secondThenInput = (Fnode *) Mux_ThenInput (elseInput);
01679             secondElseInput = (Fnode *) Mux_ElseInput (elseInput);
01680             secondCtrlInput = (Fnode *) elseInput->lchild;
01681             assert ((secondThenInput->type == Func_c)
01682                     || (secondElseInput->type == Func_c));
01683 
01684             st_lookup (nodeToNameHash, (char *) secondCtrlInput,
01685                        (char **) &writeenable2);
01686             if (secondThenInput->type == Func_c)
01687               {
01688                 invert_ctrl_input2 = 0;
01689                 assert (strstr ((char *) secondThenInput->lchild, "mem#") !=
01690                         NULL);
01691                 writeAddressNode2 = Func_SecondArg (secondThenInput);
01692                 writeDataNode2 = Func_ThirdArg (secondThenInput);
01693                 st_lookup (nodeToNameHash,
01694                            (char *) Func_SecondArg (secondThenInput),
01695                            (char **) &writeaddress2);
01696                 st_lookup (nodeToNameHash,
01697                            (char *) Func_ThirdArg (secondThenInput),
01698                            (char **) &writedata2);
01699               }
01700             else
01701               {
01702                 invert_ctrl_input2 = 0;
01703                 assert (strstr ((char *) secondElseInput->lchild, "mem#") !=
01704                         NULL);
01705                 writeAddressNode2 = Func_SecondArg (secondElseInput);
01706                 writeDataNode2 = Func_ThirdArg (secondElseInput);
01707                 st_lookup (nodeToNameHash,
01708                            (char *) Func_SecondArg (secondElseInput),
01709                            (char **) &writeaddress2);
01710                 st_lookup (nodeToNameHash,
01711                            (char *) Func_ThirdArg (secondElseInput),
01712                            (char **) &writedata2);
01713               }
01714           }
01715       }
01716     else
01717       {
01718         invert_ctrl_input1 = 1;
01719         assert (strstr ((char *) elseInput->lchild, "mem#") != NULL);
01720         writeAddressNode1 = Func_SecondArg (elseInput);
01721         writeDataNode1 = Func_ThirdArg (elseInput);
01722         st_lookup (nodeToNameHash, (char *) Func_SecondArg (elseInput),
01723                    (char **) &writeaddress1);
01724         st_lookup (nodeToNameHash, (char *) Func_ThirdArg (elseInput),
01725                    (char **) &writedata1);
01726         // code for two write ports
01727         if (num_write_ports == 2)
01728           {
01729             assert (thenInput->type == Mux_c);
01730             secondThenInput = (Fnode *) Mux_ThenInput (thenInput);
01731             secondElseInput = (Fnode *) Mux_ElseInput (thenInput);
01732             secondCtrlInput = (Fnode *) thenInput->lchild;
01733             assert ((secondThenInput->type == Func_c)
01734                     || (secondElseInput->type == Func_c));
01735 
01736             st_lookup (nodeToNameHash, (char *) secondCtrlInput,
01737                        (char **) &writeenable2);
01738             if (secondThenInput->type == Func_c)
01739               {
01740                 invert_ctrl_input2 = 0;
01741                 assert (strstr ((char *) secondThenInput->lchild, "mem#") !=
01742                         NULL);
01743                 writeAddressNode2 = Func_SecondArg (secondThenInput);
01744                 writeDataNode2 = Func_ThirdArg (secondThenInput);
01745                 st_lookup (nodeToNameHash,
01746                            (char *) Func_SecondArg (secondThenInput),
01747                            (char **) &writeaddress2);
01748                 st_lookup (nodeToNameHash,
01749                            (char *) Func_ThirdArg (secondThenInput),
01750                            (char **) &writedata2);
01751               }
01752             else
01753               {
01754                 invert_ctrl_input2 = 0;
01755                 assert (strstr ((char *) secondElseInput->lchild, "mem#") !=
01756                         NULL);
01757                 writeAddressNode2 = Func_SecondArg (secondElseInput);
01758                 writeDataNode2 = Func_ThirdArg (secondElseInput);
01759                 st_lookup (nodeToNameHash,
01760                            (char *) Func_SecondArg (secondElseInput),
01761                            (char **) &writeaddress2);
01762                 st_lookup (nodeToNameHash,
01763                            (char *) Func_ThirdArg (secondElseInput),
01764                            (char **) &writedata2);
01765               }
01766           }
01767       }
01768 
01769 
01770     Fnode *readDataNode1, *readAddressNode1, *readDataNode2,
01771       *readAddressNode2, *readDataNode3, *readAddressNode3, *readDataNode4,
01772       *readAddressNode4, *readDataNode5, *readAddressNode5;
01773     Fnode *readDataNode6, *readAddressNode6, *readDataNode7,
01774       *readAddressNode7, *readDataNode8, *readAddressNode8;
01775 
01776     strcpy (memory_name, (char *) aFormula->lchild);
01777     if(!st_lookup(net->memToSizeHash, (char *) memory_name, (char **) &memsize)) {
01778       memsize = DEFAULT_MEM_SIZE;
01779     }
01780     strtok (memory_name, "@");
01781     print_mem_name = strtok (NULL, "@");
01782 
01783     switch (num_read_ports)
01784       {
01785       case 1:
01786         assert (num_write_ports == 1);
01787         readDataNode1 = array_fetch (Fnode *, readPortArray, 0);
01788         assert (readDataNode1 != nil);
01789         assert (readDataNode1->type == Func_c);
01790         st_lookup (nodeToNameHash, (char *) readDataNode1,
01791                    (char **) &readdata1);
01792         readAddressNode1 = Func_SecondArg (readDataNode1);
01793         assert (readAddressNode1 != nil);
01794         st_lookup (nodeToNameHash, (char *) readAddressNode1,
01795                    (char **) &readaddress1);
01796         // now instantiate the memory
01797         fprintf (fptr,
01798                  "memory_%s: memory_model generic map (width => %d, addrtotal => %d)\n",
01799                  print_mem_name, vector_width, memsize);
01800         fprintf (fptr, "port map(initial_value => %s,\n", initname);
01801         if (invert_ctrl_input1)
01802           {
01803             fprintf (fptr,
01804                      "                                    write_enable1 => not (%s),\n",
01805                      writeenable1);
01806           }
01807         else
01808           {
01809             fprintf (fptr,
01810                      "                                    write_enable1 => %s,\n",
01811                      writeenable1);
01812           }
01813         fprintf (fptr,
01814                  "                                        write_address1 => %s,\n",
01815                  writeaddress1);
01816         fprintf (fptr,
01817                  "                                        write_data1 => %s,\n",
01818                  writedata1);
01819         fprintf (fptr,
01820                  "                                        read_address1 => %s,\n",
01821                  readaddress1);
01822         fprintf (fptr,
01823                  "                                        read_data1 => %s);\n",
01824                  readdata1);
01825         // call node printvhdl on all the relevant nodes
01826         Node_PrintVHDL (net, initState, fptr, nodeToNameHash, processedNodes,
01827                         uifInstantiateHash, uifToNumInputs, vector_width);
01828         Node_PrintVHDL (net, ctrlInput, fptr, nodeToNameHash, processedNodes,
01829                         uifInstantiateHash, uifToNumInputs, vector_width);
01830         Node_PrintVHDL (net, writeDataNode1, fptr, nodeToNameHash,
01831                         processedNodes, uifInstantiateHash, uifToNumInputs,
01832                         vector_width);
01833         Node_PrintVHDL (net, writeAddressNode1, fptr, nodeToNameHash,
01834                         processedNodes, uifInstantiateHash, uifToNumInputs,
01835                         vector_width);
01836         Node_PrintVHDL (net, readAddressNode1, fptr, nodeToNameHash,
01837                         processedNodes, uifInstantiateHash, uifToNumInputs,
01838                         vector_width);
01839         break;
01840       case 2:
01841         assert (num_write_ports == 1);
01842         // first read port
01843         readDataNode1 = array_fetch (Fnode *, readPortArray, 0);
01844         assert (readDataNode1 != nil);
01845         assert (readDataNode1->type == Func_c);
01846         st_lookup (nodeToNameHash, (char *) readDataNode1,
01847                    (char **) &readdata1);
01848         readAddressNode1 = Func_SecondArg (readDataNode1);
01849         assert (readAddressNode1 != nil);
01850         st_lookup (nodeToNameHash, (char *) readAddressNode1,
01851                    (char **) &readaddress1);
01852         // second read port
01853         readDataNode2 = array_fetch (Fnode *, readPortArray, 1);
01854         assert (readDataNode2 != nil);
01855         assert (readDataNode2->type == Func_c);
01856         st_lookup (nodeToNameHash, (char *) readDataNode2,
01857                    (char **) &readdata2);
01858         readAddressNode2 = Func_SecondArg (readDataNode2);
01859         assert (readAddressNode2 != nil);
01860         st_lookup (nodeToNameHash, (char *) readAddressNode2,
01861                    (char **) &readaddress2);
01862         // now instantiate the memory
01863         fprintf (fptr,
01864                  "memory_%s: memory_model generic map (width => %d, addrtotal => %d)\n",
01865                  print_mem_name, vector_width, memsize);
01866         fprintf (fptr, "port map(initial_value => %s,\n", initname);
01867         if (invert_ctrl_input1)
01868           {
01869             fprintf (fptr,
01870                      "                                    write_enable1 => not (%s),\n",
01871                      writeenable1);
01872           }
01873         else
01874           {
01875             fprintf (fptr,
01876                      "                                    write_enable1 => %s,\n",
01877                      writeenable1);
01878           }
01879         fprintf (fptr,
01880                  "                                        write_address1 => %s,\n",
01881                  writeaddress1);
01882         fprintf (fptr,
01883                  "                                        write_data1 => %s,\n",
01884                  writedata1);
01885         fprintf (fptr,
01886                  "                                        read_address1 => %s,\n",
01887                  readaddress1);
01888         fprintf (fptr,
01889                  "                                        read_data1 => %s,\n",
01890                  readdata1);
01891         fprintf (fptr,
01892                  "                                        read_address2 => %s,\n",
01893                  readaddress2);
01894         fprintf (fptr,
01895                  "                                        read_data2 => %s);\n",
01896                  readdata2);
01897         // call node printvhdl on all the relevant nodes
01898         Node_PrintVHDL (net, initState, fptr, nodeToNameHash, processedNodes,
01899                         uifInstantiateHash, uifToNumInputs, vector_width);
01900         Node_PrintVHDL (net, ctrlInput, fptr, nodeToNameHash, processedNodes,
01901                         uifInstantiateHash, uifToNumInputs, vector_width);
01902         Node_PrintVHDL (net, writeDataNode1, fptr, nodeToNameHash,
01903                         processedNodes, uifInstantiateHash, uifToNumInputs,
01904                         vector_width);
01905         Node_PrintVHDL (net, writeAddressNode1, fptr, nodeToNameHash,
01906                         processedNodes, uifInstantiateHash, uifToNumInputs,
01907                         vector_width);
01908         Node_PrintVHDL (net, readAddressNode1, fptr, nodeToNameHash,
01909                         processedNodes, uifInstantiateHash, uifToNumInputs,
01910                         vector_width);
01911         Node_PrintVHDL (net, readAddressNode2, fptr, nodeToNameHash,
01912                         processedNodes, uifInstantiateHash, uifToNumInputs,
01913                         vector_width);
01914         break;
01915       case 3:
01916         // first read port
01917         assert (num_write_ports == 1);
01918         readDataNode1 = array_fetch (Fnode *, readPortArray, 0);
01919         assert (readDataNode1 != nil);
01920         assert (readDataNode1->type == Func_c);
01921         st_lookup (nodeToNameHash, (char *) readDataNode1,
01922                    (char **) &readdata1);
01923         readAddressNode1 = Func_SecondArg (readDataNode1);
01924         assert (readAddressNode1 != nil);
01925         st_lookup (nodeToNameHash, (char *) readAddressNode1,
01926                    (char **) &readaddress1);
01927         // second read port
01928         readDataNode2 = array_fetch (Fnode *, readPortArray, 1);
01929         assert (readDataNode2 != nil);
01930         assert (readDataNode2->type == Func_c);
01931         st_lookup (nodeToNameHash, (char *) readDataNode2,
01932                    (char **) &readdata2);
01933         readAddressNode2 = Func_SecondArg (readDataNode2);
01934         assert (readAddressNode2 != nil);
01935         st_lookup (nodeToNameHash, (char *) readAddressNode2,
01936                    (char **) &readaddress2);
01937         // third read port
01938         readDataNode3 = array_fetch (Fnode *, readPortArray, 2);
01939         assert (readDataNode3 != nil);
01940         assert (readDataNode3->type == Func_c);
01941         st_lookup (nodeToNameHash, (char *) readDataNode3,
01942                    (char **) &readdata3);
01943         readAddressNode3 = Func_SecondArg (readDataNode3);
01944         assert (readAddressNode3 != nil);
01945         st_lookup (nodeToNameHash, (char *) readAddressNode3,
01946                    (char **) &readaddress3);
01947         // now instantiate the memory
01948         fprintf (fptr,
01949                  "memory_%s: memory_model generic map (width => %d, addrtotal => %d)\n",
01950                  print_mem_name, vector_width, memsize);
01951         fprintf (fptr, "port map(initial_value => %s,\n", initname);
01952         if (invert_ctrl_input1)
01953           {
01954             fprintf (fptr,
01955                      "                                    write_enable1 => not (%s),\n",
01956                      writeenable1);
01957           }
01958         else
01959           {
01960             fprintf (fptr,
01961                      "                                    write_enable1 => %s,\n",
01962                      writeenable1);
01963           }
01964         fprintf (fptr,
01965                  "                                        write_address1 => %s,\n",
01966                  writeaddress1);
01967         fprintf (fptr,
01968                  "                                        write_data1 => %s,\n",
01969                  writedata1);
01970         fprintf (fptr,
01971                  "                                        read_address1 => %s,\n",
01972                  readaddress1);
01973         fprintf (fptr,
01974                  "                                        read_data1 => %s,\n",
01975                  readdata1);
01976         fprintf (fptr,
01977                  "                                        read_address2 => %s,\n",
01978                  readaddress2);
01979         fprintf (fptr,
01980                  "                                        read_data2 => %s,\n",
01981                  readdata2);
01982         fprintf (fptr,
01983                  "                                        read_address3 => %s,\n",
01984                  readaddress3);
01985         fprintf (fptr,
01986                  "                                        read_data3 => %s);\n",
01987                  readdata3);
01988         // call node printvhdl on all the relevant nodes
01989         Node_PrintVHDL (net, initState, fptr, nodeToNameHash, processedNodes,
01990                         uifInstantiateHash, uifToNumInputs, vector_width);
01991         Node_PrintVHDL (net, ctrlInput, fptr, nodeToNameHash, processedNodes,
01992                         uifInstantiateHash, uifToNumInputs, vector_width);
01993         Node_PrintVHDL (net, writeDataNode1, fptr, nodeToNameHash,
01994                         processedNodes, uifInstantiateHash, uifToNumInputs,
01995                         vector_width);
01996         Node_PrintVHDL (net, writeAddressNode1, fptr, nodeToNameHash,
01997                         processedNodes, uifInstantiateHash, uifToNumInputs,
01998                         vector_width);
01999         Node_PrintVHDL (net, readAddressNode1, fptr, nodeToNameHash,
02000                         processedNodes, uifInstantiateHash, uifToNumInputs,
02001                         vector_width);
02002         Node_PrintVHDL (net, readAddressNode2, fptr, nodeToNameHash,
02003                         processedNodes, uifInstantiateHash, uifToNumInputs,
02004                         vector_width);
02005         Node_PrintVHDL (net, readAddressNode3, fptr, nodeToNameHash,
02006                         processedNodes, uifInstantiateHash, uifToNumInputs,
02007                         vector_width);
02008         break;
02009       case 4:
02010         // first read port
02011         assert (num_write_ports == 1);
02012         readDataNode1 = array_fetch (Fnode *, readPortArray, 0);
02013         assert (readDataNode1 != nil);
02014         assert (readDataNode1->type == Func_c);
02015         st_lookup (nodeToNameHash, (char *) readDataNode1,
02016                    (char **) &readdata1);
02017         readAddressNode1 = Func_SecondArg (readDataNode1);
02018         assert (readAddressNode1 != nil);
02019         st_lookup (nodeToNameHash, (char *) readAddressNode1,
02020                    (char **) &readaddress1);
02021         // second read port
02022         readDataNode2 = array_fetch (Fnode *, readPortArray, 1);
02023         assert (readDataNode2 != nil);
02024         assert (readDataNode2->type == Func_c);
02025         st_lookup (nodeToNameHash, (char *) readDataNode2,
02026                    (char **) &readdata2);
02027         readAddressNode2 = Func_SecondArg (readDataNode2);
02028         assert (readAddressNode2 != nil);
02029         st_lookup (nodeToNameHash, (char *) readAddressNode2,
02030                    (char **) &readaddress2);
02031         // third read port
02032         readDataNode3 = array_fetch (Fnode *, readPortArray, 2);
02033         assert (readDataNode3 != nil);
02034         assert (readDataNode3->type == Func_c);
02035         st_lookup (nodeToNameHash, (char *) readDataNode3,
02036                    (char **) &readdata3);
02037         readAddressNode3 = Func_SecondArg (readDataNode3);
02038         assert (readAddressNode3 != nil);
02039         st_lookup (nodeToNameHash, (char *) readAddressNode3,
02040                    (char **) &readaddress3);
02041         // fourth read port
02042         readDataNode4 = array_fetch (Fnode *, readPortArray, 3);
02043         assert (readDataNode4 != nil);
02044         assert (readDataNode4->type == Func_c);
02045         st_lookup (nodeToNameHash, (char *) readDataNode4,
02046                    (char **) &readdata4);
02047         readAddressNode4 = Func_SecondArg (readDataNode4);
02048         assert (readAddressNode4 != nil);
02049         st_lookup (nodeToNameHash, (char *) readAddressNode4,
02050                    (char **) &readaddress4);
02051 
02052         // now instantiate the memory
02053         fprintf (fptr,
02054                  "memory_%s: memory_model generic map (width => %d, addrtotal => %d)\n",
02055                  print_mem_name, vector_width, memsize);
02056         fprintf (fptr, "port map(initial_value => %s,\n", initname);
02057         if (invert_ctrl_input1)
02058           {
02059             fprintf (fptr,
02060                      "                                    write_enable1 => not (%s),\n",
02061                      writeenable1);
02062           }
02063         else
02064           {
02065             fprintf (fptr,
02066                      "                                    write_enable1 => %s,\n",
02067                      writeenable1);
02068           }
02069         fprintf (fptr,
02070                  "                                        write_address1 => %s,\n",
02071                  writeaddress1);
02072         fprintf (fptr,
02073                  "                                        write_data1 => %s,\n",
02074                  writedata1);
02075         fprintf (fptr,
02076                  "                                        read_address1 => %s,\n",
02077                  readaddress1);
02078         fprintf (fptr,
02079                  "                                        read_data1 => %s,\n",
02080                  readdata1);
02081         fprintf (fptr,
02082                  "                                        read_address2 => %s,\n",
02083                  readaddress2);
02084         fprintf (fptr,
02085                  "                                        read_data2 => %s,\n",
02086                  readdata2);
02087         fprintf (fptr,
02088                  "                                        read_address3 => %s,\n",
02089                  readaddress3);
02090         fprintf (fptr,
02091                  "                                        read_data3 => %s,\n",
02092                  readdata3);
02093         fprintf (fptr,
02094                  "                                        read_address4 => %s,\n",
02095                  readaddress4);
02096         fprintf (fptr,
02097                  "                                        read_data4 => %s);\n",
02098                  readdata4);
02099         // call node printvhdl on all the relevant nodes
02100         Node_PrintVHDL (net, initState, fptr, nodeToNameHash, processedNodes,
02101                         uifInstantiateHash, uifToNumInputs, vector_width);
02102         Node_PrintVHDL (net, ctrlInput, fptr, nodeToNameHash, processedNodes,
02103                         uifInstantiateHash, uifToNumInputs, vector_width);
02104         Node_PrintVHDL (net, writeDataNode1, fptr, nodeToNameHash,
02105                         processedNodes, uifInstantiateHash, uifToNumInputs,
02106                         vector_width);
02107         Node_PrintVHDL (net, writeAddressNode1, fptr, nodeToNameHash,
02108                         processedNodes, uifInstantiateHash, uifToNumInputs,
02109                         vector_width);
02110         Node_PrintVHDL (net, readAddressNode1, fptr, nodeToNameHash,
02111                         processedNodes, uifInstantiateHash, uifToNumInputs,
02112                         vector_width);
02113         Node_PrintVHDL (net, readAddressNode2, fptr, nodeToNameHash,
02114                         processedNodes, uifInstantiateHash, uifToNumInputs,
02115                         vector_width);
02116         Node_PrintVHDL (net, readAddressNode3, fptr, nodeToNameHash,
02117                         processedNodes, uifInstantiateHash, uifToNumInputs,
02118                         vector_width);
02119         Node_PrintVHDL (net, readAddressNode4, fptr, nodeToNameHash,
02120                         processedNodes, uifInstantiateHash, uifToNumInputs,
02121                         vector_width);
02122         break;
02123       case 5:
02124         assert (num_write_ports == 2);
02125         // first read port
02126         readDataNode1 = array_fetch (Fnode *, readPortArray, 0);
02127         assert (readDataNode1 != nil);
02128         assert (readDataNode1->type == Func_c);
02129         st_lookup (nodeToNameHash, (char *) readDataNode1,
02130                    (char **) &readdata1);
02131         readAddressNode1 = Func_SecondArg (readDataNode1);
02132         assert (readAddressNode1 != nil);
02133         st_lookup (nodeToNameHash, (char *) readAddressNode1,
02134                    (char **) &readaddress1);
02135         // second read port
02136         readDataNode2 = array_fetch (Fnode *, readPortArray, 1);
02137         assert (readDataNode2 != nil);
02138         assert (readDataNode2->type == Func_c);
02139         st_lookup (nodeToNameHash, (char *) readDataNode2,
02140                    (char **) &readdata2);
02141         readAddressNode2 = Func_SecondArg (readDataNode2);
02142         assert (readAddressNode2 != nil);
02143         st_lookup (nodeToNameHash, (char *) readAddressNode2,
02144                    (char **) &readaddress2);
02145         // third read port
02146         readDataNode3 = array_fetch (Fnode *, readPortArray, 2);
02147         assert (readDataNode3 != nil);
02148         assert (readDataNode3->type == Func_c);
02149         st_lookup (nodeToNameHash, (char *) readDataNode3,
02150                    (char **) &readdata3);
02151         readAddressNode3 = Func_SecondArg (readDataNode3);
02152         assert (readAddressNode3 != nil);
02153         st_lookup (nodeToNameHash, (char *) readAddressNode3,
02154                    (char **) &readaddress3);
02155         // fourth read port
02156         readDataNode4 = array_fetch (Fnode *, readPortArray, 3);
02157         assert (readDataNode4 != nil);
02158         assert (readDataNode4->type == Func_c);
02159         st_lookup (nodeToNameHash, (char *) readDataNode4,
02160                    (char **) &readdata4);
02161         readAddressNode4 = Func_SecondArg (readDataNode4);
02162         assert (readAddressNode4 != nil);
02163         st_lookup (nodeToNameHash, (char *) readAddressNode4,
02164                    (char **) &readaddress4);
02165         // fifth read port
02166         readDataNode5 = array_fetch (Fnode *, readPortArray, 4);
02167         assert (readDataNode5 != nil);
02168         assert (readDataNode5->type == Func_c);
02169         st_lookup (nodeToNameHash, (char *) readDataNode5,
02170                    (char **) &readdata5);
02171         readAddressNode5 = Func_SecondArg (readDataNode5);
02172         assert (readAddressNode5 != nil);
02173         st_lookup (nodeToNameHash, (char *) readAddressNode5,
02174                    (char **) &readaddress5);
02175         // now instantiate the memory
02176         fprintf (fptr,
02177                  "memory_%s: memory_model generic map (width => %d, addrtotal => %d)\n",
02178                  print_mem_name, vector_width, memsize);
02179         fprintf (fptr, "port map(initial_value => %s,\n", initname);
02180         if (invert_ctrl_input1)
02181           {
02182             fprintf (fptr,
02183                      "                                    write_enable1 => not (%s),\n",
02184                      writeenable1);
02185           }
02186         else
02187           {
02188             fprintf (fptr,
02189                      "                                    write_enable1 => %s,\n",
02190                      writeenable1);
02191           }
02192         fprintf (fptr,
02193                  "                                        write_address1 => %s,\n",
02194                  writeaddress1);
02195         fprintf (fptr,
02196                  "                                        write_data1 => %s,\n",
02197                  writedata1);
02198         if (invert_ctrl_input2)
02199           {
02200             fprintf (fptr,
02201                      "                                    write_enable2 => not (%s),\n",
02202                      writeenable2);
02203           }
02204         else
02205           {
02206             fprintf (fptr,
02207                      "                                    write_enable2 => %s,\n",
02208                      writeenable2);
02209           }
02210         fprintf (fptr,
02211                  "                                        write_address2 => %s,\n",
02212                  writeaddress2);
02213         fprintf (fptr,
02214                  "                                        write_data2 => %s,\n",
02215                  writedata2);
02216         fprintf (fptr,
02217                  "                                        read_address1 => %s,\n",
02218                  readaddress1);
02219         fprintf (fptr,
02220                  "                                        read_data1 => %s,\n",
02221                  readdata1);
02222         fprintf (fptr,
02223                  "                                        read_address2 => %s,\n",
02224                  readaddress2);
02225         fprintf (fptr,
02226                  "                                        read_data2 => %s,\n",
02227                  readdata2);
02228         fprintf (fptr,
02229                  "                                        read_address3 => %s,\n",
02230                  readaddress3);
02231         fprintf (fptr,
02232                  "                                        read_data3 => %s,\n",
02233                  readdata3);
02234         fprintf (fptr,
02235                  "                                        read_address4 => %s,\n",
02236                  readaddress4);
02237         fprintf (fptr,
02238                  "                                        read_data4 => %s,\n",
02239                  readdata4);
02240         fprintf (fptr,
02241                  "                                        read_address5 => %s,\n",
02242                  readaddress5);
02243         fprintf (fptr,
02244                  "                                        read_data5 => %s);\n",
02245                  readdata5);
02246 
02247         // call node printvhdl on all the relevant nodes
02248         Node_PrintVHDL (net, initState, fptr, nodeToNameHash, processedNodes,
02249                         uifInstantiateHash, uifToNumInputs, vector_width);
02250         Node_PrintVHDL (net, ctrlInput, fptr, nodeToNameHash, processedNodes,
02251                         uifInstantiateHash, uifToNumInputs, vector_width);
02252         Node_PrintVHDL (net, writeDataNode1, fptr, nodeToNameHash,
02253                         processedNodes, uifInstantiateHash, uifToNumInputs,
02254                         vector_width);
02255         Node_PrintVHDL (net, writeAddressNode1, fptr, nodeToNameHash,
02256                         processedNodes, uifInstantiateHash, uifToNumInputs,
02257                         vector_width);
02258         Node_PrintVHDL (net, secondCtrlInput, fptr, nodeToNameHash,
02259                         processedNodes, uifInstantiateHash, uifToNumInputs,
02260                         vector_width);
02261         Node_PrintVHDL (net, writeDataNode2, fptr, nodeToNameHash,
02262                         processedNodes, uifInstantiateHash, uifToNumInputs,
02263                         vector_width);
02264         Node_PrintVHDL (net, writeAddressNode2, fptr, nodeToNameHash,
02265                         processedNodes, uifInstantiateHash, uifToNumInputs,
02266                         vector_width);
02267         Node_PrintVHDL (net, readAddressNode1, fptr, nodeToNameHash,
02268                         processedNodes, uifInstantiateHash, uifToNumInputs,
02269                         vector_width);
02270         Node_PrintVHDL (net, readAddressNode2, fptr, nodeToNameHash,
02271                         processedNodes, uifInstantiateHash, uifToNumInputs,
02272                         vector_width);
02273         Node_PrintVHDL (net, readAddressNode3, fptr, nodeToNameHash,
02274                         processedNodes, uifInstantiateHash, uifToNumInputs,
02275                         vector_width);
02276         Node_PrintVHDL (net, readAddressNode4, fptr, nodeToNameHash,
02277                         processedNodes, uifInstantiateHash, uifToNumInputs,
02278                         vector_width);
02279         Node_PrintVHDL (net, readAddressNode5, fptr, nodeToNameHash,
02280                         processedNodes, uifInstantiateHash, uifToNumInputs,
02281                         vector_width);
02282         break;
02283       case 8:
02284         assert (num_write_ports == 2);
02285         // first read port
02286         readDataNode1 = array_fetch (Fnode *, readPortArray, 0);
02287         assert (readDataNode1 != nil);
02288         assert (readDataNode1->type == Func_c);
02289         st_lookup (nodeToNameHash, (char *) readDataNode1,
02290                    (char **) &readdata1);
02291         readAddressNode1 = Func_SecondArg (readDataNode1);
02292         assert (readAddressNode1 != nil);
02293         st_lookup (nodeToNameHash, (char *) readAddressNode1,
02294                    (char **) &readaddress1);
02295         // second read port
02296         readDataNode2 = array_fetch (Fnode *, readPortArray, 1);
02297         assert (readDataNode2 != nil);
02298         assert (readDataNode2->type == Func_c);
02299         st_lookup (nodeToNameHash, (char *) readDataNode2,
02300                    (char **) &readdata2);
02301         readAddressNode2 = Func_SecondArg (readDataNode2);
02302         assert (readAddressNode2 != nil);
02303         st_lookup (nodeToNameHash, (char *) readAddressNode2,
02304                    (char **) &readaddress2);
02305         // third read port
02306         readDataNode3 = array_fetch (Fnode *, readPortArray, 2);
02307         assert (readDataNode3 != nil);
02308         assert (readDataNode3->type == Func_c);
02309         st_lookup (nodeToNameHash, (char *) readDataNode3,
02310                    (char **) &readdata3);
02311         readAddressNode3 = Func_SecondArg (readDataNode3);
02312         assert (readAddressNode3 != nil);
02313         st_lookup (nodeToNameHash, (char *) readAddressNode3,
02314                    (char **) &readaddress3);
02315         // fourth read port
02316         readDataNode4 = array_fetch (Fnode *, readPortArray, 3);
02317         assert (readDataNode4 != nil);
02318         assert (readDataNode4->type == Func_c);
02319         st_lookup (nodeToNameHash, (char *) readDataNode4,
02320                    (char **) &readdata4);
02321         readAddressNode4 = Func_SecondArg (readDataNode4);
02322         assert (readAddressNode4 != nil);
02323         st_lookup (nodeToNameHash, (char *) readAddressNode4,
02324                    (char **) &readaddress4);
02325         // fifth read port
02326         readDataNode5 = array_fetch (Fnode *, readPortArray, 4);
02327         assert (readDataNode5 != nil);
02328         assert (readDataNode5->type == Func_c);
02329         st_lookup (nodeToNameHash, (char *) readDataNode5,
02330                    (char **) &readdata5);
02331         readAddressNode5 = Func_SecondArg (readDataNode5);
02332         assert (readAddressNode5 != nil);
02333         st_lookup (nodeToNameHash, (char *) readAddressNode5,
02334                    (char **) &readaddress5);
02335         // sixth read port
02336         readDataNode6 = array_fetch (Fnode *, readPortArray, 5);
02337         assert (readDataNode6 != nil);
02338         assert (readDataNode6->type == Func_c);
02339         st_lookup (nodeToNameHash, (char *) readDataNode6,
02340                    (char **) &readdata6);
02341         readAddressNode6 = Func_SecondArg (readDataNode6);
02342         assert (readAddressNode6 != nil);
02343         st_lookup (nodeToNameHash, (char *) readAddressNode6,
02344                    (char **) &readaddress6);
02345         // seventh read port
02346         readDataNode7 = array_fetch (Fnode *, readPortArray, 6);
02347         assert (readDataNode7 != nil);
02348         assert (readDataNode7->type == Func_c);
02349         st_lookup (nodeToNameHash, (char *) readDataNode7,
02350                    (char **) &readdata7);
02351         readAddressNode7 = Func_SecondArg (readDataNode7);
02352         assert (readAddressNode7 != nil);
02353         st_lookup (nodeToNameHash, (char *) readAddressNode7,
02354                    (char **) &readaddress7);
02355         // eighth read port
02356         readDataNode8 = array_fetch (Fnode *, readPortArray, 7);
02357         assert (readDataNode8 != nil);
02358         assert (readDataNode8->type == Func_c);
02359         st_lookup (nodeToNameHash, (char *) readDataNode8,
02360                    (char **) &readdata8);
02361         readAddressNode8 = Func_SecondArg (readDataNode8);
02362         assert (readAddressNode8 != nil);
02363         st_lookup (nodeToNameHash, (char *) readAddressNode8,
02364                    (char **) &readaddress8);
02365 
02366         // now instantiate the memory
02367         fprintf (fptr,
02368                  "memory_%s: memory_model generic map (width => %d, addrtotal => %d)\n",
02369                  print_mem_name, vector_width, memsize);
02370         fprintf (fptr, "port map(initial_value => %s,\n", initname);
02371         if (invert_ctrl_input1)
02372           {
02373             fprintf (fptr,
02374                      "                                    write_enable1 => not (%s),\n",
02375                      writeenable1);
02376           }
02377         else
02378           {
02379             fprintf (fptr,
02380                      "                                    write_enable1 => %s,\n",
02381                      writeenable1);
02382           }
02383         fprintf (fptr,
02384                  "                                        write_address1 => %s,\n",
02385                  writeaddress1);
02386         fprintf (fptr,
02387                  "                                        write_data1 => %s,\n",
02388                  writedata1);
02389         if (invert_ctrl_input2)
02390           {
02391             fprintf (fptr,
02392                      "                                    write_enable2 => not (%s),\n",
02393                      writeenable2);
02394           }
02395         else
02396           {
02397             fprintf (fptr,
02398                      "                                    write_enable2 => %s,\n",
02399                      writeenable2);
02400           }
02401         fprintf (fptr,
02402                  "                                        write_address2 => %s,\n",
02403                  writeaddress2);
02404         fprintf (fptr,
02405                  "                                        write_data2 => %s,\n",
02406                  writedata2);
02407         fprintf (fptr,
02408                  "                                        read_address1 => %s,\n",
02409                  readaddress1);
02410         fprintf (fptr,
02411                  "                                        read_data1 => %s,\n",
02412                  readdata1);
02413         fprintf (fptr,
02414                  "                                        read_address2 => %s,\n",
02415                  readaddress2);
02416         fprintf (fptr,
02417                  "                                        read_data2 => %s,\n",
02418                  readdata2);
02419         fprintf (fptr,
02420                  "                                        read_address3 => %s,\n",
02421                  readaddress3);
02422         fprintf (fptr,
02423                  "                                        read_data3 => %s,\n",
02424                  readdata3);
02425         fprintf (fptr,
02426                  "                                        read_address4 => %s,\n",
02427                  readaddress4);
02428         fprintf (fptr,
02429                  "                                        read_data4 => %s,\n",
02430                  readdata4);
02431         fprintf (fptr,
02432                  "                                        read_address5 => %s,\n",
02433                  readaddress5);
02434         fprintf (fptr,
02435                  "                                        read_data5 => %s,\n",
02436                  readdata5);
02437         fprintf (fptr,
02438                  "                                        read_address6 => %s,\n",
02439                  readaddress6);
02440         fprintf (fptr,
02441                  "                                        read_data6 => %s,\n",
02442                  readdata6);
02443         fprintf (fptr,
02444                  "                                        read_address7 => %s,\n",
02445                  readaddress7);
02446         fprintf (fptr,
02447                  "                                        read_data7 => %s,\n",
02448                  readdata7);
02449         fprintf (fptr,
02450                  "                                        read_address8 => %s,\n",
02451                  readaddress8);
02452         fprintf (fptr,
02453                  "                                        read_data8 => %s);\n",
02454                  readdata8);
02455 
02456         // call node printvhdl on all the relevant nodes
02457         Node_PrintVHDL (net, initState, fptr, nodeToNameHash, processedNodes,
02458                         uifInstantiateHash, uifToNumInputs, vector_width);
02459         Node_PrintVHDL (net, ctrlInput, fptr, nodeToNameHash, processedNodes,
02460                         uifInstantiateHash, uifToNumInputs, vector_width);
02461         Node_PrintVHDL (net, writeDataNode1, fptr, nodeToNameHash,
02462                         processedNodes, uifInstantiateHash, uifToNumInputs,
02463                         vector_width);
02464         Node_PrintVHDL (net, writeAddressNode1, fptr, nodeToNameHash,
02465                         processedNodes, uifInstantiateHash, uifToNumInputs,
02466                         vector_width);
02467         Node_PrintVHDL (net, secondCtrlInput, fptr, nodeToNameHash,
02468                         processedNodes, uifInstantiateHash, uifToNumInputs,
02469                         vector_width);
02470         Node_PrintVHDL (net, writeDataNode2, fptr, nodeToNameHash,
02471                         processedNodes, uifInstantiateHash, uifToNumInputs,
02472                         vector_width);
02473         Node_PrintVHDL (net, writeAddressNode2, fptr, nodeToNameHash,
02474                         processedNodes, uifInstantiateHash, uifToNumInputs,
02475                         vector_width);
02476         Node_PrintVHDL (net, readAddressNode1, fptr, nodeToNameHash,
02477                         processedNodes, uifInstantiateHash, uifToNumInputs,
02478                         vector_width);
02479         Node_PrintVHDL (net, readAddressNode2, fptr, nodeToNameHash,
02480                         processedNodes, uifInstantiateHash, uifToNumInputs,
02481                         vector_width);
02482         Node_PrintVHDL (net, readAddressNode3, fptr, nodeToNameHash,
02483                         processedNodes, uifInstantiateHash, uifToNumInputs,
02484                         vector_width);
02485         Node_PrintVHDL (net, readAddressNode4, fptr, nodeToNameHash,
02486                         processedNodes, uifInstantiateHash, uifToNumInputs,
02487                         vector_width);
02488         Node_PrintVHDL (net, readAddressNode5, fptr, nodeToNameHash,
02489                         processedNodes, uifInstantiateHash, uifToNumInputs,
02490                         vector_width);
02491         Node_PrintVHDL (net, readAddressNode6, fptr, nodeToNameHash,
02492                         processedNodes, uifInstantiateHash, uifToNumInputs,
02493                         vector_width);
02494         Node_PrintVHDL (net, readAddressNode7, fptr, nodeToNameHash,
02495                         processedNodes, uifInstantiateHash, uifToNumInputs,
02496                         vector_width);
02497         Node_PrintVHDL (net, readAddressNode8, fptr, nodeToNameHash,
02498                         processedNodes, uifInstantiateHash, uifToNumInputs,
02499                         vector_width);
02500       default:
02501         break;
02502       }
02503   }
02504 
02509   static void
02510     Net_AnalyzeUIF (Net_t * net,
02511                     FILE * fptr,
02512                     Fnode * aFormula,
02513                     st_table * uifToNumInputs, st_table * uifComponentHash)
02514   {
02515     assert (aFormula != nil);
02516     assert (uifToNumInputs != NIL (st_table));
02517     assert (uifComponentHash != NIL (st_table));
02518 
02519     // First we will analyze the number of inputs to UIF
02520     Fnode *input;
02521     int num_inputs = 0;
02522     input = aFormula->rchild;
02523     while (input != nil)
02524       {
02525         assert (input->lchild != nil);
02526         num_inputs++;
02527         input = input->rchild;
02528       }
02529     assert (num_inputs > 0);
02530     st_insert (uifToNumInputs, (char *) aFormula, (char *) num_inputs);
02531     //printf("UIF %s has %d inputs\n", (char *) aFormula->lchild, num_inputs);
02532 
02533     array_t *instance_array;
02534     int num_instantiations = 0;
02535     st_lookup (net->UIFs, (char *) aFormula->lchild,
02536                (char **) &instance_array);
02537     //printf("UIF %s has %d instantiations\n", (char *) aFormula->lchild, array_n(instance_array));
02538     num_instantiations = array_n (instance_array);
02539 
02540     if (!st_lookup (uifComponentHash, (char *) num_inputs, (char **) 0))
02541       {
02542         // we have to instantiate the component
02543         st_insert (uifComponentHash, (char *) num_inputs, (char *) 0);
02544         switch (num_inputs)
02545           {
02546           case 1:
02547             fprintf (fptr, "component single_input_uif_model generic (\n");
02548             fprintf (fptr, "width: integer;\n");
02549             fprintf (fptr, "addrtotal : integer);\n");
02550             fprintf (fptr, " port (\n");
02551             fprintf (fptr,
02552                      "        inst1_input1 : in std_ulogic_vector (0 to width-1);\n");
02553             fprintf (fptr,
02554                      "        inst2_input1 : in std_ulogic_vector (0 to width-1);\n");
02555             fprintf (fptr,
02556                      "        inst3_input1 : in std_ulogic_vector (0 to width-1);\n");
02557             fprintf (fptr,
02558                      "        inst4_input1 : in std_ulogic_vector (0 to width-1);\n");
02559             fprintf (fptr,
02560                      "        inst5_input1 : in std_ulogic_vector (0 to width-1);\n");
02561             fprintf (fptr,
02562                      "        inst6_input1 : in std_ulogic_vector (0 to width-1);\n");
02563             fprintf (fptr,
02564                      "        inst7_input1 : in std_ulogic_vector (0 to width-1);\n");
02565             fprintf (fptr,
02566                      "        inst8_input1 : in std_ulogic_vector (0 to width-1);\n");
02567             fprintf (fptr,
02568                      "        uif_enable   : in std_ulogic_vector(0 to 7);\n");
02569             fprintf (fptr,
02570                      "        inst1_output : out std_ulogic_vector(0 to width-1);\n");
02571             fprintf (fptr,
02572                      "        inst2_output : out std_ulogic_vector(0 to width-1);\n");
02573             fprintf (fptr,
02574                      "        inst3_output : out std_ulogic_vector(0 to width-1);\n");
02575             fprintf (fptr,
02576                      "        inst4_output : out std_ulogic_vector(0 to width-1);\n");
02577             fprintf (fptr,
02578                      "        inst5_output : out std_ulogic_vector(0 to width-1);\n");
02579             fprintf (fptr,
02580                      "        inst6_output : out std_ulogic_vector(0 to width-1);\n");
02581             fprintf (fptr,
02582                      "        inst7_output : out std_ulogic_vector(0 to width-1);\n");
02583             fprintf (fptr,
02584                      "        inst8_output : out std_ulogic_vector(0 to width-1)\n");
02585             fprintf (fptr, "                                   );\n");
02586             fprintf (fptr, "end component;\n");
02587             break;
02588           case 2:
02589             fprintf (fptr, "component two_input_uif_model generic (\n");
02590             fprintf (fptr, "width: integer;\n");
02591             fprintf (fptr, "addrtotal : integer);\n");
02592             fprintf (fptr, " port (\n");
02593             fprintf (fptr,
02594                      "            inst1_input1 : in std_ulogic_vector (0 to width-1);\n");
02595             fprintf (fptr,
02596                      "            inst1_input2 : in std_ulogic_vector (0 to width-1);\n");
02597             fprintf (fptr,
02598                      "            inst2_input1 : in std_ulogic_vector (0 to width-1);\n");
02599             fprintf (fptr,
02600                      "            inst2_input2 : in std_ulogic_vector (0 to width-1);\n");
02601             fprintf (fptr,
02602                      "            inst3_input1 : in std_ulogic_vector (0 to width-1);\n");
02603             fprintf (fptr,
02604                      "            inst3_input2 : in std_ulogic_vector (0 to width-1);\n");
02605             fprintf (fptr,
02606                      "            inst4_input1 : in std_ulogic_vector (0 to width-1);\n");
02607             fprintf (fptr,
02608                      "            inst4_input2 : in std_ulogic_vector (0 to width-1);\n");
02609             fprintf (fptr,
02610                      "            inst5_input1 : in std_ulogic_vector (0 to width-1);\n");
02611             fprintf (fptr,
02612                      "            inst5_input2 : in std_ulogic_vector (0 to width-1);\n");
02613             fprintf (fptr,
02614                      "            inst6_input1 : in std_ulogic_vector (0 to width-1);\n");
02615             fprintf (fptr,
02616                      "            inst6_input2 : in std_ulogic_vector (0 to width-1);\n");
02617             fprintf (fptr,
02618                      "            inst7_input1 : in std_ulogic_vector (0 to width-1);\n");
02619             fprintf (fptr,
02620                      "            inst7_input2 : in std_ulogic_vector (0 to width-1);\n");
02621             fprintf (fptr,
02622                      "            inst8_input1 : in std_ulogic_vector (0 to width-1);\n");
02623             fprintf (fptr,
02624                      "            inst8_input2 : in std_ulogic_vector (0 to width-1);\n");
02625             fprintf (fptr,
02626                      "        uif_enable   : in std_ulogic_vector(0 to 7);\n");
02627             fprintf (fptr,
02628                      "        inst1_output : out std_ulogic_vector(0 to width-1);\n");
02629             fprintf (fptr,
02630                      "        inst2_output : out std_ulogic_vector(0 to width-1);\n");
02631             fprintf (fptr,
02632                      "        inst3_output : out std_ulogic_vector(0 to width-1);\n");
02633             fprintf (fptr,
02634                      "        inst4_output : out std_ulogic_vector(0 to width-1);\n");
02635             fprintf (fptr,
02636                      "        inst5_output : out std_ulogic_vector(0 to width-1);\n");
02637             fprintf (fptr,
02638                      "        inst6_output : out std_ulogic_vector(0 to width-1);\n");
02639             fprintf (fptr,
02640                      "        inst7_output : out std_ulogic_vector(0 to width-1);\n");
02641             fprintf (fptr,
02642                      "        inst8_output : out std_ulogic_vector(0 to width-1)\n");
02643             fprintf (fptr, "                                   );\n");
02644             fprintf (fptr, "end component;\n");
02645             break;
02646           case 3:
02647             fprintf (fptr, "component three_input_uif_model generic (\n");
02648             fprintf (fptr, "width: integer;\n");
02649             fprintf (fptr, "addrtotal : integer);\n");
02650             fprintf (fptr, " port (\n");
02651             fprintf (fptr,
02652                      "            inst1_input1 : in std_ulogic_vector (0 to width-1);\n");
02653             fprintf (fptr,
02654                      "            inst1_input2 : in std_ulogic_vector (0 to width-1);\n");
02655             fprintf (fptr,
02656                      "            inst1_input3 : in std_ulogic_vector (0 to width-1);\n");
02657             fprintf (fptr,
02658                      "            inst2_input1 : in std_ulogic_vector (0 to width-1);\n");
02659             fprintf (fptr,
02660                      "            inst2_input2 : in std_ulogic_vector (0 to width-1);\n");
02661             fprintf (fptr,
02662                      "            inst2_input3 : in std_ulogic_vector (0 to width-1);\n");
02663             fprintf (fptr,
02664                      "            inst3_input1 : in std_ulogic_vector (0 to width-1);\n");
02665             fprintf (fptr,
02666                      "            inst3_input2 : in std_ulogic_vector (0 to width-1);\n");
02667             fprintf (fptr,
02668                      "            inst3_input3 : in std_ulogic_vector (0 to width-1);\n");
02669             fprintf (fptr,
02670                      "            inst4_input1 : in std_ulogic_vector (0 to width-1);\n");
02671             fprintf (fptr,
02672                      "            inst4_input2 : in std_ulogic_vector (0 to width-1);\n");
02673             fprintf (fptr,
02674                      "            inst4_input3 : in std_ulogic_vector (0 to width-1);\n");
02675             fprintf (fptr,
02676                      "            inst5_input1 : in std_ulogic_vector (0 to width-1);\n");
02677             fprintf (fptr,
02678                      "            inst5_input2 : in std_ulogic_vector (0 to width-1);\n");
02679             fprintf (fptr,
02680                      "            inst5_input3 : in std_ulogic_vector (0 to width-1);\n");
02681             fprintf (fptr,
02682                      "            inst6_input1 : in std_ulogic_vector (0 to width-1);\n");
02683             fprintf (fptr,
02684                      "            inst6_input2 : in std_ulogic_vector (0 to width-1);\n");
02685             fprintf (fptr,
02686                      "            inst6_input3 : in std_ulogic_vector (0 to width-1);\n");
02687             fprintf (fptr,
02688                      "            inst7_input1 : in std_ulogic_vector (0 to width-1);\n");
02689             fprintf (fptr,
02690                      "            inst7_input2 : in std_ulogic_vector (0 to width-1);\n");
02691             fprintf (fptr,
02692                      "            inst7_input3 : in std_ulogic_vector (0 to width-1);\n");
02693             fprintf (fptr,
02694                      "            inst8_input1 : in std_ulogic_vector (0 to width-1);\n");
02695             fprintf (fptr,
02696                      "            inst8_input2 : in std_ulogic_vector (0 to width-1);\n");
02697             fprintf (fptr,
02698                      "            inst8_input3 : in std_ulogic_vector (0 to width-1);\n");
02699             fprintf (fptr,
02700                      "        uif_enable   : in std_ulogic_vector(0 to 7);\n");
02701             fprintf (fptr,
02702                      "        inst1_output : out std_ulogic_vector(0 to width-1);\n");
02703             fprintf (fptr,
02704                      "        inst2_output : out std_ulogic_vector(0 to width-1);\n");
02705             fprintf (fptr,
02706                      "        inst3_output : out std_ulogic_vector(0 to width-1);\n");
02707             fprintf (fptr,
02708                      "        inst4_output : out std_ulogic_vector(0 to width-1);\n");
02709             fprintf (fptr,
02710                      "        inst5_output : out std_ulogic_vector(0 to width-1);\n");
02711             fprintf (fptr,
02712                      "        inst6_output : out std_ulogic_vector(0 to width-1);\n");
02713             fprintf (fptr,
02714                      "        inst7_output : out std_ulogic_vector(0 to width-1);\n");
02715             fprintf (fptr,
02716                      "        inst8_output : out std_ulogic_vector(0 to width-1)\n");
02717             fprintf (fptr, "                                   );\n");
02718             fprintf (fptr, "end component;\n");
02719             break;
02720           default:
02721             assert (0);
02722             break;
02723           }
02724       }
02725   }
02726 
02732   static void
02733     Net_InstantiateUIF (Net_t * net,
02734                         FILE * fptr,
02735                         Fnode * aFormula,
02736                         st_table * uifToNumInputs,
02737                         st_table * nodeToNameHash,
02738                         st_table * processedNodes,
02739                         st_table * uifInstantiateHash, int vector_width)
02740   {
02741     assert (aFormula != nil);
02742     assert (fptr != NULL);
02743     assert (nodeToNameHash != NIL (st_table));
02744     assert (uifToNumInputs != NIL (st_table));
02745     assert (uifInstantiateHash != NIL (st_table));
02746 
02747 
02748     if (!st_lookup
02749         (uifInstantiateHash, (char *) aFormula->lchild, (char **) 0))
02750       {
02751         /* If a module has not been instantiated for this UIF */
02752         st_insert (uifInstantiateHash, (char *) aFormula->lchild, (char *) 0);
02753         int num_inputs = 0;
02754         char *uifname, *input1, *input2, *input3;
02755         st_lookup (nodeToNameHash, (char *) aFormula, (char **) &uifname);
02756         st_lookup (uifToNumInputs, (char *) aFormula, (char **) &num_inputs);
02757 
02758         // look at all the instantiations of this UIF
02759         array_t *instance_array;
02760         int num_instantiations = 0;
02761         st_lookup (net->UIFs, (char *) aFormula->lchild,
02762                    (char **) &instance_array);
02763         num_instantiations = array_n (instance_array);
02764 
02765         assert (num_inputs > 0);
02766         switch (num_inputs)
02767           {
02768           case 1:
02769             if (num_instantiations == 1)
02770               {
02771                 fprintf (fptr,
02772                          "uif_%s: single_input_uif_model generic map (width => %d, addrtotal => 16)\n",
02773                          (char *) aFormula->lchild, vector_width);
02774                 fprintf (fptr, "port map(\n");
02775                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (aFormula),
02776                            (char **) &input1);
02777                 fprintf (fptr,
02778                          "                            inst1_input1 => %s,\n",
02779                          input1);
02780                 fprintf (fptr,
02781                          "                            uif_enable => \"10000000\",\n");
02782                 fprintf (fptr,
02783                          "                            inst1_output => %s);\n",
02784                          uifname);
02785                 Node_PrintVHDL (net, Func_FirstArg (aFormula), fptr,
02786                                 nodeToNameHash, processedNodes,
02787                                 uifInstantiateHash, uifToNumInputs,
02788                                 vector_width);
02789               }
02790             else if (num_instantiations == 2)
02791               {
02792                 fprintf (fptr,
02793                          "uif_%s: single_input_uif_model generic map (width => %d, addrtotal => 16)\n",
02794                          (char *) aFormula->lchild, vector_width);
02795                 fprintf (fptr, "port map(\n");
02796                 char *inst1_input1, *inst2_input1, *inst1_output,
02797                   *inst2_output;
02798                 Fnode *instance1 = array_fetch (Fnode *, instance_array, 0);
02799                 Fnode *instance2 = array_fetch (Fnode *, instance_array, 1);
02800                 st_lookup (nodeToNameHash, (char *) instance1,
02801                            (char **) &inst1_output);
02802                 st_lookup (nodeToNameHash, (char *) instance2,
02803                            (char **) &inst2_output);
02804                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance1),
02805                            (char **) &inst1_input1);
02806                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance2),
02807                            (char **) &inst2_input1);
02808                 fprintf (fptr,
02809                          "                            inst1_input1 => %s,\n",
02810                          inst1_input1);
02811                 fprintf (fptr,
02812                          "                            inst2_input1 => %s,\n",
02813                          inst2_input1);
02814                 fprintf (fptr,
02815                          "                            uif_enable => \"11000000\",\n");
02816                 fprintf (fptr,
02817                          "                            inst1_output => %s,\n",
02818                          inst1_output);
02819                 fprintf (fptr,
02820                          "                            inst2_output => %s);\n",
02821                          inst2_output);
02822                 // now call node_printvhdl for the correct nodes
02823                 Node_PrintVHDL (net, Func_FirstArg (instance1), fptr,
02824                                 nodeToNameHash, processedNodes,
02825                                 uifInstantiateHash, uifToNumInputs,
02826                                 vector_width);
02827                 Node_PrintVHDL (net, Func_FirstArg (instance2), fptr,
02828                                 nodeToNameHash, processedNodes,
02829                                 uifInstantiateHash, uifToNumInputs,
02830                                 vector_width);
02831               }
02832             else if (num_instantiations == 3)
02833               {
02834                 fprintf (fptr,
02835                          "uif_%s: single_input_uif_model generic map (width => %d, addrtotal => 16)\n",
02836                          (char *) aFormula->lchild, vector_width);
02837                 fprintf (fptr, "port map(\n");
02838                 char *inst1_input1, *inst2_input1, *inst3_input1,
02839                   *inst1_output, *inst2_output, *inst3_output;
02840                 Fnode *instance1 = array_fetch (Fnode *, instance_array, 0);
02841                 Fnode *instance2 = array_fetch (Fnode *, instance_array, 1);
02842                 Fnode *instance3 = array_fetch (Fnode *, instance_array, 2);
02843                 st_lookup (nodeToNameHash, (char *) instance1,
02844                            (char **) &inst1_output);
02845                 st_lookup (nodeToNameHash, (char *) instance2,
02846                            (char **) &inst2_output);
02847                 st_lookup (nodeToNameHash, (char *) instance3,
02848                            (char **) &inst3_output);
02849                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance1),
02850                            (char **) &inst1_input1);
02851                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance2),
02852                            (char **) &inst2_input1);
02853                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance3),
02854                            (char **) &inst3_input1);
02855                 fprintf (fptr,
02856                          "                            inst1_input1 => %s,\n",
02857                          inst1_input1);
02858                 fprintf (fptr,
02859                          "                            inst2_input1 => %s,\n",
02860                          inst2_input1);
02861                 fprintf (fptr,
02862                          "                            inst3_input1 => %s,\n",
02863                          inst3_input1);
02864                 fprintf (fptr,
02865                          "                            uif_enable => \"11100000\",\n");
02866                 fprintf (fptr,
02867                          "                            inst1_output => %s,\n",
02868                          inst1_output);
02869                 fprintf (fptr,
02870                          "                            inst2_output => %s,\n",
02871                          inst2_output);
02872                 fprintf (fptr,
02873                          "                            inst3_output => %s);\n",
02874                          inst3_output);
02875                 // now call node_printvhdl for the correct nodes
02876                 Node_PrintVHDL (net, Func_FirstArg (instance1), fptr,
02877                                 nodeToNameHash, processedNodes,
02878                                 uifInstantiateHash, uifToNumInputs,
02879                                 vector_width);
02880                 Node_PrintVHDL (net, Func_FirstArg (instance2), fptr,
02881                                 nodeToNameHash, processedNodes,
02882                                 uifInstantiateHash, uifToNumInputs,
02883                                 vector_width);
02884                 Node_PrintVHDL (net, Func_FirstArg (instance3), fptr,
02885                                 nodeToNameHash, processedNodes,
02886                                 uifInstantiateHash, uifToNumInputs,
02887                                 vector_width);
02888               }
02889             else if (num_instantiations == 4)
02890               {
02891                 fprintf (fptr,
02892                          "uif_%s: single_input_uif_model generic map (width => %d, addrtotal => 16)\n",
02893                          (char *) aFormula->lchild, vector_width);
02894                 fprintf (fptr, "port map(\n");
02895                 char *inst1_input1, *inst2_input1, *inst3_input1,
02896                   *inst4_input1, *inst1_output, *inst2_output, *inst3_output,
02897                   *inst4_output;
02898                 Fnode *instance1 = array_fetch (Fnode *, instance_array, 0);
02899                 Fnode *instance2 = array_fetch (Fnode *, instance_array, 1);
02900                 Fnode *instance3 = array_fetch (Fnode *, instance_array, 2);
02901                 Fnode *instance4 = array_fetch (Fnode *, instance_array, 3);
02902                 st_lookup (nodeToNameHash, (char *) instance1,
02903                            (char **) &inst1_output);
02904                 st_lookup (nodeToNameHash, (char *) instance2,
02905                            (char **) &inst2_output);
02906                 st_lookup (nodeToNameHash, (char *) instance3,
02907                            (char **) &inst3_output);
02908                 st_lookup (nodeToNameHash, (char *) instance4,
02909                            (char **) &inst4_output);
02910                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance1),
02911                            (char **) &inst1_input1);
02912                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance2),
02913                            (char **) &inst2_input1);
02914                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance3),
02915                            (char **) &inst3_input1);
02916                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance4),
02917                            (char **) &inst4_input1);
02918                 fprintf (fptr,
02919                          "                            inst1_input1 => %s,\n",
02920                          inst1_input1);
02921                 fprintf (fptr,
02922                          "                            inst2_input1 => %s,\n",
02923                          inst2_input1);
02924                 fprintf (fptr,
02925                          "                            inst3_input1 => %s,\n",
02926                          inst3_input1);
02927                 fprintf (fptr,
02928                          "                            inst4_input1 => %s,\n",
02929                          inst4_input1);
02930                 fprintf (fptr,
02931                          "                            uif_enable => \"11110000\",\n");
02932                 fprintf (fptr,
02933                          "                            inst1_output => %s,\n",
02934                          inst1_output);
02935                 fprintf (fptr,
02936                          "                            inst2_output => %s,\n",
02937                          inst2_output);
02938                 fprintf (fptr,
02939                          "                            inst3_output => %s,\n",
02940                          inst3_output);
02941                 fprintf (fptr,
02942                          "                            inst4_output => %s);\n",
02943                          inst4_output);
02944                 // now call node_printvhdl for the correct nodes
02945                 Node_PrintVHDL (net, Func_FirstArg (instance1), fptr,
02946                                 nodeToNameHash, processedNodes,
02947                                 uifInstantiateHash, uifToNumInputs,
02948                                 vector_width);
02949                 Node_PrintVHDL (net, Func_FirstArg (instance2), fptr,
02950                                 nodeToNameHash, processedNodes,
02951                                 uifInstantiateHash, uifToNumInputs,
02952                                 vector_width);
02953                 Node_PrintVHDL (net, Func_FirstArg (instance3), fptr,
02954                                 nodeToNameHash, processedNodes,
02955                                 uifInstantiateHash, uifToNumInputs,
02956                                 vector_width);
02957                 Node_PrintVHDL (net, Func_FirstArg (instance4), fptr,
02958                                 nodeToNameHash, processedNodes,
02959                                 uifInstantiateHash, uifToNumInputs,
02960                                 vector_width);
02961               }
02962             else if (num_instantiations == 6)
02963               {
02964                 fprintf (fptr,
02965                          "uif_%s: single_input_uif_model generic map (width => %d, addrtotal => 16)\n",
02966                          (char *) aFormula->lchild, vector_width);
02967                 fprintf (fptr, "port map(\n");
02968                 char *inst1_input1, *inst2_input1, *inst3_input1,
02969                   *inst4_input1, *inst1_output, *inst2_output, *inst3_output,
02970                   *inst4_output;
02971                 char *inst5_input1, *inst6_input1, *inst5_output,
02972                   *inst6_output;
02973                 Fnode *instance1 = array_fetch (Fnode *, instance_array, 0);
02974                 Fnode *instance2 = array_fetch (Fnode *, instance_array, 1);
02975                 Fnode *instance3 = array_fetch (Fnode *, instance_array, 2);
02976                 Fnode *instance4 = array_fetch (Fnode *, instance_array, 3);
02977                 Fnode *instance5 = array_fetch (Fnode *, instance_array, 4);
02978                 Fnode *instance6 = array_fetch (Fnode *, instance_array, 5);
02979                 st_lookup (nodeToNameHash, (char *) instance1,
02980                            (char **) &inst1_output);
02981                 st_lookup (nodeToNameHash, (char *) instance2,
02982                            (char **) &inst2_output);
02983                 st_lookup (nodeToNameHash, (char *) instance3,
02984                            (char **) &inst3_output);
02985                 st_lookup (nodeToNameHash, (char *) instance4,
02986                            (char **) &inst4_output);
02987                 st_lookup (nodeToNameHash, (char *) instance5,
02988                            (char **) &inst5_output);
02989                 st_lookup (nodeToNameHash, (char *) instance6,
02990                            (char **) &inst6_output);
02991 
02992                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance1),
02993                            (char **) &inst1_input1);
02994                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance2),
02995                            (char **) &inst2_input1);
02996                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance3),
02997                            (char **) &inst3_input1);
02998                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance4),
02999                            (char **) &inst4_input1);
03000                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance5),
03001                            (char **) &inst5_input1);
03002                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance6),
03003                            (char **) &inst6_input1);
03004 
03005                 fprintf (fptr,
03006                          "                            inst1_input1 => %s,\n",
03007                          inst1_input1);
03008                 fprintf (fptr,
03009                          "                            inst2_input1 => %s,\n",
03010                          inst2_input1);
03011                 fprintf (fptr,
03012                          "                            inst3_input1 => %s,\n",
03013                          inst3_input1);
03014                 fprintf (fptr,
03015                          "                            inst4_input1 => %s,\n",
03016                          inst4_input1);
03017                 fprintf (fptr,
03018                          "                            inst5_input1 => %s,\n",
03019                          inst5_input1);
03020                 fprintf (fptr,
03021                          "                            inst6_input1 => %s,\n",
03022                          inst6_input1);
03023                 fprintf (fptr,
03024                          "                            uif_enable => \"11111100\",\n");
03025                 fprintf (fptr,
03026                          "                            inst1_output => %s,\n",
03027                          inst1_output);
03028                 fprintf (fptr,
03029                          "                            inst2_output => %s,\n",
03030                          inst2_output);
03031                 fprintf (fptr,
03032                          "                            inst3_output => %s,\n",
03033                          inst3_output);
03034                 fprintf (fptr,
03035                          "                            inst4_output => %s,\n",
03036                          inst4_output);
03037                 fprintf (fptr,
03038                          "                            inst5_output => %s,\n",
03039                          inst5_output);
03040                 fprintf (fptr,
03041                          "                            inst6_output => %s);\n",
03042                          inst6_output);
03043                 // now call node_printvhdl for the correct nodes
03044                 Node_PrintVHDL (net, Func_FirstArg (instance1), fptr,
03045                                 nodeToNameHash, processedNodes,
03046                                 uifInstantiateHash, uifToNumInputs,
03047                                 vector_width);
03048                 Node_PrintVHDL (net, Func_FirstArg (instance2), fptr,
03049                                 nodeToNameHash, processedNodes,
03050                                 uifInstantiateHash, uifToNumInputs,
03051                                 vector_width);
03052                 Node_PrintVHDL (net, Func_FirstArg (instance3), fptr,
03053                                 nodeToNameHash, processedNodes,
03054                                 uifInstantiateHash, uifToNumInputs,
03055                                 vector_width);
03056                 Node_PrintVHDL (net, Func_FirstArg (instance4), fptr,
03057                                 nodeToNameHash, processedNodes,
03058                                 uifInstantiateHash, uifToNumInputs,
03059                                 vector_width);
03060                 Node_PrintVHDL (net, Func_FirstArg (instance5), fptr,
03061                                 nodeToNameHash, processedNodes,
03062                                 uifInstantiateHash, uifToNumInputs,
03063                                 vector_width);
03064                 Node_PrintVHDL (net, Func_FirstArg (instance6), fptr,
03065                                 nodeToNameHash, processedNodes,
03066                                 uifInstantiateHash, uifToNumInputs,
03067                                 vector_width);
03068               }
03069             else
03070               {
03071                 assert (0);
03072               }
03073             break;
03074           case 2:
03075             if (num_instantiations == 1)
03076               {
03077                 fprintf (fptr,
03078                          "uif_%s: two_input_uif_model generic map (width => %d, addrtotal => 16)\n",
03079                          (char *) aFormula->lchild, vector_width);
03080                 fprintf (fptr, "port map(\n");
03081                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (aFormula),
03082                            (char **) &input1);
03083                 fprintf (fptr,
03084                          "                            inst1_input1 => %s,\n",
03085                          input1);
03086                 st_lookup (nodeToNameHash, (char *) Func_SecondArg (aFormula),
03087                            (char **) &input2);
03088                 fprintf (fptr,
03089                          "                            inst1_input2 => %s,\n",
03090                          input2);
03091                 fprintf (fptr,
03092                          "                            uif_enable => \"10000000\",\n");
03093                 fprintf (fptr,
03094                          "                            inst1_output => %s);\n",
03095                          uifname);
03096                 Node_PrintVHDL (net, Func_FirstArg (aFormula), fptr,
03097                                 nodeToNameHash, processedNodes,
03098                                 uifInstantiateHash, uifToNumInputs,
03099                                 vector_width);
03100                 Node_PrintVHDL (net, Func_SecondArg (aFormula), fptr,
03101                                 nodeToNameHash, processedNodes,
03102                                 uifInstantiateHash, uifToNumInputs,
03103                                 vector_width);
03104               }
03105             else if (num_instantiations == 2)
03106               {
03107                 fprintf (fptr,
03108                          "uif_%s: two_input_uif_model generic map (width => %d, addrtotal => 16)\n",
03109                          (char *) aFormula->lchild, vector_width);
03110                 fprintf (fptr, "port map(\n");
03111                 char *inst1_input1, *inst1_input2, *inst2_input1,
03112                   *inst2_input2, *inst1_output, *inst2_output;
03113                 Fnode *instance1 = array_fetch (Fnode *, instance_array, 0);
03114                 Fnode *instance2 = array_fetch (Fnode *, instance_array, 1);
03115                 st_lookup (nodeToNameHash, (char *) instance1,
03116                            (char **) &inst1_output);
03117                 st_lookup (nodeToNameHash, (char *) instance2,
03118                            (char **) &inst2_output);
03119                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance1),
03120                            (char **) &inst1_input1);
03121                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance2),
03122                            (char **) &inst2_input1);
03123                 st_lookup (nodeToNameHash,
03124                            (char *) Func_SecondArg (instance1),
03125                            (char **) &inst1_input2);
03126                 st_lookup (nodeToNameHash,
03127                            (char *) Func_SecondArg (instance2),
03128                            (char **) &inst2_input2);
03129                 fprintf (fptr,
03130                          "                            inst1_input1 => %s,\n",
03131                          inst1_input1);
03132                 fprintf (fptr,
03133                          "                            inst1_input2 => %s,\n",
03134                          inst1_input2);
03135                 fprintf (fptr,
03136                          "                            inst2_input1 => %s,\n",
03137                          inst2_input1);
03138                 fprintf (fptr,
03139                          "                            inst2_input2 => %s,\n",
03140                          inst2_input2);
03141                 fprintf (fptr,
03142                          "                            uif_enable => \"11000000\",\n");
03143                 fprintf (fptr,
03144                          "                            inst1_output => %s,\n",
03145                          inst1_output);
03146                 fprintf (fptr,
03147                          "                            inst2_output => %s);\n",
03148                          inst2_output);
03149                 // now call node_printvhdl for the correct nodes
03150                 Node_PrintVHDL (net, Func_FirstArg (instance1), fptr,
03151                                 nodeToNameHash, processedNodes,
03152                                 uifInstantiateHash, uifToNumInputs,
03153                                 vector_width);
03154                 Node_PrintVHDL (net, Func_SecondArg (instance1), fptr,
03155                                 nodeToNameHash, processedNodes,
03156                                 uifInstantiateHash, uifToNumInputs,
03157                                 vector_width);
03158                 Node_PrintVHDL (net, Func_FirstArg (instance2), fptr,
03159                                 nodeToNameHash, processedNodes,
03160                                 uifInstantiateHash, uifToNumInputs,
03161                                 vector_width);
03162                 Node_PrintVHDL (net, Func_SecondArg (instance2), fptr,
03163                                 nodeToNameHash, processedNodes,
03164                                 uifInstantiateHash, uifToNumInputs,
03165                                 vector_width);
03166               }
03167             else if (num_instantiations == 3)
03168               {
03169                 fprintf (fptr,
03170                          "uif_%s: two_input_uif_model generic map (width => %d, addrtotal => 16)\n",
03171                          (char *) aFormula->lchild, vector_width);
03172                 fprintf (fptr, "port map(\n");
03173                 char *inst1_input1, *inst1_input2, *inst2_input1,
03174                   *inst2_input2, *inst3_input1, *inst3_input2, *inst1_output,
03175                   *inst2_output, *inst3_output;
03176                 Fnode *instance1 = array_fetch (Fnode *, instance_array, 0);
03177                 Fnode *instance2 = array_fetch (Fnode *, instance_array, 1);
03178                 Fnode *instance3 = array_fetch (Fnode *, instance_array, 2);
03179                 st_lookup (nodeToNameHash, (char *) instance1,
03180                            (char **) &inst1_output);
03181                 st_lookup (nodeToNameHash, (char *) instance2,
03182                            (char **) &inst2_output);
03183                 st_lookup (nodeToNameHash, (char *) instance3,
03184                            (char **) &inst3_output);
03185                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance1),
03186                            (char **) &inst1_input1);
03187                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance2),
03188                            (char **) &inst2_input1);
03189                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance3),
03190                            (char **) &inst3_input1);
03191                 st_lookup (nodeToNameHash,
03192                            (char *) Func_SecondArg (instance1),
03193                            (char **) &inst1_input2);
03194                 st_lookup (nodeToNameHash,
03195                            (char *) Func_SecondArg (instance2),
03196                            (char **) &inst2_input2);
03197                 st_lookup (nodeToNameHash,
03198                            (char *) Func_SecondArg (instance3),
03199                            (char **) &inst3_input2);
03200                 fprintf (fptr,
03201                          "                            inst1_input1 => %s,\n",
03202                          inst1_input1);
03203                 fprintf (fptr,
03204                          "                            inst1_input2 => %s,\n",
03205                          inst1_input2);
03206                 fprintf (fptr,
03207                          "                            inst2_input1 => %s,\n",
03208                          inst2_input1);
03209                 fprintf (fptr,
03210                          "                            inst2_input2 => %s,\n",
03211                          inst2_input2);
03212                 fprintf (fptr,
03213                          "                            inst3_input1 => %s,\n",
03214                          inst3_input1);
03215                 fprintf (fptr,
03216                          "                            inst3_input2 => %s,\n",
03217                          inst3_input2);
03218                 fprintf (fptr,
03219                          "                            uif_enable => \"11100000\",\n");
03220                 fprintf (fptr,
03221                          "                            inst1_output => %s,\n",
03222                          inst1_output);
03223                 fprintf (fptr,
03224                          "                            inst2_output => %s,\n",
03225                          inst2_output);
03226                 fprintf (fptr,
03227                          "                            inst3_output => %s);\n",
03228                          inst3_output);
03229                 // now call node_printvhdl for the correct nodes
03230                 Node_PrintVHDL (net, Func_FirstArg (instance1), fptr,
03231                                 nodeToNameHash, processedNodes,
03232                                 uifInstantiateHash, uifToNumInputs,
03233                                 vector_width);
03234                 Node_PrintVHDL (net, Func_SecondArg (instance1), fptr,
03235                                 nodeToNameHash, processedNodes,
03236                                 uifInstantiateHash, uifToNumInputs,
03237                                 vector_width);
03238                 Node_PrintVHDL (net, Func_FirstArg (instance2), fptr,
03239                                 nodeToNameHash, processedNodes,
03240                                 uifInstantiateHash, uifToNumInputs,
03241                                 vector_width);
03242                 Node_PrintVHDL (net, Func_SecondArg (instance2), fptr,
03243                                 nodeToNameHash, processedNodes,
03244                                 uifInstantiateHash, uifToNumInputs,
03245                                 vector_width);
03246                 Node_PrintVHDL (net, Func_FirstArg (instance3), fptr,
03247                                 nodeToNameHash, processedNodes,
03248                                 uifInstantiateHash, uifToNumInputs,
03249                                 vector_width);
03250                 Node_PrintVHDL (net, Func_SecondArg (instance3), fptr,
03251                                 nodeToNameHash, processedNodes,
03252                                 uifInstantiateHash, uifToNumInputs,
03253                                 vector_width);
03254               }
03255             else if (num_instantiations == 6)
03256               {
03257                 fprintf (fptr,
03258                          "uif_%s: two_input_uif_model generic map (width => %d, addrtotal => 64)\n",
03259                          (char *) aFormula->lchild, vector_width);
03260                 fprintf (fptr, "port map(\n");
03261                 char *inst1_input1, *inst1_input2, *inst2_input1,
03262                   *inst2_input2, *inst3_input1, *inst3_input2, *inst1_output,
03263                   *inst2_output, *inst3_output;
03264                 char *inst4_input1, *inst4_input2, *inst5_input1,
03265                   *inst5_input2, *inst6_input1, *inst6_input2, *inst4_output,
03266                   *inst5_output, *inst6_output;
03267                 Fnode *instance1 = array_fetch (Fnode *, instance_array, 0);
03268                 Fnode *instance2 = array_fetch (Fnode *, instance_array, 1);
03269                 Fnode *instance3 = array_fetch (Fnode *, instance_array, 2);
03270                 Fnode *instance4 = array_fetch (Fnode *, instance_array, 3);
03271                 Fnode *instance5 = array_fetch (Fnode *, instance_array, 4);
03272                 Fnode *instance6 = array_fetch (Fnode *, instance_array, 5);
03273                 st_lookup (nodeToNameHash, (char *) instance1,
03274                            (char **) &inst1_output);
03275                 st_lookup (nodeToNameHash, (char *) instance2,
03276                            (char **) &inst2_output);
03277                 st_lookup (nodeToNameHash, (char *) instance3,
03278                            (char **) &inst3_output);
03279                 st_lookup (nodeToNameHash, (char *) instance4,
03280                            (char **) &inst4_output);
03281                 st_lookup (nodeToNameHash, (char *) instance5,
03282                            (char **) &inst5_output);
03283                 st_lookup (nodeToNameHash, (char *) instance6,
03284                            (char **) &inst6_output);
03285 
03286                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance1),
03287                            (char **) &inst1_input1);
03288                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance2),
03289                            (char **) &inst2_input1);
03290                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance3),
03291                            (char **) &inst3_input1);
03292                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance4),
03293                            (char **) &inst4_input1);
03294                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance5),
03295                            (char **) &inst5_input1);
03296                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance6),
03297                            (char **) &inst6_input1);
03298 
03299                 st_lookup (nodeToNameHash,
03300                            (char *) Func_SecondArg (instance1),
03301                            (char **) &inst1_input2);
03302                 st_lookup (nodeToNameHash,
03303                            (char *) Func_SecondArg (instance2),
03304                            (char **) &inst2_input2);
03305                 st_lookup (nodeToNameHash,
03306                            (char *) Func_SecondArg (instance3),
03307                            (char **) &inst3_input2);
03308                 st_lookup (nodeToNameHash,
03309                            (char *) Func_SecondArg (instance4),
03310                            (char **) &inst4_input2);
03311                 st_lookup (nodeToNameHash,
03312                            (char *) Func_SecondArg (instance5),
03313                            (char **) &inst5_input2);
03314                 st_lookup (nodeToNameHash,
03315                            (char *) Func_SecondArg (instance6),
03316                            (char **) &inst6_input2);
03317 
03318                 fprintf (fptr,
03319                          "                            inst1_input1 => %s,\n",
03320                          inst1_input1);
03321                 fprintf (fptr,
03322                          "                            inst1_input2 => %s,\n",
03323                          inst1_input2);
03324                 fprintf (fptr,
03325                          "                            inst2_input1 => %s,\n",
03326                          inst2_input1);
03327                 fprintf (fptr,
03328                          "                            inst2_input2 => %s,\n",
03329                          inst2_input2);
03330                 fprintf (fptr,
03331                          "                            inst3_input1 => %s,\n",
03332                          inst3_input1);
03333                 fprintf (fptr,
03334                          "                            inst3_input2 => %s,\n",
03335                          inst3_input2);
03336                 fprintf (fptr,
03337                          "                            inst4_input1 => %s,\n",
03338                          inst4_input1);
03339                 fprintf (fptr,
03340                          "                            inst4_input2 => %s,\n",
03341                          inst4_input2);
03342                 fprintf (fptr,
03343                          "                            inst5_input1 => %s,\n",
03344                          inst5_input1);
03345                 fprintf (fptr,
03346                          "                            inst5_input2 => %s,\n",
03347                          inst5_input2);
03348                 fprintf (fptr,
03349                          "                            inst6_input1 => %s,\n",
03350                          inst6_input1);
03351                 fprintf (fptr,
03352                          "                            inst6_input2 => %s,\n",
03353                          inst6_input2);
03354                 fprintf (fptr,
03355                          "                            uif_enable => \"11111100\",\n");
03356                 fprintf (fptr,
03357                          "                            inst1_output => %s,\n",
03358                          inst1_output);
03359                 fprintf (fptr,
03360                          "                            inst2_output => %s,\n",
03361                          inst2_output);
03362                 fprintf (fptr,
03363                          "                            inst3_output => %s,\n",
03364                          inst3_output);
03365                 fprintf (fptr,
03366                          "                            inst4_output => %s,\n",
03367                          inst4_output);
03368                 fprintf (fptr,
03369                          "                            inst5_output => %s,\n",
03370                          inst5_output);
03371                 fprintf (fptr,
03372                          "                            inst6_output => %s);\n",
03373                          inst6_output);
03374                 // now call node_printvhdl for the correct nodes
03375                 Node_PrintVHDL (net, Func_FirstArg (instance1), fptr,
03376                                 nodeToNameHash, processedNodes,
03377                                 uifInstantiateHash, uifToNumInputs,
03378                                 vector_width);
03379                 Node_PrintVHDL (net, Func_SecondArg (instance1), fptr,
03380                                 nodeToNameHash, processedNodes,
03381                                 uifInstantiateHash, uifToNumInputs,
03382                                 vector_width);
03383                 Node_PrintVHDL (net, Func_FirstArg (instance2), fptr,
03384                                 nodeToNameHash, processedNodes,
03385                                 uifInstantiateHash, uifToNumInputs,
03386                                 vector_width);
03387                 Node_PrintVHDL (net, Func_SecondArg (instance2), fptr,
03388                                 nodeToNameHash, processedNodes,
03389                                 uifInstantiateHash, uifToNumInputs,
03390                                 vector_width);
03391                 Node_PrintVHDL (net, Func_FirstArg (instance3), fptr,
03392                                 nodeToNameHash, processedNodes,
03393                                 uifInstantiateHash, uifToNumInputs,
03394                                 vector_width);
03395                 Node_PrintVHDL (net, Func_SecondArg (instance3), fptr,
03396                                 nodeToNameHash, processedNodes,
03397                                 uifInstantiateHash, uifToNumInputs,
03398                                 vector_width);
03399                 Node_PrintVHDL (net, Func_FirstArg (instance4), fptr,
03400                                 nodeToNameHash, processedNodes,
03401                                 uifInstantiateHash, uifToNumInputs,
03402                                 vector_width);
03403                 Node_PrintVHDL (net, Func_SecondArg (instance4), fptr,
03404                                 nodeToNameHash, processedNodes,
03405                                 uifInstantiateHash, uifToNumInputs,
03406                                 vector_width);
03407                 Node_PrintVHDL (net, Func_FirstArg (instance5), fptr,
03408                                 nodeToNameHash, processedNodes,
03409                                 uifInstantiateHash, uifToNumInputs,
03410                                 vector_width);
03411                 Node_PrintVHDL (net, Func_SecondArg (instance5), fptr,
03412                                 nodeToNameHash, processedNodes,
03413                                 uifInstantiateHash, uifToNumInputs,
03414                                 vector_width);
03415                 Node_PrintVHDL (net, Func_FirstArg (instance6), fptr,
03416                                 nodeToNameHash, processedNodes,
03417                                 uifInstantiateHash, uifToNumInputs,
03418                                 vector_width);
03419                 Node_PrintVHDL (net, Func_SecondArg (instance6), fptr,
03420                                 nodeToNameHash, processedNodes,
03421                                 uifInstantiateHash, uifToNumInputs,
03422                                 vector_width);
03423               }
03424             else
03425               {
03426                 assert (0);
03427               }
03428             break;
03429           case 3:
03430             if (num_instantiations == 1)
03431               {
03432                 fprintf (fptr,
03433                          "uif_%s: three_input_uif_model generic map (width => %d, addrtotal => 16)\n",
03434                          (char *) aFormula->lchild, vector_width);
03435                 fprintf (fptr, "port map(\n");
03436                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (aFormula),
03437                            (char **) &input1);
03438                 fprintf (fptr,
03439                          "                            inst1_input1 => %s,\n",
03440                          input1);
03441                 st_lookup (nodeToNameHash, (char *) Func_SecondArg (aFormula),
03442                            (char **) &input2);
03443                 fprintf (fptr,
03444                          "                            inst1_input2 => %s,\n",
03445                          input2);
03446                 st_lookup (nodeToNameHash, (char *) Func_ThirdArg (aFormula),
03447                            (char **) &input3);
03448                 fprintf (fptr,
03449                          "                            inst1_input3 => %s,\n",
03450                          input3);
03451                 fprintf (fptr,
03452                          "                            uif_enable => \"10000000\",\n");
03453                 fprintf (fptr,
03454                          "                            inst1_output => %s);\n",
03455                          uifname);
03456                 Node_PrintVHDL (net, Func_FirstArg (aFormula), fptr,
03457                                 nodeToNameHash, processedNodes,
03458                                 uifInstantiateHash, uifToNumInputs,
03459                                 vector_width);
03460                 Node_PrintVHDL (net, Func_SecondArg (aFormula), fptr,
03461                                 nodeToNameHash, processedNodes,
03462                                 uifInstantiateHash, uifToNumInputs,
03463                                 vector_width);
03464                 Node_PrintVHDL (net, Func_ThirdArg (aFormula), fptr,
03465                                 nodeToNameHash, processedNodes,
03466                                 uifInstantiateHash, uifToNumInputs,
03467                                 vector_width);
03468               }
03469             else if (num_instantiations == 2)
03470               {
03471                 fprintf (fptr,
03472                          "uif_%s: three_input_uif_model generic map (width => %d, addrtotal => 16)\n",
03473                          (char *) aFormula->lchild, vector_width);
03474                 fprintf (fptr, "port map(\n");
03475                 char *inst1_input1, *inst1_input2, *inst1_input3,
03476                   *inst2_input1, *inst2_input2, *inst2_input3, *inst1_output,
03477                   *inst2_output;
03478                 Fnode *instance1 = array_fetch (Fnode *, instance_array, 0);
03479                 Fnode *instance2 = array_fetch (Fnode *, instance_array, 1);
03480                 st_lookup (nodeToNameHash, (char *) instance1,
03481                            (char **) &inst1_output);
03482                 st_lookup (nodeToNameHash, (char *) instance2,
03483                            (char **) &inst2_output);
03484                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance1),
03485                            (char **) &inst1_input1);
03486                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance2),
03487                            (char **) &inst2_input1);
03488                 st_lookup (nodeToNameHash,
03489                            (char *) Func_SecondArg (instance1),
03490                            (char **) &inst1_input2);
03491                 st_lookup (nodeToNameHash,
03492                            (char *) Func_SecondArg (instance2),
03493                            (char **) &inst2_input2);
03494                 st_lookup (nodeToNameHash, (char *) Func_ThirdArg (instance1),
03495                            (char **) &inst1_input3);
03496                 st_lookup (nodeToNameHash, (char *) Func_ThirdArg (instance2),
03497                            (char **) &inst2_input3);
03498                 fprintf (fptr,
03499                          "                            inst1_input1 => %s,\n",
03500                          inst1_input1);
03501                 fprintf (fptr,
03502                          "                            inst1_input2 => %s,\n",
03503                          inst1_input2);
03504                 fprintf (fptr,
03505                          "                            inst1_input3 => %s,\n",
03506                          inst1_input3);
03507                 fprintf (fptr,
03508                          "                            inst2_input1 => %s,\n",
03509                          inst2_input1);
03510                 fprintf (fptr,
03511                          "                            inst2_input2 => %s,\n",
03512                          inst2_input2);
03513                 fprintf (fptr,
03514                          "                            inst2_input3 => %s,\n",
03515                          inst2_input3);
03516                 fprintf (fptr,
03517                          "                            uif_enable => \"11000000\",\n");
03518                 fprintf (fptr,
03519                          "                            inst1_output => %s,\n",
03520                          inst1_output);
03521                 fprintf (fptr,
03522                          "                            inst2_output => %s);\n",
03523                          inst2_output);
03524                 // now call node_printvhdl for the correct nodes
03525                 Node_PrintVHDL (net, Func_FirstArg (instance1), fptr,
03526                                 nodeToNameHash, processedNodes,
03527                                 uifInstantiateHash, uifToNumInputs,
03528                                 vector_width);
03529                 Node_PrintVHDL (net, Func_SecondArg (instance1), fptr,
03530                                 nodeToNameHash, processedNodes,
03531                                 uifInstantiateHash, uifToNumInputs,
03532                                 vector_width);
03533                 Node_PrintVHDL (net, Func_ThirdArg (instance1), fptr,
03534                                 nodeToNameHash, processedNodes,
03535                                 uifInstantiateHash, uifToNumInputs,
03536                                 vector_width);
03537                 Node_PrintVHDL (net, Func_FirstArg (instance2), fptr,
03538                                 nodeToNameHash, processedNodes,
03539                                 uifInstantiateHash, uifToNumInputs,
03540                                 vector_width);
03541                 Node_PrintVHDL (net, Func_SecondArg (instance2), fptr,
03542                                 nodeToNameHash, processedNodes,
03543                                 uifInstantiateHash, uifToNumInputs,
03544                                 vector_width);
03545                 Node_PrintVHDL (net, Func_ThirdArg (instance2), fptr,
03546                                 nodeToNameHash, processedNodes,
03547                                 uifInstantiateHash, uifToNumInputs,
03548                                 vector_width);
03549               }
03550             else if (num_instantiations == 3)
03551               {
03552                 fprintf (fptr,
03553                          "uif_%s: three_input_uif_model generic map (width => %d, addrtotal => 16)\n",
03554                          (char *) aFormula->lchild, vector_width);
03555                 fprintf (fptr, "port map(\n");
03556                 char *inst1_input1, *inst1_input2, *inst1_input3,
03557                   *inst2_input1, *inst2_input2, *inst2_input3, *inst3_input1,
03558                   *inst3_input2, *inst3_input3, *inst1_output, *inst2_output,
03559                   *inst3_output;
03560                 Fnode *instance1 = array_fetch (Fnode *, instance_array, 0);
03561                 Fnode *instance2 = array_fetch (Fnode *, instance_array, 1);
03562                 Fnode *instance3 = array_fetch (Fnode *, instance_array, 2);
03563                 st_lookup (nodeToNameHash, (char *) instance1,
03564                            (char **) &inst1_output);
03565                 st_lookup (nodeToNameHash, (char *) instance2,
03566                            (char **) &inst2_output);
03567                 st_lookup (nodeToNameHash, (char *) instance3,
03568                            (char **) &inst3_output);
03569                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance1),
03570                            (char **) &inst1_input1);
03571                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance2),
03572                            (char **) &inst2_input1);
03573                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance3),
03574                            (char **) &inst3_input1);
03575                 st_lookup (nodeToNameHash,
03576                            (char *) Func_SecondArg (instance1),
03577                            (char **) &inst1_input2);
03578                 st_lookup (nodeToNameHash,
03579                            (char *) Func_SecondArg (instance2),
03580                            (char **) &inst2_input2);
03581                 st_lookup (nodeToNameHash,
03582                            (char *) Func_SecondArg (instance3),
03583                            (char **) &inst3_input2);
03584                 st_lookup (nodeToNameHash, (char *) Func_ThirdArg (instance1),
03585                            (char **) &inst1_input3);
03586                 st_lookup (nodeToNameHash, (char *) Func_ThirdArg (instance2),
03587                            (char **) &inst2_input3);
03588                 st_lookup (nodeToNameHash, (char *) Func_ThirdArg (instance3),
03589                            (char **) &inst3_input3);
03590                 fprintf (fptr,
03591                          "                            inst1_input1 => %s,\n",
03592                          inst1_input1);
03593                 fprintf (fptr,
03594                          "                            inst1_input2 => %s,\n",
03595                          inst1_input2);
03596                 fprintf (fptr,
03597                          "                            inst1_input3 => %s,\n",
03598                          inst1_input3);
03599                 fprintf (fptr,
03600                          "                            inst2_input1 => %s,\n",
03601                          inst2_input1);
03602                 fprintf (fptr,
03603                          "                            inst2_input2 => %s,\n",
03604                          inst2_input2);
03605                 fprintf (fptr,
03606                          "                            inst2_input3 => %s,\n",
03607                          inst2_input3);
03608                 fprintf (fptr,
03609                          "                            inst3_input1 => %s,\n",
03610                          inst3_input1);
03611                 fprintf (fptr,
03612                          "                            inst3_input2 => %s,\n",
03613                          inst3_input2);
03614                 fprintf (fptr,
03615                          "                            inst3_input3 => %s,\n",
03616                          inst3_input3);
03617                 fprintf (fptr,
03618                          "                            uif_enable => \"11100000\",\n");
03619                 fprintf (fptr,
03620                          "                            inst1_output => %s,\n",
03621                          inst1_output);
03622                 fprintf (fptr,
03623                          "                            inst2_output => %s,\n",
03624                          inst2_output);
03625                 fprintf (fptr,
03626                          "                            inst3_output => %s);\n",
03627                          inst3_output);
03628                 // now call node_printvhdl for the correct nodes
03629                 Node_PrintVHDL (net, Func_FirstArg (instance1), fptr,
03630                                 nodeToNameHash, processedNodes,
03631                                 uifInstantiateHash, uifToNumInputs,
03632                                 vector_width);
03633                 Node_PrintVHDL (net, Func_SecondArg (instance1), fptr,
03634                                 nodeToNameHash, processedNodes,
03635                                 uifInstantiateHash, uifToNumInputs,
03636                                 vector_width);
03637                 Node_PrintVHDL (net, Func_ThirdArg (instance1), fptr,
03638                                 nodeToNameHash, processedNodes,
03639                                 uifInstantiateHash, uifToNumInputs,
03640                                 vector_width);
03641                 Node_PrintVHDL (net, Func_FirstArg (instance2), fptr,
03642                                 nodeToNameHash, processedNodes,
03643                                 uifInstantiateHash, uifToNumInputs,
03644                                 vector_width);
03645                 Node_PrintVHDL (net, Func_SecondArg (instance2), fptr,
03646                                 nodeToNameHash, processedNodes,
03647                                 uifInstantiateHash, uifToNumInputs,
03648                                 vector_width);
03649                 Node_PrintVHDL (net, Func_ThirdArg (instance2), fptr,
03650                                 nodeToNameHash, processedNodes,
03651                                 uifInstantiateHash, uifToNumInputs,
03652                                 vector_width);
03653                 Node_PrintVHDL (net, Func_FirstArg (instance3), fptr,
03654                                 nodeToNameHash, processedNodes,
03655                                 uifInstantiateHash, uifToNumInputs,
03656                                 vector_width);
03657                 Node_PrintVHDL (net, Func_SecondArg (instance3), fptr,
03658                                 nodeToNameHash, processedNodes,
03659                                 uifInstantiateHash, uifToNumInputs,
03660                                 vector_width);
03661                 Node_PrintVHDL (net, Func_ThirdArg (instance3), fptr,
03662                                 nodeToNameHash, processedNodes,
03663                                 uifInstantiateHash, uifToNumInputs,
03664                                 vector_width);
03665               }
03666             else if (num_instantiations == 4)
03667               {
03668                 fprintf (fptr,
03669                          "uif_%s: three_input_uif_model generic map (width => %d, addrtotal => 16)\n",
03670                          (char *) aFormula->lchild, vector_width);
03671                 fprintf (fptr, "port map(\n");
03672                 char *inst1_input1, *inst1_input2, *inst1_input3;
03673                 char *inst2_input1, *inst2_input2, *inst2_input3;
03674                 char *inst3_input1, *inst3_input2, *inst3_input3;
03675                 char *inst4_input1, *inst4_input2, *inst4_input3;
03676                 char *inst1_output, *inst2_output, *inst3_output,
03677                   *inst4_output;
03678                 Fnode *instance1 = array_fetch (Fnode *, instance_array, 0);
03679                 Fnode *instance2 = array_fetch (Fnode *, instance_array, 1);
03680                 Fnode *instance3 = array_fetch (Fnode *, instance_array, 2);
03681                 Fnode *instance4 = array_fetch (Fnode *, instance_array, 3);
03682 
03683                 st_lookup (nodeToNameHash, (char *) instance1,
03684                            (char **) &inst1_output);
03685                 st_lookup (nodeToNameHash, (char *) instance2,
03686                            (char **) &inst2_output);
03687                 st_lookup (nodeToNameHash, (char *) instance3,
03688                            (char **) &inst3_output);
03689                 st_lookup (nodeToNameHash, (char *) instance4,
03690                            (char **) &inst4_output);
03691 
03692                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance1),
03693                            (char **) &inst1_input1);
03694                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance2),
03695                            (char **) &inst2_input1);
03696                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance3),
03697                            (char **) &inst3_input1);
03698                 st_lookup (nodeToNameHash, (char *) Func_FirstArg (instance4),
03699                            (char **) &inst4_input1);
03700 
03701                 st_lookup (nodeToNameHash,
03702                            (char *) Func_SecondArg (instance1),
03703                            (char **) &inst1_input2);
03704                 st_lookup (nodeToNameHash,
03705                            (char *) Func_SecondArg (instance2),
03706                            (char **) &inst2_input2);
03707                 st_lookup (nodeToNameHash,
03708                            (char *) Func_SecondArg (instance3),
03709                            (char **) &inst3_input2);
03710                 st_lookup (nodeToNameHash,
03711                            (char *) Func_SecondArg (instance4),
03712                            (char **) &inst4_input2);
03713 
03714                 st_lookup (nodeToNameHash, (char *) Func_ThirdArg (instance1),
03715                            (char **) &inst1_input3);
03716                 st_lookup (nodeToNameHash, (char *) Func_ThirdArg (instance2),
03717                            (char **) &inst2_input3);
03718                 st_lookup (nodeToNameHash, (char *) Func_ThirdArg (instance3),
03719                            (char **) &inst3_input3);
03720                 st_lookup (nodeToNameHash, (char *) Func_ThirdArg (instance4),
03721                            (char **) &inst4_input3);
03722 
03723                 fprintf (fptr,
03724                          "                            inst1_input1 => %s,\n",
03725                          inst1_input1);
03726                 fprintf (fptr,
03727                          "                            inst1_input2 => %s,\n",
03728                          inst1_input2);
03729                 fprintf (fptr,
03730                          "                            inst1_input3 => %s,\n",
03731                          inst1_input3);
03732                 fprintf (fptr,
03733                          "                            inst2_input1 => %s,\n",
03734                          inst2_input1);
03735                 fprintf (fptr,
03736                          "                            inst2_input2 => %s,\n",
03737                          inst2_input2);
03738                 fprintf (fptr,
03739                          "                            inst2_input3 => %s,\n",
03740                          inst2_input3);
03741                 fprintf (fptr,
03742                          "                            inst3_input1 => %s,\n",
03743                          inst3_input1);
03744                 fprintf (fptr,
03745                          "                            inst3_input2 => %s,\n",
03746                          inst3_input2);
03747                 fprintf (fptr,
03748                          "                            inst3_input3 => %s,\n",
03749                          inst3_input3);
03750                 fprintf (fptr,
03751                          "                            inst4_input1 => %s,\n",
03752                          inst4_input1);
03753                 fprintf (fptr,
03754                          "                            inst4_input2 => %s,\n",
03755                          inst4_input2);
03756                 fprintf (fptr,
03757                          "                            inst4_input3 => %s,\n",
03758                          inst4_input3);
03759                 fprintf (fptr,
03760                          "                            uif_enable => \"11110000\",\n");
03761                 fprintf (fptr,
03762                          "                            inst1_output => %s,\n",
03763                          inst1_output);
03764                 fprintf (fptr,
03765                          "                            inst2_output => %s,\n",
03766                          inst2_output);
03767                 fprintf (fptr,
03768                          "                            inst3_output => %s,\n",
03769                          inst3_output);
03770                 fprintf (fptr,
03771                          "                            inst4_output => %s);\n",
03772                          inst4_output);
03773 
03774                 // now call node_printvhdl for the correct nodes
03775                 Node_PrintVHDL (net, Func_FirstArg (instance1), fptr,
03776                                 nodeToNameHash, processedNodes,
03777                                 uifInstantiateHash, uifToNumInputs,
03778                                 vector_width);
03779                 Node_PrintVHDL (net, Func_SecondArg (instance1), fptr,
03780                                 nodeToNameHash, processedNodes,
03781                                 uifInstantiateHash, uifToNumInputs,
03782                                 vector_width);
03783                 Node_PrintVHDL (net, Func_ThirdArg (instance1), fptr,
03784                                 nodeToNameHash, processedNodes,
03785                                 uifInstantiateHash, uifToNumInputs,
03786                                 vector_width);
03787 
03788                 Node_PrintVHDL (net, Func_FirstArg (instance2), fptr,
03789                                 nodeToNameHash, processedNodes,
03790                                 uifInstantiateHash, uifToNumInputs,
03791                                 vector_width);
03792                 Node_PrintVHDL (net, Func_SecondArg (instance2), fptr,
03793                                 nodeToNameHash, processedNodes,
03794                                 uifInstantiateHash, uifToNumInputs,
03795                                 vector_width);
03796                 Node_PrintVHDL (net, Func_ThirdArg (instance2), fptr,
03797                                 nodeToNameHash, processedNodes,
03798                                 uifInstantiateHash, uifToNumInputs,
03799                                 vector_width);
03800 
03801                 Node_PrintVHDL (net, Func_FirstArg (instance3), fptr,
03802                                 nodeToNameHash, processedNodes,
03803                                 uifInstantiateHash, uifToNumInputs,
03804                                 vector_width);
03805                 Node_PrintVHDL (net, Func_SecondArg (instance3), fptr,
03806                                 nodeToNameHash, processedNodes,
03807                                 uifInstantiateHash, uifToNumInputs,
03808                                 vector_width);
03809                 Node_PrintVHDL (net, Func_ThirdArg (instance3), fptr,
03810                                 nodeToNameHash, processedNodes,
03811                                 uifInstantiateHash, uifToNumInputs,
03812                                 vector_width);
03813 
03814                 Node_PrintVHDL (net, Func_FirstArg (instance4), fptr,
03815                                 nodeToNameHash, processedNodes,
03816                                 uifInstantiateHash, uifToNumInputs,
03817                                 vector_width);
03818                 Node_PrintVHDL (net, Func_SecondArg (instance4), fptr,
03819                                 nodeToNameHash, processedNodes,
03820                                 uifInstantiateHash, uifToNumInputs,
03821                                 vector_width);
03822                 Node_PrintVHDL (net, Func_ThirdArg (instance4), fptr,
03823                                 nodeToNameHash, processedNodes,
03824                                 uifInstantiateHash, uifToNumInputs,
03825                                 vector_width);
03826               }
03827             else
03828               {
03829                 assert (0);
03830               }
03831             break;
03832           default:
03833             assert (0);
03834             break;
03835           }
03836       }
03837   }
03838 
03844   int
03845     ReplaceWritewithRead (Net_t * net, char *writeUifName, char *readUifName)
03846   {
03847 
03848     array_t *readArray;
03849     array_t *writeArray;
03850     int lookup_success, i;
03851     array_t *newReadArray = array_alloc (Fnode *, 0);
03852     // lookup all the instantiations of writeUif
03853     lookup_success =
03854       st_lookup (net->UIFs, (char *) writeUifName, (char **) &writeArray);
03855     assert (lookup_success);
03856 
03857     // lookup all the instantiations of readUif
03858     lookup_success =
03859       st_lookup (net->UIFs, (char *) readUifName, (char **) &readArray);
03860     assert (lookup_success);
03861 
03862     // we will create a writeTable for easy lookup of the writeinstances
03863     st_table *writeTable =
03864       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
03865     for (i = 0; i < array_n (writeArray); i++)
03866       {
03867         Fnode *writeInstance = array_fetch (Fnode *, writeArray, i);
03868         st_insert (writeTable, (char *) writeInstance,
03869                    (char *) writeInstance);
03870       }
03871 
03872 
03873     // iterate through each instantiation of readUif and rebuild its fanin
03874     for (i = 0; i < array_n (readArray); i++)
03875       {
03876         // create a processedTable to store intermediate info
03877         st_table *processedTable =
03878           st_init_table ((int (*)()) st_ptrcmp, (int (*)()) st_ptrhash);
03879         Fnode *readInstance = array_fetch (Fnode *, readArray, i);
03880         Fnode *readSource = Func_FirstArg (readInstance);
03881         Fnode *readAddress = Func_SecondArg (readInstance);
03882         Fnode *newReadNode =
03883           createReadUsingWrite (net, readUifName, readSource, readAddress,
03884                                 writeTable, processedTable);
03885         array_insert_last (Fnode *, newReadArray, newReadNode);
03886         // free the processedTable
03887         st_free_table (processedTable);
03888       }
03889 
03890 
03891     st_table *processedNodes =
03892       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
03893     // now replace the readUifs with newReadNodes 
03894     for (i = 0; i < array_n (readArray); i++)
03895       {
03896         Fnode *oldReadNode = array_fetch (Fnode *, readArray, i);
03897         Fnode *newReadNode = array_fetch (Fnode *, newReadArray, i);
03898         if (oldReadNode != newReadNode)
03899           {
03900             updateFanoutArray (net, newReadNode, nil, processedNodes);
03901             swapNodes (net, oldReadNode, newReadNode);
03902           }
03903       }
03904     return 0;
03905   }
03906 
03912   static Fnode *createReadUsingWrite (Net_t * net,
03913                                       char *readUifName,
03914                                       Fnode * formula,
03915                                       Fnode * readAddress,
03916                                       st_table * writeTable,
03917                                       st_table * processedNodes)
03918   {
03919 
03920     Fnode *result;
03921 
03922     if (formula == nil)
03923       {
03924         return nil;
03925       }
03926 
03927     if (!st_lookup (net->nodeToId, (char *) formula, (char **) 0))
03928       {
03929         // must be a string if it's not nil and not a formula
03930         return formula;
03931       }
03932 
03933     if (st_lookup (processedNodes, (char *) formula, (char **) &result))
03934       {
03935         // node already created
03936         return result;
03937       }
03938 
03939     if ((formula->type == ScalarConst_c) ||
03940         (formula->type == ScalarReg_c) ||
03941         (formula->type == BooleanReg_c) ||
03942         (formula->type == InternalScalarVar_c) ||
03943         (formula->type == InternalBooleanVar_c))
03944       {
03945         // nothing to do    
03946         return formula;
03947       }
03948 
03949     if ((formula->type == ScalarPI_c) || (formula->type == BooleanPI_c))
03950       {
03951         // This is actually the initial value of the writeDestination
03952         Fnode *listNode1 = new_node (List_c, readAddress, nil);
03953         Fnode *listNode2 = new_node (List_c, formula, listNode1);
03954         Fnode *funcNode = new_node (Func_c, (Fnode *) readUifName, listNode2);
03955         return funcNode;
03956       }
03957 
03958     // Now check whether the formula node is a Write 
03959     if (st_lookup (writeTable, (char *) formula, (char **) 0))
03960       {
03961         // it is a write!
03962         // We will now replace the write by a MUX
03963         Fnode *writeAddress = Func_SecondArg (formula);
03964         Fnode *writeDestination = Func_FirstArg (formula);
03965         Fnode *writeData = Func_ThirdArg (formula);
03966 
03967         Fnode *muxCtrl = new_node (Equal_c, writeAddress, readAddress);
03968         Fnode *listNode1 = new_node (List_c, readAddress, nil);
03969         Fnode *listNode2 = new_node (List_c, writeDestination, listNode1);
03970 
03971         Fnode *muxElseNode =
03972           new_node (Func_c, (Fnode *) readUifName, listNode2);
03973         Fnode *muxIfNode = writeData;
03974         Fnode *muxPair = new_node (Pair_c, muxIfNode, muxElseNode);
03975         Fnode *muxNode = new_node (Mux_c, muxCtrl, muxPair);
03976         result = muxNode;
03977         st_insert (processedNodes, (char *) formula, (char *) result);
03978       }
03979     else
03980       {
03981         if (formula->type == Mux_c)
03982           {
03983             Fnode *muxCtrl = formula->lchild;
03984             Fnode *muxIfNode = createReadUsingWrite (net,
03985                                                      readUifName,
03986                                                      Mux_ThenInput (formula),
03987                                                      readAddress,
03988                                                      writeTable,
03989                                                      processedNodes);
03990             Fnode *muxElseNode = createReadUsingWrite (net,
03991                                                        readUifName,
03992                                                        Mux_ElseInput
03993                                                        (formula),
03994                                                        readAddress,
03995                                                        writeTable,
03996                                                        processedNodes);
03997             Fnode *muxPair = new_node (Pair_c, muxIfNode, muxElseNode);
03998             result = new_node (Mux_c, muxCtrl, muxPair);
03999             st_insert (processedNodes, (char *) formula, (char *) result);
04000           }
04001         else
04002           {
04003             Fnode *new_rchild = createReadUsingWrite (net,
04004                                                       readUifName,
04005                                                       formula->rchild,
04006                                                       readAddress,
04007                                                       writeTable,
04008                                                       processedNodes);
04009             Fnode *new_lchild = createReadUsingWrite (net,
04010                                                       readUifName,
04011                                                       formula->lchild,
04012                                                       readAddress,
04013                                                       writeTable,
04014                                                       processedNodes);
04015             result = new_node (formula->type, new_lchild, new_rchild);
04016             st_insert (processedNodes, (char *) formula, (char *) result);
04017           }
04018       }
04019     return result;
04020   }
04021 
04027   int
04028     AddReadatEnd (Net_t * net,
04029                   Fnode * readAddress, char *readUifName, int formula_index)
04030   {
04031 
04032     Fnode *top_formula = array_fetch (Fnode *, net->formulas, formula_index);
04033 
04034     if ((top_formula != nil) && (top_formula->lchild != nil))
04035       {
04036         Fnode *readData1 = top_formula->lchild->lchild;
04037         Fnode *readData2 = top_formula->lchild->rchild;
04038 
04039         Fnode *listNode1 = new_node_raw (List_c, readAddress, nil);
04040         Fnode *listNode2 = new_node_raw (List_c, nil, listNode1);
04041         Fnode *listNode3 = new_node_raw (List_c, nil, listNode1);
04042 
04043         Fnode *funcNode1 =
04044           new_node_raw (Func_c, (Fnode *) readUifName, listNode2);
04045         Fnode *funcNode2 =
04046           new_node_raw (Func_c, (Fnode *) readUifName, listNode3);
04047 
04048         st_table *processedNodes =
04049           st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
04050 
04051         listNode2->lchild = readData1;
04052         listNode3->lchild = readData2;
04053 
04054         updateFanoutArray (net, funcNode1, nil, processedNodes);
04055         updateFanoutArray (net, funcNode2, nil, processedNodes);
04056 
04057         Fnode *new_top_formula_not =
04058           new_node_raw (Equal_c, funcNode1, funcNode2);
04059         Fnode *new_top_formula =
04060           new_node_raw (Not_c, new_top_formula_not, nil);
04061 
04062         updateFanoutArray (net, new_top_formula, nil, processedNodes);
04063         updateFanoutArray (net, funcNode2, nil, processedNodes);
04064 
04065         array_insert (Fnode *, net->formulas, formula_index, new_top_formula);
04066 
04067         //swapNodes(net, readData1, funcNode1);
04068         //swapNodes(net, readData2, funcNode2);
04069       }
04070     return 0;
04071   }
04072 
04073 
04079   int
04080     Net_TopologicalSort (Fnode * aFormula,
04081                          st_table * sortedTable, st_table * processedNodes)
04082   {
04083 
04084     int depth = -1, lchild_depth = -1, rchild_depth = -1;
04085     assert (sortedTable != NIL (st_table));
04086     assert (processedNodes != NIL (st_table));
04087     array_t *depth_array = NIL (array_t);
04088     if (aFormula == nil)
04089       {
04090         // Neither scalar nor boolean 
04091         return 1;
04092       }
04093 
04094     if (st_lookup (processedNodes, (char *) aFormula, (char **) &depth))
04095       {
04096         return depth;
04097       }
04098     // switch on type 
04099     switch (aFormula->type)
04100       {
04101       case Undef_c:
04102         // should not be reached
04103         assert (0);
04104         depth = -1;
04105         break;
04106       case ScalarPI_c:
04107       case InternalScalarVar_c:
04108       case ScalarConst_c:
04109       case ScalarReg_c:
04110       case BooleanPI_c:
04111       case InternalBooleanVar_c:
04112       case TRUE_c:
04113       case FALSE_c:
04114       case BooleanReg_c:
04115         // nodes at depth 1
04116         depth = 1;
04117         break;
04118       case Not_c:
04119         // child_depth + 1
04120         lchild_depth = Net_TopologicalSort (aFormula->lchild,
04121                                             sortedTable, processedNodes);
04122         assert (lchild_depth != -1);
04123         depth = lchild_depth + 1;
04124         break;
04125       case UnaryFunc_c:
04126       case Func_c:
04127         // child_depth + 1
04128         rchild_depth = Net_TopologicalSort (aFormula->rchild,
04129                                             sortedTable, processedNodes);
04130         assert (rchild_depth != -1);
04131         depth = rchild_depth + 1;
04132         break;
04133       case List_c:
04134       case Pair_c:
04135       case Iff_c:
04136       case Equal_c:
04137       case And_c:
04138       case Or_c:
04139       case Mux_c:
04140         // Here the depth would be max(ldepth,rdepth) + 1
04141         lchild_depth = Net_TopologicalSort (aFormula->lchild,
04142                                             sortedTable, processedNodes);
04143         assert (lchild_depth > -1);
04144         rchild_depth = Net_TopologicalSort (aFormula->rchild,
04145                                             sortedTable, processedNodes);
04146         assert (rchild_depth > -1);
04147         depth = (lchild_depth > rchild_depth) ? lchild_depth : rchild_depth;
04148         depth++;
04149         break;
04150       default:
04151         printf ("The type is %d\n", aFormula->type);
04152 
04153         assert (0);
04154       }
04155     assert (depth != -1);
04156     // insert into processedNodes
04157     st_insert (processedNodes, (char *) aFormula, (char *) depth);
04158 
04159     // update the sortedTable
04160     st_lookup (sortedTable, (char *) depth, (char **) &depth_array);
04161     if (depth_array == NIL (array_t))
04162       {
04163         depth_array = array_alloc (Fnode *, 0);
04164         array_insert_last (Fnode *, depth_array, aFormula);
04165         st_insert (sortedTable, (char *) depth, (char *) depth_array);
04166       }
04167     else
04168       {
04169         array_insert_last (Fnode *, depth_array, aFormula);
04170       }
04171 
04172     return depth;
04173   }
04174 
04180   int
04181     Net_ConstantPropagation (st_table * sortedTable,
04182                              st_table * equivalentNodeHash, int max_depth)
04183   {
04184 
04185     int i, j;
04186     assert (sortedTable != NIL (st_table));
04187     assert (equivalentNodeHash != NIL (st_table));
04188     array_t *depth_array = NIL (array_t);
04189     Fnode *aFormula = nil, *lchild = nil, *rchild = nil, *new_aFormula = nil;
04190     Fnode *ctrl_child = nil, *then_child = nil, *else_child = nil;
04191 
04192 
04193     for (i = 1; i <= max_depth; i++)
04194       {
04195         st_lookup (sortedTable, (char *) i, (char **) &depth_array);
04196         assert (depth_array != NIL (array_t));
04197 
04198         for (j = 0; j < array_n (depth_array); j++)
04199           {
04200             aFormula = array_fetch (Fnode *, depth_array, j);
04201             assert (aFormula != nil);
04202 
04203             // switch on type 
04204             switch (aFormula->type)
04205               {
04206               case Undef_c:
04207                 // should not be reached
04208                 assert (0);
04209                 break;
04210               case ScalarPI_c:
04211               case InternalScalarVar_c:
04212               case ScalarConst_c:
04213               case ScalarReg_c:
04214               case BooleanPI_c:
04215               case InternalBooleanVar_c:
04216               case TRUE_c:
04217               case FALSE_c:
04218               case BooleanReg_c:
04219                 // nodes at depth 1
04220                 assert (i == 1);
04221                 new_aFormula = aFormula;
04222                 break;
04223               case Func_c:
04224               case UnaryFunc_c:
04225                 if (!st_lookup (equivalentNodeHash,
04226                                 (char *) aFormula->rchild, (char **) &rchild))
04227                   {
04228                     rchild = aFormula->rchild;
04229                   }
04230                 aFormula->rchild = rchild;
04231                 new_aFormula = aFormula;
04232                 break;
04233               case List_c:
04234               case Pair_c:
04235                 if (!st_lookup (equivalentNodeHash,
04236                                 (char *) aFormula->lchild, (char **) &lchild))
04237                   {
04238                     lchild = aFormula->lchild;
04239                   }
04240                 if (!st_lookup (equivalentNodeHash,
04241                                 (char *) aFormula->rchild, (char **) &rchild))
04242                   {
04243                     rchild = aFormula->rchild;
04244                   }
04245                 aFormula->lchild = lchild;
04246                 aFormula->rchild = rchild;
04247                 new_aFormula = aFormula;
04248                 break;
04249               case Iff_c:
04250               case Equal_c:
04251                 // here we will check the left and right child
04252                 // and if they are equal, this node will be replaced 
04253                 // by one of its children
04254                 assert (i > 1);
04255                 if (!st_lookup (equivalentNodeHash,
04256                                 (char *) aFormula->lchild, (char **) &lchild))
04257                   {
04258                     lchild = aFormula->lchild;
04259                   }
04260                 if (!st_lookup (equivalentNodeHash,
04261                                 (char *) aFormula->rchild, (char **) &rchild))
04262                   {
04263                     rchild = aFormula->rchild;
04264                   }
04265                 if (lchild == rchild)
04266                   {
04267                     new_aFormula = new_node_raw (TRUE_c, nil, nil);
04268                   }
04269                 else if ((lchild->type == ScalarConst_c) &&
04270                          (rchild->type == ScalarConst_c) && 1)
04271                   {
04272                     new_aFormula = new_node_raw (FALSE_c, nil, nil);
04273                   }
04274                 else
04275                   {
04276                     aFormula->lchild = lchild;
04277                     aFormula->rchild = rchild;
04278                     new_aFormula = aFormula;
04279                   }
04280                 break;
04281               case Not_c:
04282                 assert (i > 1);
04283                 if (!st_lookup (equivalentNodeHash,
04284                                 (char *) aFormula->lchild, (char **) &lchild))
04285                   {
04286                     lchild = aFormula->lchild;
04287                   }
04288 
04289                 if (lchild->type == TRUE_c)
04290                   {
04291                     new_aFormula = new_node_raw (FALSE_c, nil, nil);
04292                   }
04293                 else if (lchild->type == FALSE_c)
04294                   {
04295                     new_aFormula = new_node_raw (TRUE_c, nil, nil);
04296                   }
04297                 else
04298                   {
04299                     aFormula->lchild = lchild;
04300                     new_aFormula = aFormula;
04301                   }
04302                 break;
04303               case And_c:
04304                 if (!st_lookup (equivalentNodeHash,
04305                                 (char *) aFormula->lchild, (char **) &lchild))
04306                   {
04307                     lchild = aFormula->lchild;
04308                   }
04309                 if (!st_lookup (equivalentNodeHash,
04310                                 (char *) aFormula->rchild, (char **) &rchild))
04311                   {
04312                     rchild = aFormula->rchild;
04313                   }
04314                 if ((lchild->type == FALSE_c) || (rchild->type == FALSE_c))
04315                   {
04316                     // false if one of the inputs is false 
04317                     new_aFormula = new_node_raw (FALSE_c, nil, nil);
04318                   }
04319                 else if (lchild->type == TRUE_c)
04320                   {
04321                     new_aFormula = rchild;
04322                   }
04323                 else if (rchild->type == TRUE_c)
04324                   {
04325                     new_aFormula = lchild;
04326                   }
04327                 else if (rchild == lchild)
04328                   {
04329                     new_aFormula = lchild;
04330                   }
04331                 else
04332                   {
04333                     aFormula->lchild = lchild;
04334                     aFormula->rchild = rchild;
04335                     new_aFormula = aFormula;
04336                   }
04337                 break;
04338               case Or_c:
04339                 if (!st_lookup (equivalentNodeHash,
04340                                 (char *) aFormula->lchild, (char **) &lchild))
04341                   {
04342                     lchild = aFormula->lchild;
04343                   }
04344                 if (!st_lookup (equivalentNodeHash,
04345                                 (char *) aFormula->rchild, (char **) &rchild))
04346                   {
04347                     rchild = aFormula->rchild;
04348                   }
04349                 if ((lchild->type == TRUE_c) || (rchild->type == TRUE_c))
04350                   {
04351                     // false if one of the inputs is false 
04352                     new_aFormula = new_node_raw (TRUE_c, nil, nil);
04353                   }
04354                 else if (lchild->type == FALSE_c)
04355                   {
04356                     new_aFormula = rchild;
04357                   }
04358                 else if (rchild->type == FALSE_c)
04359                   {
04360                     new_aFormula = lchild;
04361                   }
04362                 else if (rchild == lchild)
04363                   {
04364                     new_aFormula = lchild;
04365                   }
04366                 else
04367                   {
04368                     Fnode *tmp_lchild0, *tmp_rchild0;
04369                     tmp_lchild0 = (lchild < rchild) ? lchild : rchild;
04370                     tmp_rchild0 = (lchild < rchild) ? rchild : lchild;
04371                     aFormula->lchild = tmp_lchild0;
04372                     aFormula->rchild = tmp_rchild0;
04373                     new_aFormula = aFormula;
04374                   }
04375                 break;
04376               case Mux_c:
04377                 if (!st_lookup (equivalentNodeHash,
04378                                 (char *) aFormula->lchild,
04379                                 (char **) &ctrl_child))
04380                   {
04381                     ctrl_child = aFormula->lchild;
04382                   }
04383                 if (!st_lookup (equivalentNodeHash,
04384                                 (char *) aFormula->rchild, (char **) &rchild))
04385                   {
04386                     rchild = aFormula->rchild;
04387                   }
04388                 if (!st_lookup (equivalentNodeHash,
04389                                 (char *) Mux_ThenInput (aFormula),
04390                                 (char **) &then_child))
04391                   {
04392                     then_child = Mux_ThenInput (aFormula);
04393                   }
04394                 if (!st_lookup (equivalentNodeHash,
04395                                 (char *) Mux_ElseInput (aFormula),
04396                                 (char **) &else_child))
04397                   {
04398                     else_child = Mux_ElseInput (aFormula);
04399                   }
04400                 if (ctrl_child->type == TRUE_c)
04401                   {
04402                     new_aFormula = then_child;
04403                   }
04404                 else if (ctrl_child->type == FALSE_c)
04405                   {
04406                     new_aFormula = else_child;
04407                   }
04408                 else if (else_child == then_child)
04409                   {
04410                     new_aFormula = else_child;
04411                   }
04412                 else if ((ctrl_child->type == Equal_c) &&
04413                          ((ctrl_child->lchild == then_child)
04414                           || (ctrl_child->lchild == else_child))
04415                          && ((ctrl_child->rchild == then_child)
04416                              || (ctrl_child->rchild == else_child)) && 1)
04417                   {
04418                     // Review the check above
04419                     new_aFormula = else_child;
04420                   }
04421                 else
04422                   {
04423                     aFormula->lchild = ctrl_child;
04424                     aFormula->rchild = rchild;
04425                     new_aFormula = aFormula;
04426                   }
04427                 break;
04428               default:
04429                 assert (0);
04430               }
04431 
04432             Fnode *unique_aFormula = node_GetUnique (new_aFormula);
04433             // first we have to get the uniqified new_aFormula 
04434 
04435             // insert into equivalentNodeHash
04436             st_insert (equivalentNodeHash, (char *) aFormula,
04437                        (char *) unique_aFormula);
04438           }
04439       }
04440     return 1;
04441   }
04442 
04448   static Fnode *getUnfoldedNode2 (Net_t * net,
04449                                   Fnode * formula,
04450                                   int depth, array_t * newprocessedTableArray)
04451   {
04452     Fnode *result;
04453     char suf[100];
04454     sprintf (suf, "_%d", depth);
04455 
04456     st_table *newprocessedTable =
04457       array_fetch (st_table *, newprocessedTableArray, depth);
04458     // return nil if formula itself is nil
04459     if (formula == nil)
04460       {
04461         return nil;
04462       }
04463     if (st_lookup (newprocessedTable, (char *) formula, (char **) &result))
04464       {
04465         return result;
04466       }
04467 
04468     // if it is a string, let us get unfolded string name 
04469     if (!st_lookup (net->nodeToId, (char *) formula, (char **) 0))
04470       {
04471         // must be a string if it's not nil and not a formula
04472         // use rs to preserve canonicity
04473         char *newName = (char *) rs (util_strcat ((char *) formula, suf));
04474         return (Fnode *) newName;
04475       }
04476     // if the formula is a register
04477     if ((formula->type == ScalarReg_c) || (formula->type == BooleanReg_c))
04478       {
04479         /* if depth is 0, we will get unfolded node for initial value node
04480          * else, we will get unfolded node for next state node */
04481         if (depth == 0)
04482           {
04483             result =
04484               getUnfoldedNode2 (net, Reg_InitFunc (formula), depth,
04485                                 newprocessedTableArray);
04486           }
04487         else
04488           {
04489             result =
04490               getUnfoldedNode2 (net, Reg_NsFunc (formula), (depth - 1),
04491                                 newprocessedTableArray);
04492           }
04493       }
04494     else
04495       {
04496         // result corresponds to unfolded node at depth "depth" 
04497         // We would have to connect its inputs carefully though
04498         Fnode *lchild = nil, *rchild = nil;
04499         if ((formula->type == UnaryFunc_c) ||
04500             (formula->type == Func_c) || (formula->type == ScalarConst_c))
04501           {
04502             /* Need not modify their names */
04503             lchild = formula->lchild;
04504           }
04505         else
04506           {
04507             lchild =
04508               getUnfoldedNode2 (net, (Fnode *) formula->lchild, depth,
04509                                 newprocessedTableArray);
04510           }
04511         rchild =
04512           getUnfoldedNode2 (net, (Fnode *) formula->rchild, depth,
04513                             newprocessedTableArray);
04514         result = new_node (formula->type, lchild, rchild);
04515       }
04516     st_insert (newprocessedTable, (char *) formula, (char *) result);
04517     return result;
04518   }
04519 
04520   st_table *Net_ReadNodeVals (char *fileName)
04521   {
04522     FILE *simFile = fopen (fileName, "r");
04523     char nodeName[512], nodeVal[512];
04524     assert (simFile != NIL (FILE));
04525     st_table *result =
04526       st_init_table ((int (*)()) strcmp, (int (*)()) st_strhash);
04527 
04528     char tmpbuf[200];           // max line length
04529     while (NIL (char) != fgets (tmpbuf, 200, simFile))
04530       {
04531         sscanf (tmpbuf, "%s %s", nodeName, nodeVal);
04532         unsigned i;
04533         for (i = 0; i < strlen (nodeName); i++)
04534           {
04535             if (isupper (nodeName[i]))
04536               {
04537                 nodeName[i] = tolower (nodeName[i]);
04538               }
04539           }
04540         st_insert (result, strdup (nodeName), strdup (nodeVal));
04541       }
04542     fclose (simFile);
04543     return result;
04544   }
04545 
04546 // Function to check whether Burch's ODC simplification can be useful.
04547 
04548   int Net_CheckBurchFeasibility (Fnode * aFormula, Fnode * ctrl_child)
04549   {
04550     int feasibility = 0, lchild_feasibility = 0, rchild_feasibility = 0;
04551     if (aFormula == nil)
04552       {
04553         return 0;
04554       }
04555     // switch on type 
04556     switch (aFormula->type)
04557       {
04558       case Undef_c:
04559         // should not be reached
04560         assert (0);
04561         feasibility = 0;
04562         break;
04563       case ScalarPI_c:
04564       case BooleanPI_c:
04565       case InternalScalarVar_c:
04566       case InternalBooleanVar_c:
04567       case ScalarConst_c:
04568       case TRUE_c:
04569       case FALSE_c:
04570         // no feasibility
04571         feasibility = 0;
04572         break;
04573       case ScalarReg_c:
04574       case BooleanReg_c:
04575         // we need to call feasibility check on next state functions
04576         lchild_feasibility =
04577           Net_CheckBurchFeasibility ((Fnode *) Reg_InitFunc (aFormula),
04578                                      ctrl_child);
04579         rchild_feasibility =
04580           Net_CheckBurchFeasibility ((Fnode *) Reg_NsFunc (aFormula),
04581                                      ctrl_child);
04582         feasibility =
04583           (lchild_feasibility >
04584            rchild_feasibility) ? lchild_feasibility : rchild_feasibility;
04585         break;
04586       case Not_c:
04587         feasibility =
04588           Net_CheckBurchFeasibility (aFormula->lchild, ctrl_child);
04589         break;
04590       case UnaryFunc_c:
04591       case Func_c:
04592         feasibility =
04593           Net_CheckBurchFeasibility (aFormula->rchild, ctrl_child);
04594         break;
04595       case List_c:
04596       case Pair_c:
04597       case Iff_c:
04598       case Equal_c:
04599       case And_c:
04600       case Or_c:
04601         lchild_feasibility =
04602           Net_CheckBurchFeasibility (aFormula->lchild, ctrl_child);
04603         rchild_feasibility =
04604           Net_CheckBurchFeasibility (aFormula->rchild, ctrl_child);
04605         feasibility =
04606           (lchild_feasibility >
04607            rchild_feasibility) ? lchild_feasibility : rchild_feasibility;
04608         break;
04609       case Mux_c:
04610         if (aFormula->lchild == ctrl_child)
04611           {
04612             feasibility = 1;
04613           }
04614         else
04615           {
04616             lchild_feasibility =
04617               Net_CheckBurchFeasibility ((Fnode *) Mux_ThenInput (aFormula),
04618                                          ctrl_child);
04619             rchild_feasibility =
04620               Net_CheckBurchFeasibility ((Fnode *) Mux_ElseInput (aFormula),
04621                                          ctrl_child);
04622             feasibility =
04623               (lchild_feasibility >
04624                rchild_feasibility) ? lchild_feasibility : rchild_feasibility;
04625           }
04626         break;
04627       default:
04628         printf ("The type is %d\n", aFormula->type);
04629         assert (0);
04630       }
04631     return feasibility;
04632   }
04633 
04634   void Net_CollectMuxes (Fnode * aFormula, st_table * mux_hash)
04635   {
04636 
04637     assert (mux_hash != NIL (st_table));
04638     if (aFormula == nil)
04639       {
04640         return;
04641       }
04642     // switch on type 
04643     switch (aFormula->type)
04644       {
04645       case Undef_c:
04646         // should not be reached
04647         assert (0);
04648         break;
04649       case ScalarPI_c:
04650       case BooleanPI_c:
04651       case InternalScalarVar_c:
04652       case InternalBooleanVar_c:
04653       case ScalarConst_c:
04654       case TRUE_c:
04655       case FALSE_c:
04656         break;
04657       case ScalarReg_c:
04658       case BooleanReg_c:
04659         Net_CollectMuxes ((Fnode *) Reg_InitFunc (aFormula), mux_hash);
04660         Net_CollectMuxes ((Fnode *) Reg_NsFunc (aFormula), mux_hash);
04661         break;
04662       case Not_c:
04663         Net_CollectMuxes ((Fnode *) aFormula->lchild, mux_hash);
04664         break;
04665       case UnaryFunc_c:
04666       case Func_c:
04667         Net_CollectMuxes ((Fnode *) aFormula->rchild, mux_hash);
04668         break;
04669       case List_c:
04670       case Pair_c:
04671       case Iff_c:
04672       case Equal_c:
04673       case And_c:
04674       case Or_c:
04675         Net_CollectMuxes (aFormula->lchild, mux_hash);
04676         Net_CollectMuxes (aFormula->rchild, mux_hash);
04677         break;
04678       case Mux_c:
04679         if (!st_lookup (mux_hash, (char *) aFormula, (char **) 0))
04680           {
04681             st_insert (mux_hash, (char *) aFormula, (char *) 0);
04682           }
04683         break;
04684       default:
04685         printf ("The type is %d\n", aFormula->type);
04686         assert (0);
04687       }
04688     return;
04689   }
04690 
04695   Fnode *Net_SimplifyUsingConstantPropagation (Fnode * aFormula)
04696   {
04697 
04698     int depth;
04699     Fnode *simplified_aFormula;
04700 
04701     st_table *processedNodes =
04702       st_init_table ((int (*)()) st_ptrcmp, (int (*)()) st_ptrhash);
04703     st_table *sortedTable =
04704       st_init_table ((int (*)()) st_numcmp, (int (*)()) st_numhash);
04705     st_table *equivalentNodeHash =
04706       st_init_table ((int (*)()) st_ptrcmp, (int (*)()) st_ptrhash);
04707 
04708     depth = Net_TopologicalSort (aFormula, sortedTable, processedNodes);
04709     Net_ConstantPropagation (sortedTable, equivalentNodeHash, depth);
04710     st_lookup (equivalentNodeHash, (char *) aFormula,
04711                (char **) &simplified_aFormula);
04712 
04713     st_free_table (sortedTable);
04714     st_free_table (equivalentNodeHash);
04715     st_free_table (processedNodes);
04716     return simplified_aFormula;
04717 
04718   }
04719 
04720 
04727 static int
04728 Net_PrintFormulaInt (Net_t * net,
04729                        Fnode * formula,
04730                        st_table * processedNodes, FILE * fptr)
04731   {
04732     int id;
04733     if (formula == nil)
04734       {
04735         return 0;
04736       }
04737     if (!st_lookup (net->nodeToId, (char *) formula, (char **) &id))
04738       {
04739         // assuming that it's a string so returning
04740         return 0;
04741       }
04742     if (st_lookup (processedNodes, (char *) formula, (char **) 0))
04743       {
04744         return 0;
04745       }
04746     st_insert (processedNodes, (char *) formula, (char *) 0);
04747 
04748     extern char *typeString[];
04749 
04750     int lid = -1;
04751     int rid = -1;
04752     if (Node_HasLeftChildNode (formula))
04753       {
04754         lid = Net_NodeGetId (net, (Fnode *) formula->lchild);
04755       }
04756     if (Node_HasRightChildNode (formula))
04757       {
04758         rid = Net_NodeGetId (net, (Fnode *) formula->rchild);
04759       }
04760 
04761 
04762     Operator_t type = formula->type;
04763     switch (type)
04764       {
04765       case Pair_c:
04766         fprintf (fptr, "Node %d is %s, elt0 is node %d, elt1 is node %d\n",
04767                  id, typeString[type], lid, rid);
04768         fprintf (fptr, "%d [label=\"%s\"];\n", id, typeString[type]);
04769         lid != -1 ? fprintf (fptr, "%d -> %d [label =\" P0 \"];\n", lid,
04770                              id) : 0;
04771         rid != -1 ? fprintf (fptr, "%d -> %d [label =\" P1 \"];\n", rid,
04772                              id) : 0;
04773         break;
04774       case List_c:
04775         fprintf (fptr, "Node %d is %s, elt0 is node %d, elt1 is node %d\n",
04776                  id, typeString[type], lid, rid);
04777         fprintf (fptr, "%d [color=grey,label=\"%s\"];\n", id,
04778                  typeString[type]);
04779         lid != -1 ? fprintf (fptr, "%d -> %d [label =\" left \"];\n", lid,
04780                              id) : 0;
04781         rid != -1 ? fprintf (fptr, "%d -> %d [label =\" right \"];\n", rid,
04782                              id) : 0;
04783         break;
04784       case Undef_c:
04785         fprintf (fptr, "Node %d is Undef_c\n", id);
04786         break;
04787       case ScalarPI_c:
04788       case BooleanPI_c:
04789       case InternalScalarVar_c:
04790       case InternalBooleanVar_c:
04791       case ScalarConst_c:
04792         char *val;
04793         val = "";
04794         fprintf (fptr, "%d [shape=polygon,sides=6,label=\"%s %s %s\"];\n",
04795                  id, typeString[type], (char *) formula->lchild, val);
04796         fprintf (fptr, "Node %d is %s with id %s value %s\n",
04797                  id, typeString[type], (char *) formula->lchild, val);
04798         break;
04799       case And_c:
04800       case Or_c:
04801       case Iff_c:
04802       case Equal_c:
04803         fprintf (fptr, "%d [shape=invtriangle,label=\"%s\"];\n", id,
04804                  typeString[type]);
04805         lid != -1 ? fprintf (fptr, "%d -> %d;\n", lid, id) : 0;
04806         rid != -1 ? fprintf (fptr, "%d -> %d;\n", rid, id) : 0;
04807         fprintf (fptr, "Node %d is %s with args node %d and node %d\n",
04808                  id, typeString[type], lid, rid);
04809         break;
04810       case ScalarReg_c:
04811       case BooleanReg_c:
04812         fprintf (fptr,
04813                  "Node %d is a %s register with name %s, init value %d and ns %d\n",
04814                  id, typeString[type], (char *) formula->lchild,
04815                  Net_NodeGetId (net, Reg_InitFunc (formula)),
04816                  Net_NodeGetId (net, Reg_NsFunc (formula)));
04817         fprintf (fptr, "%d [shape=polygon,sides=4,label=\"%s %s\"];\n", id,
04818                  typeString[type], (char *) formula->lchild);
04819         lid != -1 ? fprintf (fptr, "%d -> %d;\n", lid, id) : 0;
04820         rid != -1 ? fprintf (fptr, "%d -> %d;\n", rid, id) : 0;
04821         break;
04822       case Not_c:
04823         fprintf (fptr, "Node %d is negation of %d\n", id, lid);
04824         fprintf (fptr, "%d [label=\"%s\"];\n", id, typeString[type]);
04825         lid != -1 ? fprintf (fptr, "%d -> %d;\n", lid, id) : 0;
04826         break;
04827       case Mux_c:
04828         {
04829           int thenId = Net_NodeGetId (net, (Fnode *) Mux_ThenInput (formula));
04830           int elseId = Net_NodeGetId (net, (Fnode *) Mux_ElseInput (formula));
04831           fprintf (fptr,
04832                    "Node %d is a mux with control %d, IF input %d and ELSE input %d\n",
04833                    id, lid, thenId, elseId);
04834           fprintf (fptr,
04835                    "%d [shape=polygon,sides=4,distortion=0.7,label=\"%s\"];\n",
04836                    id, typeString[type]);
04837           fprintf (fptr, "%d -> %d [style=dotted,label=\"Ctrl\"];\n", lid,
04838                    id);
04839           fprintf (fptr, "%d -> %d [label=\"THEN/ELSE\"];\n", rid, id);
04840           break;
04841         }
04842       case Assign_c:
04843         fprintf (fptr, "Node %d is assignment %s := node %d\n",
04844                  id, (char *) formula->lchild, rid);
04845         fprintf (fptr, "%d [label=\"%s %s\"];\n", id, typeString[type],
04846                  (char *) formula->lchild);
04847         fprintf (fptr, "%d -> %d;\n", rid, id);
04848         break;
04849       case UnaryFunc_c:
04850         fprintf (fptr, "Node %d is unary UIF %s of node %d\n",
04851                  id, (char *) formula->lchild, rid);
04852         fprintf (fptr, "%d [color=red,label=\"%s %s\"];\n", id,
04853                  typeString[type], (char *) formula->lchild);
04854         fprintf (fptr, "%d -> %d;\n", rid, id);
04855         break;
04856       case TRUE_c:
04857       case FALSE_c:
04858         fprintf (fptr, "Node %d is Boolean %s\n", id,
04859                  (type == TRUE_c) ? "TRUE" : "FALSE");
04860         fprintf (fptr, "%d [label=\"%s\"];\n", id, typeString[type]);
04861         break;
04862       case Func_c:
04863       case Relation_c:
04864         fprintf (fptr,
04865                  "Node %d is %s with name %s of with argument list node %d\n",
04866                  id, typeString[type], (char *) formula->lchild, rid);
04867         fprintf (fptr, "%d [color=red,label=\"%s %s\"];\n", id,
04868                  typeString[type], (char *) formula->lchild);
04869         fprintf (fptr, "%d -> %d;\n", rid, id);
04870         break;
04871       default:
04872         fprintf (fptr, "Panic, encountered unknown type of node in print\n");
04873         assert (0);
04874       }
04875 
04876     if (Node_HasLeftChildNode (formula))
04877       {
04878         Net_PrintFormulaInt (net, 
04879                              (Fnode *) formula->lchild, 
04880                              processedNodes,
04881                              fptr);
04882       }
04883 
04884     if (Node_HasRightChildNode (formula))
04885       {
04886         Net_PrintFormulaInt (net, 
04887                              (Fnode *) formula->rchild, 
04888                              processedNodes,
04889                              fptr);
04890       }
04891 
04892     return 0;
04893   }
04894 
04903 static int Net_PrintVHDLInt (Net_t * net, FILE * fptr, int vector_width, char *entity_name)
04904 {
04905   int i, net_formula_type, memory_component_declared = 0;
04906   Fnode *instance = nil;
04907   char *name = NULL;
04908   st_table *nodeToTypeHash = NIL (st_table);
04909   st_table *nodeToNameHash = NIL (st_table);
04910   st_table *processedNodes = NIL (st_table);
04911   st_table *uifToNumInputs = NIL (st_table);
04912   st_table *uifComponentHash = NIL (st_table);
04913   st_table *uifInstantiateHash = NIL (st_table);
04914   
04915   extern int node_cmp ();
04916   extern int node_hash ();
04917   if (net == NIL (Net_t))
04918     {
04919       return 0;
04920     }
04921   assert (fptr);
04922   // init the nodeToTypeHash
04923   nodeToTypeHash =
04924     st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
04925   // init the nodeToNameHash
04926   nodeToNameHash =
04927     st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
04928   // init the processedNodes
04929   //processedNodes = st_init_table( (int (*)()) st_ptrcmp,  (int (*)()) st_ptrhash);
04930   processedNodes =
04931       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
04932     // init uifToNumInputs
04933     uifToNumInputs =
04934       st_init_table ((int (*)()) node_cmp, (int (*)()) node_hash);
04935     // init uifComponentHash
04936     uifComponentHash =
04937       st_init_table ((int (*)()) st_numcmp, (int (*)()) st_numhash);
04938     // init uifInstantiateHash
04939     uifInstantiateHash =
04940       st_init_table ((int (*)()) strcmp, (int (*)()) st_strhash);
04941     // call setNodeType
04942     for (i = 0; i < array_n (net->formulas); i++)
04943       {
04944         Fnode *net_formula = array_fetch (Fnode *, net->formulas, i);
04945         net_formula_type = setNodeType (net, net_formula, nodeToTypeHash);
04946       }
04947     // Now start dumping VHDL
04948     // Library usage info
04949     fprintf (fptr, "LIBRARY ieee,ibm;\n");
04950     fprintf (fptr, "use ieee.std_logic_1164.all;\n");
04951 
04952     // comment out the ibm stuff, maybe reqd later for sixthsense
04953     // fprintf(fptr, "use ibm.numeric_std.all;\n");
04954     // fprintf(fptr, "use ibm.synthesis_support.all;\n");
04955     // fprintf(fptr, "use ibm.std_ulogic_support.all;\n");
04956     // fprintf(fptr, "use ibm.std_function_support.all;\n");
04957 
04958     // Entity declaration
04959     fprintf (fptr, "entity %s is port (\n", entity_name);
04960     // input declarations
04961     for (i = 0; i < array_n (net->PIs); i++)
04962       {
04963         instance = array_fetch (Fnode *, net->PIs, i);
04964         assert ((instance->type == ScalarPI_c)
04965                 || (instance->type == BooleanPI_c));
04966         if(strstr((char *) instance->lchild, "mem@") != NULL) {
04967           char saved_lchild[BUFFER_SIZE];
04968           char *lchild_suffix;
04969           strcpy(saved_lchild, (char *) instance->lchild);
04970           name = (char *) malloc(BUFFER_SIZE);
04971           strtok(saved_lchild, "@");
04972           lchild_suffix = strtok(NULL, "@");
04973           sprintf(name, "mem_%s", lchild_suffix);
04974           //printf("original name is %s, the modified name is %s\n", (char *) instance->lchild, name);
04975         }
04976         else {
04977           name = (char *) malloc(BUFFER_SIZE);
04978           sprintf(name, "%s", (char *) instance->lchild);
04979         }
04980           
04981         if (instance->type == ScalarPI_c)
04982           {
04983             // this is a scalar input, so will be a std_ulogic_vector input
04984             fprintf (fptr, "%s : in std_ulogic_vector(0 to %d);\n",
04985                      name, (vector_width - 1));
04986           }
04987         else
04988           {
04989             // this is a boolean input, so will be a std_ulogic input
04990             fprintf (fptr, "%s : in std_ulogic;\n",
04991                      name);
04992           }
04993         st_insert (nodeToNameHash, (char *) instance,
04994                    (char *) string_register((char *) name));
04995       }
04996     //scalar constants declared as inputs
04997     for (i = 0; i < array_n (net->constants); i++)
04998       {
04999         instance = array_fetch (Fnode *, net->constants, i);
05000         assert (instance->type == ScalarConst_c);
05001         //setting all scalar constants to 0
05002         fprintf (fptr, "%s : in std_ulogic_vector(0 to %d);\n",
05003                  (char *) instance->lchild, (vector_width - 1));
05004         st_insert (nodeToNameHash, (char *) instance,
05005                    (char *) instance->lchild);
05006       }
05007 
05008     // dummy output declaration for now
05009     for (i = 0; i < array_n (net->formulas); i++)
05010       {
05011         if (i == (array_n (net->formulas) - 1))
05012           {
05013             fprintf (fptr, "dummy_out%d : out std_ulogic\n", i);
05014           }
05015         else
05016           {
05017             fprintf (fptr, "dummy_out%d: out std_ulogic;\n", i);
05018           }
05019       }
05020     // end the entity
05021     fprintf (fptr, ");\n");
05022     fprintf (fptr, "end %s;\n", entity_name);
05023 
05024     //architecture declaration
05025     fprintf (fptr, "architecture %s of %s is\n", entity_name, entity_name);
05026     //signal declarations
05027     int num_uifs = 0;
05028     for (i = 0; i < array_n (net->allNodes); i++)
05029       {
05030         int instance_type = 0;
05031         instance = array_fetch (Fnode *, net->allNodes, i);
05032         switch (instance->type)
05033           {
05034           case List_c:
05035           case Pair_c:
05036             // no signal declaration
05037             break;
05038           case Undef_c:
05039             // no signal declaration
05040             break;
05041           case ScalarPI_c:
05042             // already declared as an input
05043             break;
05044           case BooleanPI_c:
05045             //already declared as an input
05046             break;
05047           case InternalScalarVar_c:
05048             // need to be declared as a signal
05049             st_insert (nodeToNameHash, (char *) instance,
05050                        (char *) instance->lchild);
05051             fprintf (fptr, "signal %s : std_ulogic_vector(0 to %d);\n",
05052                      (char *) instance->lchild, (vector_width - 1));
05053             break;
05054           case InternalBooleanVar_c:
05055             st_insert (nodeToNameHash, (char *) instance,
05056                        (char *) instance->lchild);
05057             // need to be declared as a signal
05058             fprintf (fptr, "signal %s : std_ulogic;\n",
05059                      (char *) instance->lchild);
05060             break;
05061           case ScalarConst_c:
05062             // already declared as a constant
05063             break;
05064           case And_c:
05065           case Or_c:
05066           case Iff_c:
05067           case Equal_c:
05068           case Not_c:
05069           case Mux_c:
05070             assert (st_lookup
05071                     (nodeToTypeHash, (char *) instance,
05072                      (char **) &instance_type));
05073             // we will declare a signal Net_%d, where %d is the nodeId      
05074             name = (char *) malloc (BUFFER_SIZE);
05075             sprintf (name, "Net_%d", Net_NodeGetId (net, instance));
05076             if (instance_type == 1)
05077               {
05078                 // boolean signal
05079                 fprintf (fptr, "signal %s : std_ulogic;\n", name);
05080               }
05081             else if (instance_type == 2)
05082               {
05083                 // scalar signal
05084                 fprintf (fptr, "signal %s : std_ulogic_vector(0 to %d);\n",
05085                          name, (vector_width - 1));
05086               }
05087             st_insert (nodeToNameHash, (char *) instance,
05088                        (char *) string_register ((char *) name));
05089             break;
05090           case ScalarReg_c:
05091             // the scalar reg could be a memory, in which case we would want to instantiate
05092             // the memory
05093             if (strstr ((char *) instance->lchild, "mem@") != NULL)
05094               {
05095                 if (!memory_component_declared)
05096                   {
05097                     Net_AnalyzeMemory (net, fptr, instance);
05098                     memory_component_declared = 1;
05099                   }
05100               }
05101             else
05102               {
05103                 // need to be declared as a signal
05104                 // hack for initial values, scalar reg is a wrapper around the actual latch
05105                 // actual latch named Net_%d, wrapper uses the name in lchild
05106                 fprintf (fptr,
05107                          "signal Net_%d : std_ulogic_vector(0 to %d);\n",
05108                          Net_NodeGetId (net, instance), (vector_width - 1));
05109                 fprintf (fptr, "signal %s : std_ulogic_vector(0 to %d);\n",
05110                          (char *) instance->lchild, (vector_width - 1));
05111                 st_insert (nodeToNameHash, (char *) instance,
05112                            (char *) instance->lchild);
05113               }
05114             break;
05115           case BooleanReg_c:
05116             // need to be declared as a signal
05117             // hack for initial values, scalar reg is a wrapper around the actual latch
05118             // actual latch named Net_%d, wrapper uses the name in lchild
05119             fprintf (fptr, "signal Net_%d : std_ulogic;\n",
05120                      Net_NodeGetId (net, instance));
05121             fprintf (fptr, "signal %s : std_ulogic;\n",
05122                      (char *) instance->lchild);
05123             st_insert (nodeToNameHash, (char *) instance,
05124                        (char *) instance->lchild);
05125             break;
05126           case Assign_c:
05127             // need to be declared as a signal      
05128             assert (st_lookup
05129                     (nodeToTypeHash, (char *) instance,
05130                      (char **) &instance_type));
05131             if (instance_type == 1)
05132               {
05133                 // boolean
05134                 fprintf (fptr, "signal %s : std_ulogic;\n",
05135                          (char *) instance->lchild);
05136               }
05137             else if (instance_type == 2)
05138               {
05139                 // scalar
05140                 fprintf (fptr, "signal %s : std_ulogic_vector(0 to %d);\n",
05141                          (char *) instance->lchild, (vector_width - 1));
05142               }
05143             st_insert (nodeToNameHash, (char *) instance,
05144                        (char *) instance->lchild);
05145             break;
05146           case UnaryFunc_c:
05147             // scalar signal
05148             if (strstr ((char *) instance->lchild, "mem#") == NULL)
05149               {
05150                 name = (char *) malloc (BUFFER_SIZE);
05151                 if (strstr ((char *) instance->lchild, "mem@") != NULL)
05152                   {
05153                     sprintf (name, "mem_read_UIF_%d", num_uifs++);
05154                   }
05155                 else
05156                   {
05157                     sprintf (name, "%s_UIF_%d", (char *) instance->lchild,
05158                              num_uifs++);
05159                   }
05160                 st_insert (nodeToNameHash, (char *) instance,
05161                            (char *) string_register ((char *) name));
05162                 fprintf (fptr, "signal %s : std_ulogic_vector(0 to %d);\n",
05163                          name, (vector_width - 1));
05164               }
05165             if ((strstr ((char *) instance->lchild, "mem@") == NULL) &&
05166                 (strstr ((char *) instance->lchild, "mem#") == NULL))
05167               {
05168                 Net_AnalyzeUIF (net, fptr, instance, uifToNumInputs,
05169                                 uifComponentHash);
05170               }
05171             //assert(0);
05172             break;
05173           case TRUE_c:
05174             // need to be declared as a constant
05175             fprintf (fptr, "constant true : std_ulogic := '1';\n");
05176             name = (char *) malloc (BUFFER_SIZE);
05177             sprintf (name, "true");
05178             st_insert (nodeToNameHash, (char *) instance,
05179                        (char *) string_register (name));
05180             break;
05181           case FALSE_c:
05182             fprintf (fptr, "constant false : std_ulogic := '0';\n");
05183             name = (char *) malloc (BUFFER_SIZE);
05184             sprintf (name, "false");
05185             st_insert (nodeToNameHash, (char *) instance,
05186                        (char *) string_register (name));
05187             break;
05188           case Func_c:
05189             //assert(0);
05190             if (strstr ((char *) instance->lchild, "mem#") == NULL)
05191               {
05192                 name = (char *) malloc (BUFFER_SIZE);
05193                 if (strstr ((char *) instance->lchild, "mem@") != NULL)
05194                   {
05195                     sprintf (name, "mem_read_UIF_%d", num_uifs++);
05196                   }
05197                 else
05198                   {
05199                     sprintf (name, "%s_UIF_%d", (char *) instance->lchild,
05200                              num_uifs++);
05201                   }
05202                 st_insert (nodeToNameHash, (char *) instance,
05203                            (char *) string_register ((char *) name));
05204                 // scalar signal
05205                 fprintf (fptr, "signal %s : std_ulogic_vector(0 to %d);\n",
05206                          name, (vector_width - 1));
05207               }
05208             if ((strstr ((char *) instance->lchild, "mem@") == NULL) &&
05209                 (strstr ((char *) instance->lchild, "mem#") == NULL))
05210               {
05211                 Net_AnalyzeUIF (net, fptr, instance, uifToNumInputs,
05212                                 uifComponentHash);
05213               }
05214             break;
05215           default:
05216             printf ("Panic, encountered unknown type of node in print\n");
05217             assert (0);
05218           }
05219       }
05220     // create the dummy initial value signal
05221     fprintf (fptr, "signal dummy_init_val : std_ulogic;\n");
05222     // create the dummy_clock signal
05223     fprintf (fptr, "signal dummy_clock : std_ulogic;\n");
05224     fprintf (fptr, "BEGIN\n");
05225     // the body of VHDL goes here
05226     // assign dummy_clock to 1 and setup the dummy_init_val
05227     fprintf (fptr, "dummy_clock <= '1';\n");
05228     fprintf (fptr,
05229              "process(dummy_clock) begin\nif(dummy_clock = '1') then\ndummy_init_val <= '1';\nend if;\nend process;\n");
05230     // now call Node_PrintVHDL
05231     for (i = 0; i < array_n (net->formulas); i++)
05232       {
05233         Fnode *net_formula = array_fetch (Fnode *, net->formulas, i);
05234         Node_PrintVHDL (net, net_formula, fptr, nodeToNameHash,
05235                         processedNodes, uifInstantiateHash, uifToNumInputs,
05236                         vector_width);
05237       }
05238     // just assign dummy_out to 0 
05239     char *formula_name;
05240     for (i = 0; i < array_n (net->formulas); i++)
05241       {
05242         Fnode *net_formula = array_fetch (Fnode *, net->formulas, i);
05243         
05244         if(st_lookup (nodeToNameHash, (char *) net_formula,
05245                       (char **) &formula_name)) {
05246           fprintf (fptr, "dummy_out%d <= %s;\n", i, formula_name);
05247         }
05248         else {
05249           fprintf( fptr, "dummy_out%d <= '0';\n", i);
05250         }
05251       }
05252     fprintf (fptr, "END %s;\n", entity_name);
05253     return 0;
05254   }
05255 
05256 
05257 }

Generated on Thu Oct 11 11:47:28 2007 for Tarski by  doxygen 1.3.9.1