Subversion Repositories Vertical

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* $Id: print_vhdl.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $ */
  2. /*
  3.  * $Log: print_vhdl.c,v $
  4.  * Revision 1.1.1.1  2003/11/04 23:34:57  mjames
  5.  * Imported into local repositrory
  6.  *
  7.  * Revision 1.17  2003/01/02 21:37:16  mjames
  8.  * Experiment on creating NOT_ROUTABLE_H and NOT_ROUTABLE_L
  9.  * properties on the nets so that pin jumpers can be made without a problem.
  10.  *
  11.  * Still need to sort out pin assignments made to these not_routable nets
  12.  * which will become legal in some cases so that pullups and pulldown
  13.  * pins can be used on the FPGA.
  14.  *
  15.  * Revision 1.16  2002/09/30 13:23:05  MJAMES
  16.  * Modified partition rules to include 'default assignment on declaration'
  17.  * which maps to inputs being driven with default values on
  18.  * productuion of a partition.
  19.  *
  20.  * signal c : std_logic := '0';
  21.  *
  22.  * becomes
  23.  *
  24.  * signal c: std_logic;
  25.  *
  26.  * begin
  27.  *   c<= '0';
  28.  *
  29.  * Revision 1.15  2002/09/27 22:35:33  MJAMES
  30.  * Added lhs_expr for cases like
  31.  *
  32.  * x(0) <= y
  33.  *
  34.  * where x is std_logic_vector(0 downto 0) and y is std_logic.
  35.  *
  36.  * Also added printing for default values on signals : this to be extended
  37.  *
  38.  * Revision 1.14  2002/09/09 10:12:02  mjames
  39.  * Moved pin remapping function to pin ident editing function from
  40.  * sorting pin name routine.
  41.  *
  42.  * Revision 1.13  2002/08/23 14:19:19  mjames
  43.  * Introduced bundles and external sockets to VHDL from the Verilog printer.
  44.  *
  45.  * Revision 1.12  2001/12/13 22:18:52  mjames
  46.  * Using #ident with header to identify file
  47.  *
  48.  * Corrected an attempt to reference a null net
  49.  *
  50.  * Revision 1.11  2001/11/19 10:41:35  mjames
  51.  * Merged back DTC release
  52.  *
  53.  * Revision 1.10.2.1  2001/11/15 22:25:39  mjames
  54.  * Removed unused variables, added brackets
  55.  *
  56.  * Revision 1.10  2001/11/01 11:04:36  mjames
  57.  * Pin node identifier is printed out in a component declaration rather than
  58.  * node name which is more a property of the attached net.
  59.  *
  60.  * Revision 1.9  2001/10/31 22:20:12  mjames
  61.  * Tidying up problematical comments caused by CVS
  62.  * 'intelligent' comment guessing
  63.  *
  64.  * Revision 1.8  2001/10/10 20:18:22  mjames
  65.  * Added a vert_regcomp function to compile regular expressions
  66.  * with '^' (match start string) and  '$' (match end string) bracketing
  67.  * this => wildcard must match entire string not just a part of it.
  68.  *
  69.  * Revision 1.7  2001/09/21 14:22:27  mjames
  70.  * Added prefix to instance name in order to avoid a Model Technology name
  71.  * space collision  e.g.
  72.  *
  73.  * U1 : U1 port map () ...
  74.  *
  75.  * Now prints
  76.  *
  77.  * I_U1 : U1 port map which is safer.
  78.  *
  79.  * Revision 1.6  2001/06/22 11:06:19  mjames
  80.  * Modified to tag VHDL code generated so that
  81.  * Vertical can recognise it.
  82.  *
  83.  * Revision 1.5  2001/06/20 13:45:40  mjames
  84.  * For all components defined by 'Component' declarations, forced the
  85.  * printout of only one component for several instances sharing the same component declaration.
  86.  *
  87.  * Revision 1.4  2001/06/06 12:10:19  mjames
  88.  * Move from HPUX
  89.  *
  90.  * Revision 1.3  2001/04/27 08:08:44  mjames
  91.  * Extra tidying of the print_vhdl code
  92.  *
  93.  * Revision 1.2  2000/11/29 21:51:18  mjames
  94.  * Fine tuning of software
  95.  *
  96.  * Revision 1.1.1.1  2000/10/19 21:58:39  mjames
  97.  * Mike put it here
  98.  *
  99.  *
  100.  * Revision 1.23  2000/10/12  15:32:32  15:32:32  mjames (Mike James)
  101.  * Removed <cr>
  102.  *
  103.  * Revision 1.22  2000/10/12  14:25:55  14:25:55  mjames (Mike James)
  104.  * changed listing vhdl signals to expand expressions
  105.  * until a constant is located
  106.  *
  107.  * Revision 1.21  2000/10/04  10:37:08  10:37:08  mjames (Mike James)
  108.  * Modified for Vertical2 : support COMPONENTS and SIGNALS
  109.  *
  110.  * Revision 1.21  2000/10/04  10:37:08  10:37:08  mjames (Mike James)
  111.  * Part of Release PSAVAT01
  112.  *
  113.  * Revision 1.20  2000/10/02  11:04:17  11:04:17  mjames (Mike James)
  114.  * new_vhdl
  115.  *
  116.  * Revision 1.18  2000/09/21  10:15:48  10:15:48  mjames (Mike James)
  117.  * Part of Release Sep21Alpha
  118.  *
  119.  * Revision 1.17  2000/08/25  09:57:14  09:57:14  mjames (Mike James)
  120.  * Part of Release Aug25_alpha
  121.  *
  122.  * Revision 1.16  2000/08/25  09:55:33  09:55:33  mjames (Mike James)
  123.  * Corrected for the disappearance of generic information
  124.  *
  125.  * Revision 1.15  2000/08/16  08:57:30  08:57:30  mjames (Mike James)
  126.  * Part of Release CD01_Aug2000
  127.  *
  128.  * Revision 1.14  2000/08/14  14:45:11  14:45:11  mjames (Mike James)
  129.  * Part of Release Aug_14_2000
  130.  *
  131.  * Revision 1.13  2000/08/14  14:43:15  14:43:15  mjames (Mike James)
  132.  * Added power pins
  133.  *
  134.  * Revision 1.12  2000/08/11  08:30:32  08:30:32  mjames (Mike James)
  135.  * Part of Release Aug_11_2000
  136.  *
  137.  * Revision 1.11  2000/08/09  10:31:47  10:31:47  mjames (Mike James)
  138.  * Part of Release Aug__9_2000
  139.  *
  140.  * Revision 1.10  2000/05/31  11:42:56  11:42:56  mjames (Mike James)
  141.  * Part of Release May_31_2000
  142.  *
  143.  * Revision 1.9  2000/05/08  17:01:37  17:01:37  mjames (Mike James)
  144.  * Part of Release May__8_2000
  145.  *
  146.  * Revision 1.8  2000/05/08  16:59:30  16:59:30  mjames (Mike James)
  147.  * Part of Release May__8_2000
  148.  *
  149.  * Revision 1.7  2000/05/08  16:57:07  16:57:07  mjames (Mike James)
  150.  * Part of Release May__8_2000
  151.  *
  152.  * Revision 1.6  2000/03/08  16:19:22  16:19:22  mjames (Mike James)
  153.  * New version including PC
  154.  *
  155.  * Revision 1.3  2000/01/20  15:58:47  15:58:47  mjames (Mike James)
  156.  * Part of Release R22
  157.  *
  158.  * Revision 1.2  99/12/22  11:15:28  11:15:28  mjames (Mike James)
  159.  * Part of Release Dec_22_1999
  160.  *
  161.  * Revision 1.1  99/11/23  13:52:14  13:52:14  mjames (Mike James)
  162.  * Initial revision
  163.  *
  164.  */
  165.  
  166. #include "print_vhdl.h"
  167.  
  168. #include "cmdlog.h"
  169. #include "cmdparse.h"
  170. #include "database.h"
  171. #include "expression.h"
  172. #include "generic.h"
  173. #include "print_vlog.h"
  174. #include "printout.h"
  175. #include "sorting.h"
  176. #include "vertcl_main.h"
  177.  
  178. #include <ctype.h>
  179. #include <regex.h>
  180. #include <stdio.h>
  181. #include <stdlib.h>
  182. #include <string.h>
  183. #include <time.h>
  184. /* for streq */
  185. #include "lx_support.h"
  186. /* ********************************************************************** */
  187.  
  188. /* Decoding pin direction in VHDL */
  189. static char *decode_pin_VHDL[] = {"-NONE-",
  190.                                   "IN",
  191.                                   "OUT",
  192.                                   "BUFFER", /* buffer is a sort of Output pin */
  193.                                   "INOUT",
  194.                                   "CONFIG_PIN",
  195.                                   "POWER_PIN"};
  196. /* ********************************************************************** */
  197. /* VHDL output of the entities                                            */
  198. /* ********************************************************************** */
  199. static char illegal[] = "$:|/.\\ ";
  200. static char replace[] = "Sxxxxx_";
  201.  
  202. char *make_vhdl_name (char *buffer, char *str)
  203. {
  204.         int i, j, l;
  205.         buffer[0] = 0;
  206.         if (str)
  207.         {
  208.                 strcpy (buffer, str); /* should be a call to strncpy !! */
  209.         }
  210.         l = strlen (buffer);
  211.         /* edit out illegal strings from the net name */
  212.         for (i = 0; i < l; i++)
  213.         {
  214.                 for (j = 0; j < sizeof (illegal); j++)
  215.                         if (buffer[i] == illegal[j])
  216.                                 buffer[i] = replace[j];
  217.         }
  218.         i = l - 1;
  219.         /* convert pin indices back from Altera form if we are looking at FIT files */
  220.         if (l)
  221.         {
  222.                 /* name ends in underscore, this forces mapping name_nn_ --> name(nn) */
  223.                 if (buffer[i] == '_')
  224.                 {
  225.                         buffer[i--] = ')';
  226.                         while (i >= 0 && buffer[i] != '_')
  227.                                 i--;
  228.                         if (i >= 0)
  229.                                 buffer[i] = '(';
  230.                 }
  231.         }
  232.         return buffer;
  233. }
  234.  
  235. /* ********************************************************************** */
  236. /* decodes the 'vector' part of a bus , if known                           */
  237. void decode_vhdl_bus (FILE *f, vhdl_t *vhdl, generic_print_style recurse_generics)
  238. {
  239.         if (!vhdl)
  240.                 vhdl = default_vhdl_datatype;
  241.         if (vhdl->is_vector)
  242.                 print_range_expression (f, vhdl->expr, recurse_generics);
  243. }
  244.  
  245. /* ********************************************************************** */
  246.  
  247. void decode_vhdl_type (FILE *f, vhdl_t *vhdl, generic_print_style recurse_generics)
  248. {
  249.         /* avoid crashing on a null pointer */
  250.         if (!vhdl)
  251.                 vhdl = default_vhdl_datatype;
  252.         fprintf (f, "%s ", vhdl->basetype);
  253.         if (vhdl->is_vector)
  254.                 decode_vhdl_bus (f, vhdl, recurse_generics);
  255. }
  256.  
  257. /* ********************************************************************** */
  258.  
  259. /* print out a VHDL component declaration */
  260. void print_VHDL_component (FILE *f, socket_t *dev, int All)
  261. {
  262.         node_t *n;
  263.         /* sort the identifiers of the nodes */
  264.         sort_nodes (dev, NO_EXTRACT_XY);
  265.  
  266.         fprintf (f, "COMPONENT  %s\n", check_null_str (dev->type));
  267.         fprintf (f, "--  DEV_IDENT \"%s\"\n\n", check_null_str (dev->identifier));
  268.         if (dev->is_template)
  269.                 fprintf (f, "--  Defined by COMPONENT definition\n");
  270.  
  271.         if (dev->generics)
  272.                 list_VHDL_generic_values (f, &dev->generics);
  273.  
  274.         fprintf (f, "  PORT ( \n");
  275.         /* sort the identifiers of the nodes */
  276.         sort_nodes (dev, NO_EXTRACT_XY);
  277.         n = dev->nodes;
  278.         while (n)
  279.         {
  280.                 vhdl_t *pin_datatype = default_vhdl_datatype;
  281.                 expression_t *default_expr = NULL;
  282.                 char nam[MAXIDLEN];
  283.                 if (n->orig_vhdltype)
  284.                 {
  285.                         pin_datatype = n->orig_vhdltype;
  286.                         default_expr = n->orig_vhdltype->default_expr;
  287.                 }
  288.                 else if (n->vhdltype)
  289.                 {
  290.                         pin_datatype = n->vhdltype;
  291.                         default_expr = n->vhdltype->default_expr;
  292.                 }
  293.                 if ((n->net_assigned && n->in_use) || (All || dev->is_template))
  294.                 {
  295.                         fprintf (
  296.                             f,
  297.                             "  %-16s : %6s  ",
  298.                             make_vhdl_name (nam, check_null_str (n->identifier)), /* was
  299.                                                                                      n->name */
  300.                             decode_pin_VHDL[(int) n->pindir]);
  301.                         decode_vhdl_type (f, pin_datatype, NO_RECURSE); /* until a generic
  302.                                                                            found */
  303.                         /* ought to be optional dependent on synthesis style */
  304.                         if (default_expr)
  305.                         {
  306.                                 fprintf (f, ":= ");
  307.                                 print_expression (f, default_expr, NO_RECURSE);
  308.                         }
  309.  
  310.                         if (n->sktnext)
  311.                                 fprintf (f, ";");
  312.                         fprintf (f, " -- i=%s r=%d --\n", n->identifier, n->refcount);
  313.                 }
  314.                 n = n->sktnext; /* traverse to next pin on socket */
  315.         };
  316.         fprintf (f, ");\nEND COMPONENT;\n\n");
  317. }
  318.  
  319. /* ********************************************************************** */
  320. /* Printout an instance of a component */
  321. /* ********************************************************************** */
  322. void print_VHDL_instance (FILE *f, socket_t *dev, int All)
  323. {
  324.         node_t *n;
  325.         int need_term = 0;
  326.         char *prefix;
  327.         /* only prefix devices with similar idents and types */
  328.         if (!ISNULLSTR (dev->identifier) && !ISNULLSTR (dev->type) &&
  329.             streq (dev->identifier, dev->type))
  330.         {
  331.                 prefix = "I_";
  332.         }
  333.         else
  334.         {
  335.                 prefix = "";
  336.         }
  337.  
  338.         fprintf (
  339.             f,
  340.             "%s%s : %s \n",
  341.             prefix,
  342.             check_null_str (dev->identifier),
  343.             check_null_str (dev->type));
  344.  
  345.         if (dev->generics)
  346.                 list_VHDL_generic_map_values (f, &dev->generics);
  347.  
  348.         fprintf (f, "  PORT MAP ( \n");
  349.         /* sort the identifiers of the nodes */
  350.         sort_nodes (dev, NO_EXTRACT_XY);
  351.         n = dev->nodes;
  352.         while (n)
  353.         {
  354.                 vhdl_t *pin_datatype = default_vhdl_datatype;
  355.                 char nam1[MAXIDLEN], nam2[MAXIDLEN];
  356.                 if (n->vhdltype)
  357.                         pin_datatype = n->vhdltype;
  358.                 if ((n->net_assigned && n->in_use) || All)
  359.                 {
  360.                         char *sig_prefix;
  361.                         if (need_term)
  362.                                 fprintf (f, ",\n");
  363.                         else
  364.                                 fprintf (f, "\n");
  365.                         need_term = 1;
  366.                         /* is there a slice in the output */
  367.                         if (n->net && n->net->needs_buff_sig)
  368.                                 sig_prefix = BUFPREFIX;
  369.                         else
  370.                                 sig_prefix = "";
  371.  
  372.                         if (n->net)
  373.                         {
  374.                                 fprintf (
  375.                                     f,
  376.                                     "  %s",
  377.                                     make_vhdl_name (
  378.                                         nam1, check_null_str (n->identifier))); /* was n->name
  379.                                                                                  */
  380.                                 if (n->lhs_expr)
  381.                                 {
  382.                                         print_range_expression (f, n->lhs_expr, RECURSE_CONST);
  383.                                 }
  384.                                 fprintf (
  385.                                     f,
  386.                                     "=> %s%s ",
  387.                                     sig_prefix,
  388.                                     make_vhdl_name (nam2, check_null_str (n->net->name)));
  389.                         }
  390.                         else
  391.                         {
  392.                                 fprintf (
  393.                                     f,
  394.                                     "  %-20s => OPEN ",
  395.                                     make_vhdl_name (
  396.                                         nam1, check_null_str (n->identifier))); /* was n->name
  397.                                                                                  */
  398.                         }
  399.                         /* do bus slicing only if the connected net is a bus */
  400.                         if (n->net && n->net->vhdltype)
  401.                         {
  402.                                 decode_vhdl_bus (f, n->net->vhdltype, RECURSE_CONST);
  403.                         }
  404.                         else
  405.                         {
  406.                                 /*  fprintf(f,"\n"); */
  407.                         }
  408.                 }
  409.                 n = n->sktnext; /* traverse to next pin on socket */
  410.         };
  411.         fprintf (f, "\n   );\n\n");
  412. }
  413.  
  414. /* ********************************************************************** */
  415.  
  416. void print_VHDL_sigs (FILE *f)
  417. {
  418.         net_t *net = named_list;
  419.         char nam[MAXIDLEN], *sig_prefix;
  420.         while (net)
  421.         {
  422.                 if (net->needs_buff_sig)
  423.                         sig_prefix = BUFPREFIX;
  424.                 else
  425.                         sig_prefix = "";
  426.                 /* May 21 2001 only print nets that connect to 'external' tagged modules */
  427.                 if ((IS_ROUTABLE (net->how_routed)) &&
  428.                     ((net->bundle_member) || ((net->inside_partition) && net->has_external)))
  429.                 {
  430.                         fprintf (f, "    ");
  431.                 }
  432.                 else
  433.                 {
  434.                         fprintf (f, "  --");
  435.                 }
  436.  
  437.                 fprintf (f, " signal %s%s : ", sig_prefix, make_vhdl_name (nam, net->name));
  438.                 decode_vhdl_type (f, net->vhdltype, RECURSE_CONST);
  439.                 if (net->vhdltype)
  440.                 {
  441.                         if (net->vhdltype->decl_expr)
  442.                         {
  443.                                 print_expression (f, net->vhdltype->decl_expr, NO_RECURSE);
  444.                         }
  445.                         if (net->vhdltype->default_expr)
  446.                         {
  447.                                 fprintf (f, ":= ");
  448.                                 print_expression (f, net->vhdltype->default_expr, NO_RECURSE);
  449.                         }
  450.                 }
  451.                 fprintf (
  452.                     f,
  453.                     "; -- partition : %s %s %s %s %s\n",
  454.                     net->inside_partition ? "used in," : "unused in,",
  455.                     net->leaves_partition ? "leaves," : "buried,",
  456.                     net->needs_buff_sig ? ", buffered," : "",
  457.                     net->has_external ? "external skt" : "internal skt",
  458.                     net->bundle_member ? "bundle member" : " not bundled");
  459.                 net = net->next;
  460.         }
  461. }
  462. /* ********************************************************************** */
  463.  
  464. void print_VHDL_assignments (FILE *f)
  465. {
  466.         net_t *net = named_list;
  467.         socket_t *socket = socket_head;
  468.  
  469.         /* code borrowed from Verilog */
  470.         fprintf (f, "-- Bundled signals\n\n");
  471.  
  472.         while (socket)
  473.         {
  474.                 node_t *nodes = socket->nodes;
  475.                 if (socket->highest_bundle &&
  476.                     (socket->bundle_width > MINBUNDLE)) /* will not do assigns on small bundles
  477.                                                          */
  478.                         while (nodes)
  479.                         {
  480.                                 if (nodes->bundle_index >= 0)
  481.                                 {
  482.                                         char nam[MAXIDLEN];
  483.                                         net_t *net = nodes->net;
  484.                                         make_vhdl_name (nam, net->name);
  485.                                         fprintf (
  486.                                             f,
  487.                                             " %s <= %s(%d);\n",
  488.                                             nam,
  489.                                             socket->identifier,
  490.                                             nodes->bundle_index);
  491.                                 }
  492.                                 nodes = nodes->sktnext;
  493.                         }
  494.                 /*    else
  495.                       fprintf(f,"-- %s;\n",
  496.                                net->name);
  497.                 */
  498.  
  499.                 socket = socket->next;
  500.         }
  501.  
  502.         fprintf (f, "-- Buffered signals\n\n");
  503.         while (net)
  504.         {
  505.                 if (net->inside_partition && net->needs_buff_sig)
  506.                 {
  507.                         char nam[MAXIDLEN];
  508.                         make_vhdl_name (nam, net->name),
  509.  
  510.                             fprintf (f, " %-20s <= " BUFPREFIX "%s; -- buffer\n", nam, nam);
  511.                 }
  512.                 if (net->vhdl_connect_net && net->subnets)
  513.                 {
  514.                         char nam[MAXIDLEN], nam1[MAXIDLEN];
  515.                         make_vhdl_name (nam, net->identifier);
  516.                         make_vhdl_name (nam1, net->subnets->identifier);
  517.                         fprintf (f, " %-20s <= %s; -- connector\n", nam, nam1);
  518.                 }
  519.                 else if (net->inside_partition && net->vhdltype && net->vhdltype->default_expr)
  520.                 {
  521.                         char nam[MAXIDLEN];
  522.                         make_vhdl_name (nam, net->identifier);
  523.                         fprintf (f, " %-20s <= ", nam);
  524.                         print_range_expression (f, net->vhdltype->default_expr, NO_RECURSE);
  525.                         fprintf (f, "; -- Defined default drive value\n");
  526.                 }
  527.  
  528.                 net = net->next;
  529.         }
  530.         fprintf (f, "-- \n\n");
  531. }
  532.  
  533. /* ********************************************************************** */
  534. /* code lists bundles although they are probably broken */
  535. void print_VHDL_entity (FILE *f, char *entityname)
  536. {
  537.         net_t *net;
  538.         int need_term = 0;
  539.         socket_t *skt;
  540.         char nam[MAXIDLEN];
  541.  
  542.         fprintf (f, "ENTITY %s IS\n", entityname);
  543.         /* print out global generic settings */
  544.         /*
  545.           list_VHDL_generic_values (f,&partition_generics);
  546.         */
  547.         fprintf (f, "  PORT (\n");
  548.  
  549.         skt = socket_head;
  550.         /* bundles of pins are replaced by signals named the same as a socket which
  551.            they are bundled through , unless the bundles are too small in which case they
  552.            are replaced by separate wires */
  553.         while (skt)
  554.         {
  555.                 if (skt->highest_bundle)
  556.                 {
  557.                         if (skt->bundle_width > MINBUNDLE)
  558.                         {
  559.                                 if (need_term)
  560.                                 {
  561.                                         fprintf (f, ";\n");
  562.                                         need_term = 0;
  563.                                 }
  564.                                 else
  565.                                 {
  566.                                         fprintf (f, "\n");
  567.                                 }
  568.                                 fprintf (
  569.                                     f,
  570.                                     "  %-15s : %6s %s (%d downto 0) ",
  571.                                     make_vhdl_name (nam, skt->identifier),
  572.                                     decode_pin_VHDL[BIDIR],
  573.                                     default_vhdl_bustype->basetype,
  574.                                     skt->bundle_width - 1);
  575.  
  576.                                 need_term = 1;
  577.                         }
  578.                         else
  579.                         /* if the 'bundle' has less than MINBUNDLE pins, */
  580.                         /* list out all of the nets in turn as pins      */
  581.                         {
  582.                                 node_t *node;
  583.                                 node = skt->nodes;
  584.                                 while (node)
  585.                                 {
  586.                                         net = node->net;
  587.                                         /*
  588.                                             printf("node %s\n",node->identifier);
  589.                                         */
  590.                                         if (net && IS_ROUTABLE (net->how_routed) &&
  591.                                             net->bundle_member)
  592.                                         {
  593.                                                 if (need_term)
  594.                                                 {
  595.                                                         fprintf (f, ";\n");
  596.                                                         need_term = 0;
  597.                                                 }
  598.                                                 else
  599.                                                 {
  600.                                                         fprintf (f, "\n");
  601.                                                 }
  602.                                                 fprintf (
  603.                                                     f,
  604.                                                     "  %-15s : %6s ",
  605.                                                     make_vhdl_name (nam, net->name),
  606.                                                     decode_pin_VHDL[net->ext_dir]);
  607.                                                 decode_vhdl_type (
  608.                                                     f, net->vhdltype, RECURSE_NUMBER);
  609.                                                 need_term = 1;
  610.                                         }
  611.                                         node = node->sktnext;
  612.                                 }
  613.                         }
  614.                 }
  615.  
  616.                 skt = skt->next;
  617.         }
  618.  
  619.         /* go back and list all of the non-bundle pins */
  620.  
  621.         net = named_list;
  622.  
  623.         while (net)
  624.         {
  625.                 /* print out only unbundled nets as ports of the pcb */
  626.                 if (net->leaves_partition && !net->bundle_member)
  627.                 {
  628.                         if (need_term)
  629.                         {
  630.                                 fprintf (f, ";\n");
  631.                         }
  632.                         else
  633.                         {
  634.                                 fprintf (f, "\n");
  635.                         }
  636.                         fprintf (
  637.                             f,
  638.                             "  %-15s : %6s ",
  639.                             make_vhdl_name (nam, net->name),
  640.                             decode_pin_VHDL[net->ext_dir]);
  641.                         decode_vhdl_type (f, net->vhdltype, RECURSE_NUMBER);
  642.  
  643.                         need_term = 1;
  644.                 }
  645.                 net = net->next;
  646.         }
  647.         fprintf (f, "\n     );\n");
  648.         fprintf (f, "END %s;\n\n", entityname);
  649. }
  650.  
  651. /* ********************************************************************** */
  652. /* generate default VHDL Libraries */
  653. /* ********************************************************************** */
  654. void print_VHDL_libs (FILE *f)
  655. {
  656.         fprintf (f, "LIBRARY IEEE,WORK;\nUSE IEEE.std_logic_1164.ALL;\n\n");
  657. }
  658.  
  659. /* ********************************************************************** */
  660. /* generate a VHDL architecture forselected sockets */
  661. /* ********************************************************************** */
  662. void print_VHDL_architecture (FILE *f, char *entityname)
  663. {
  664.         socket_t *skt;
  665.         char *arch_name;
  666.         generic_info_t gen[1];
  667.         /* if we are using VHDL then look at the VHDL architecture name if  defined*/
  668.  
  669.         arch_name =
  670.             (get_generic_value (&global_generics, "vhdl_arch_name", gen) == IS_ENV_VAL &&
  671.              gen->expr)
  672.                 ? gen->expr->left.s
  673.                 : "top_arch";
  674.         fprintf (f, "\n\nARCHITECTURE %s OF  %s IS\n\n", arch_name, entityname);
  675.         /* not allowed to have generics at the top level so put them here */
  676.         list_VHDL_constants (f, &partition_generics);
  677.  
  678.         list_VHDL_constants (f, &global_generics);
  679.         /* clear type seen flags on all socket templates = components */
  680.         clr_type_seen ();
  681.  
  682.         skt = socket_head;
  683.         /* list out templates for those sockets selected */
  684.         while (skt)
  685.         {
  686.                 if (skt->is_external && skt->highest_bundle == 0)
  687.                 {
  688.                         /* suppress printout of duplicate components .... */
  689.                         if (skt->template_socket)
  690.                         {
  691.                                 if (skt->template_socket->socket_type_seen == 0)
  692.                                 {
  693.                                         print_VHDL_component (f, skt->template_socket, 0);
  694.                                         skt->template_socket->socket_type_seen = 1;
  695.                                 }
  696.                         }
  697.                         else
  698.                                 /* no components, use socket/entity as its own component */
  699.                                 print_VHDL_component (f, skt, 0);
  700.                 }
  701.                 skt = skt->next;
  702.         }
  703.  
  704.         print_VHDL_sigs (f);
  705.         fprintf (f, "\n\nBEGIN\n\n");
  706.         skt = socket_head;
  707.         while (skt)
  708.         {
  709.                 if (skt->is_external && skt->highest_bundle == 0)
  710.                         print_VHDL_instance (f, skt, 0);
  711.                 skt = skt->next;
  712.         }
  713.         print_VHDL_assignments (f);
  714.         fprintf (f, "END %s;\n\n", arch_name);
  715. }
  716.  
  717. /* ********************************************************************** */
  718. /* generate a VHDL file */
  719. /* ********************************************************************** */
  720.  
  721. void produce_VHDL (FILE *f, char *entityname, char *template)
  722. {
  723.         char linebuff[256];
  724.         int done_entity = 0, done_architecture = 0;
  725.         if (!template || !template[0])
  726.         { /* check null pointer or empty string */
  727.                 fprintf (f, "-- vertical vhdl\n");
  728.                 print_header (f, "WRITE VHDL");
  729.                 print_VHDL_libs (f);
  730.                 fprintf (f, "\n-- vertical read_off\n");
  731.                 print_VHDL_entity (f, entityname);
  732.                 fprintf (f, "\n-- vertical read_on\n");
  733.                 print_VHDL_libs (f);
  734.                 print_VHDL_architecture (f, entityname);
  735.                 fprintf (f, "\n-- vertical end;\n");
  736.         }
  737.         else
  738.         { /* there is a template file */
  739.                 FILE *tp;
  740.                 tp = fopen (template, "r");
  741.                 if (tp)
  742.                 {
  743.                         fprintf (f, "-- vertical vhdl\n");
  744.                         print_header (f, "WRITE VHDL");
  745.                         fprintf (f, "-- Using template '%s'\n", template);
  746.                         while (!feof (tp))
  747.                         {
  748.                                 if (fgets (linebuff, 256, tp))
  749.                                 {
  750.                                         if (strstr (linebuff, "$ENT"))
  751.                                         {
  752.                                                 fprintf (f, "\n-- vertical read_off\n");
  753.                                                 print_VHDL_entity (f, entityname);
  754.                                                 fprintf (f, "\n-- vertical read_on\n");
  755.                                                 done_entity++;
  756.                                         }
  757.                                         else if (strstr (linebuff, "$ARCH"))
  758.                                         {
  759.                                                 print_VHDL_architecture (f, entityname);
  760.                                                 done_architecture++;
  761.                                         }
  762.                                         else
  763.                                                 fprintf (f, "%s", linebuff); /* it already has
  764.                                                                                 a '\n' on the
  765.                                                                                 end */
  766.                                 }
  767.                         }
  768.                         fprintf (f, "\n-- vertical end;\n");
  769.                         fclose (tp);
  770.                         if (done_entity != 1)
  771.                                 Log (
  772.                                     LOG_ERROR,
  773.                                     "-- Error: %d  $ENT$ tags counted in template '%s'\n",
  774.                                     template);
  775.                         if (done_architecture != 1)
  776.                                 Log (
  777.                                     LOG_ERROR,
  778.                                     "-- Error: %d  $ARCH$ tags counted in template '%s'\n",
  779.                                     template);
  780.                 }
  781.                 else
  782.                         Log (
  783.                             LOG_ERROR,
  784.                             "-- Error: Cannot open VHDL  template '%s'\n",
  785.                             template);
  786.         }
  787. }
  788.