Subversion Repositories Vertical

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * $Id: print_vlog.c,v 1.2 2004/06/22 21:44:14 mjames Exp $
  3.  *
  4.  * $Log: print_vlog.c,v $
  5.  * Revision 1.2  2004/06/22 21:44:14  mjames
  6.  * Firrst build most files
  7.  *
  8.  * Revision 1.28  2002/09/09 10:11:27  mjames
  9.  * Moved pin remapping function to pin ident editing function from
  10.  * sorting pin name routine.
  11.  *
  12.  * Revision 1.27  2002/08/23 14:18:02  mjames
  13.  * Removed some constants to the header file
  14.  *
  15.  * Revision 1.26  2002/01/21 09:27:49  mjames
  16.  * Filtering of not routable nets was not 100% complete. Added
  17.  * code for this. Also a comma was suppressed on the first port listed on
  18.  * a top level component declaration, if this was a member of a bundle with less
  19.  * than (currently) 4 pins.
  20.  *
  21.  * Revision 1.25  2001/12/24 20:05:18  mjames
  22.  * Prevented wires being listed if not routable.
  23.  * Printing net names rather than identifiers.
  24.  *
  25.  * Revision 1.24  2001/12/20 13:37:34  mjames
  26.  * Small bundles printed as induvidual signals
  27.  *
  28.  * Revision 1.23  2001/12/11 20:32:23  mjames
  29.  * Implemented  regular expression pin  name editing
  30.  * Allows for elimination of pin_xx prefixing (as this is wrong for
  31.  * many verilog netlist)
  32.  *
  33.  * Revision 1.22  2001/11/19 10:41:35  mjames
  34.  * Merged back DTC release
  35.  *
  36.  * Revision 1.21.2.1  2001/11/15 22:04:43  mjames
  37.  * Removed unused variables
  38.  *
  39.  * Revision 1.21  2001/10/31 22:20:13  mjames
  40.  * Tidying up problematical comments caused by CVS
  41.  * 'intelligent' comment guessing
  42.  *
  43.  * Revision 1.20  2001/10/31 16:20:06  mjames
  44.  * fixed fpga alternate file printing to work in all cases.
  45.  *
  46.  * Revision 1.19  2001/10/22 10:57:52  mjames
  47.  * Identify bundle attributes with its declaration
  48.  * Allow the user to define a replacement string for the
  49.  * set fpga <socket_id> "string"
  50.  * which is printed out instead of the component declaration
  51.  *
  52.  * Revision 1.18  2001/10/11 11:52:32  mjames
  53.  * Syntax is now checked as compatible with Certify
  54.  *
  55.  * Revision 1.17  2001/10/10 20:18:22  mjames
  56.  * Added a vert_regcomp function to compile regular expressions
  57.  * with '^' (match start string) and  '$' (match end string) bracketing
  58.  * this => wildcard must match entire string not just a part of it.
  59.  *
  60.  * Revision 1.16  2001/09/16 20:36:03  mjames
  61.  * Second attempt to modify wire bundles to be connector rather than net
  62.  * centric. Allows more than one connector to carry the same net,
  63.  *
  64.  * Revision 1.15  2001/09/16 19:49:34  mjames
  65.  * Second attempt at bundling the pins on sockets
  66.  *
  67.  * Revision 1.14  2001/09/13 21:07:18  mjames
  68.  * Printing of wire bundles in place of induvidual pins for Ceritfy support.
  69.  *
  70.  * Revision 1.13  2001/08/09 20:30:37  mjames
  71.  * Needed to write net name not identifier carried on net when listing device pins
  72.  *
  73.  * Revision 1.12  2001/07/16 15:55:14  MJAMES
  74.  * Conversion to correctly print port list of  extracted components.
  75.  *
  76.  * Revision 1.11  2001/07/12 09:12:10  mjames
  77.  * Commented out dead function to do with printing signal types:
  78.  * This was a hangover from VHDL printing.
  79.  *
  80.  * Revision 1.10  2001/06/22 11:06:49  mjames
  81.  * Modified to tag Verilog code generated so that
  82.  * Vertical can recognise it.
  83.  *
  84.  * Revision 1.9  2001/06/19 05:21:26  mjames
  85.  * Fine tuning to try and reproduce files that are compatible with
  86.  * Certify
  87.  *
  88.  * Revision 1.8  2001/06/07 13:34:22  MJAMES
  89.  * Correctly removing unused nets from printouts
  90.  *
  91.  * Revision 1.7  2001/06/06 12:10:19  mjames
  92.  * Move from HPUX
  93.  *
  94.  * Revision 1.6  2001/04/06 22:47:02  mjames
  95.  * Added doc2, the creator of documentation to Vertical scripts uses PERL
  96.  *
  97.  *
  98.  * Also correcting generic behaviour and the printing of Verilog.
  99.  *
  100.  * Revision 1.5  2001/04/04 22:12:31  mjames
  101.  * Added some online documentation to the C program command handler
  102.  * THis is scanned by a utility called 'doc' that currently creates
  103.  * simple HTML from part formatted C comments
  104.  *
  105.  * Also working well on printing VERILOG
  106.  *
  107.  * still have problems with C comments and VERTICAL pragmas.
  108.  *
  109.  * Revision 1.4  2001/03/29 22:08:56  mjames
  110.  * Modified to define the scope of set generic commands : now can be global
  111.  * or defined for a socket or a simple wildcarded list of sockets.
  112.  *
  113.  * In addition the is_FPGA property has been activated so that FPGA components
  114.  * are not listed out when used in a Verilog (.vb) file.
  115.  *
  116.  * Version raised to 11.02
  117.  *
  118.  * Revision 1.3  2001/03/29 08:27:07  mjames
  119.  * Converted frbread for use with the newer files from the drawing office
  120.  *
  121.  * Revision 1.2  2001/01/02 07:53:53  mjames
  122.  * Made changes to allow for interface with TCL/Tk
  123.  *
  124.  * Revision 1.1.1.1  2000/10/19 21:58:39  mjames
  125.  * Mike put it here
  126.  *
  127.  *
  128.  * Revision 1.21  2000/10/04  10:37:08  10:37:08  mjames (Mike James)
  129.  * Modified for Vertical2 : support COMPONENTS and SIGNALS
  130.  *
  131.  * Revision 1.21  2000/10/04  10:37:08  10:37:08  mjames (Mike James)
  132.  * Part of Release PSAVAT01
  133.  *
  134.  * Revision 1.20  2000/10/02  11:04:18  11:04:18  mjames (Mike James)
  135.  * new_vhdl
  136.  *
  137.  * Revision 1.19  2000/09/27  14:42:18  14:42:18  mjames (Mike James)
  138.  * Part of Release Sep_27_ST_2000
  139.  *
  140.  * Revision 1.18  2000/09/21  10:15:48  10:15:48  mjames (Mike James)
  141.  * Part of Release Sep21Alpha
  142.  *
  143.  * Revision 1.17  2000/08/25  09:57:14  09:57:14  mjames (Mike James)
  144.  * Part of Release Aug25_alpha
  145.  *
  146.  * Revision 1.16  2000/08/16  08:57:30  08:57:30  mjames (Mike James)
  147.  * Part of Release CD01_Aug2000
  148.  *
  149.  * Revision 1.15  2000/08/14  14:45:12  14:45:12  mjames (Mike James)
  150.  * Part of Release Aug_14_2000
  151.  *
  152.  * Revision 1.14  2000/08/14  14:43:27  14:43:27  mjames (Mike James)
  153.  * Added power pins
  154.  *
  155.  * Revision 1.13  2000/08/11  14:17:18  14:17:18  mjames (Mike James)
  156.  * Failed to suppress declaring internal components
  157.  * when printing verilog.
  158.  *
  159.  * Revision 1.12  2000/08/11  08:30:32  08:30:32  mjames (Mike James)
  160.  * Part of Release Aug_11_2000
  161.  *
  162.  * Revision 1.11  2000/08/09  10:31:47  10:31:47  mjames (Mike James)
  163.  * Part of Release Aug__9_2000
  164.  *
  165.  * Revision 1.10  2000/05/31  11:42:57  11:42:57  mjames (Mike James)
  166.  * Part of Release May_31_2000
  167.  *
  168.  * Revision 1.9  2000/05/08  17:01:38  17:01:38  mjames (Mike James)
  169.  * Part of Release May__8_2000
  170.  *
  171.  * Revision 1.8  2000/05/08  16:59:31  16:59:31  mjames (Mike James)
  172.  * Part of Release May__8_2000
  173.  *
  174.  * Revision 1.7  2000/05/08  16:57:07  16:57:07  mjames (Mike James)
  175.  * Part of Release May__8_2000
  176.  *
  177.  * Revision 1.6  2000/03/08  16:19:23  16:19:23  mjames (Mike James)
  178.  * New version including PC
  179.  *
  180.  * Revision 1.3  2000/01/20  15:58:47  15:58:47  mjames (Mike James)
  181.  * Part of Release R22
  182.  *
  183.  * Revision 1.2  99/12/22  11:15:28  11:15:28  mjames (Mike James)
  184.  * Part of Release Dec_22_1999
  185.  *
  186.  * Revision 1.1  99/11/23  13:52:43  13:52:43  mjames (Mike James)
  187.  * Initial revision
  188.  *
  189.  */
  190.  
  191. #include "cmdlog.h"
  192. #include "cmdparse.h"
  193. #include "database.h"
  194. #include "expression.h"
  195. #include "generic.h"
  196. #include "print_vhdl.h"
  197. #include "printout.h"
  198. #include "sorting.h"
  199. #include "vertcl_main.h"
  200.  
  201. #include <ctype.h>
  202. #include <regex.h>
  203. #include <stdio.h>
  204. #include <stdlib.h>
  205. #include <string.h>
  206. #include <time.h>
  207.  
  208. /* ********************************************************************** */
  209.  
  210. /* Decoding pin direction in VLOG */
  211. static char *decode_pin_VLOG[] = {"inout", /* was -NONE- */
  212.                                   "inout", /* was in */
  213.                                   "out",
  214.                                   "out", /* buffer is a sort of Output pin */
  215.                                   "inout",
  216.                                   "inout",  /* config is a sort of input pin */
  217.                                   "inout"}; /* power is a sort of input pin */
  218.  
  219. /* ********************************************************************** */
  220. /* VHDL output of the entities                                            */
  221. /* ********************************************************************** */
  222. static char illegal[] = "-+:|/.\\$ ";
  223. static char replace[] = "NPCxxxxS_";
  224. char *make_VLOG_name (char *buffer, char *str)
  225. {
  226.         int i, l, j;
  227.  
  228.         l = strlen (str);
  229.         if (isdigit (str[0]))
  230.         {
  231.                 l += 1;
  232.                 sprintf (buffer, "\%s", str); /* might as well use the verilog quotation method
  233.                                                  in this case */
  234.         }
  235.         else
  236.                 strcpy (buffer, str);
  237.  
  238.         /* spot illegal strings in the net name */
  239.         for (i = 0; i < l; i++)
  240.         {
  241.                 for (j = 0; j < sizeof (illegal); j++)
  242.                         if (buffer[i] == illegal[j])
  243.                                 buffer[i] = replace[j];
  244.         }
  245.  
  246.         i = l - 1;
  247.         /* convert pin indices back from Altera form if we are looking at FIT files */
  248.         if (l)
  249.         {
  250.                 /* name ends in underscore, this forces mapping name_nn_ --> name(nn) */
  251.                 if (buffer[i] == '_')
  252.                 {
  253.                         buffer[i--] = ']';
  254.                         while (i >= 0 && buffer[i] != '_')
  255.                                 i--;
  256.                         if (i >= 0)
  257.                                 buffer[i] = '[';
  258.                 }
  259.         }
  260.         return buffer;
  261. }
  262.  
  263. /* ********************************************************************** */
  264. /* decodes the 'vector' part of a bus , if known                           */
  265. int decode_VLOG_bus (FILE *f, vhdl_t *vhdl)
  266. {
  267.         if (!vhdl)
  268.                 vhdl = default_vhdl_datatype;
  269.  
  270.         if (vhdl->is_vector)
  271.         {
  272.                 int bus_high, bus_low;
  273.                 bus_high = 0;
  274.                 bus_low = 0;
  275.                 eval_vhdl_expression (vhdl->expr, &bus_high, &bus_low);
  276.                 if (bus_high == bus_low)
  277.                         return fprintf (f, "[%d]", bus_high);
  278.                 else
  279.                         return fprintf (f, "[%d:%d]", bus_high, bus_low);
  280.         }
  281.         return 0;
  282. }
  283.  
  284. /* ********************************************************************** */
  285. /* ?? looks like hangover from VHDL */
  286. #if defined NEED_VLOG_TYPE
  287. void decode_VLOG_type (FILE *f, vhdl_t *vhdl)
  288. {
  289.         /* avoid crashing on a null pointer */
  290.         if (!vhdl)
  291.                 vhdl = default_vhdl_datatype;
  292.         fprintf (f, "%s ", vhdl->basetype);
  293.         decode_VLOG_bus (f, vhdl);
  294. }
  295. #endif
  296.  
  297. /* ********************************************************************** */
  298. /* Certify specific stuff */
  299. /* this copies declaration directives over */
  300. void assign_declaration_directives (socket_t *skt, generic_info_t *list)
  301. {
  302.         while (list)
  303.         {
  304.                 if (list->g_type == IS_DECLARATION_DIRECTIVE)
  305.                         set_generic_value (&(skt->generics), list);
  306.                 if (list->g_type == IS_INSTANCE_DIRECTIVE)
  307.                         set_generic_value (&(skt->generics), list);
  308.                 list = list->next;
  309.         }
  310. }
  311.  
  312. /* ********************************************************************** */
  313. /* print out a VLOG component declaration */
  314.  
  315. void print_VLOG_component (FILE *f, socket_t *dev, int All)
  316. {
  317.         node_t *n;
  318.         char printed = 0;
  319.         char nam[MAXIDLEN], typ[MAXIDLEN];
  320.         generic_info_t *g_list = dev->generics;
  321.         make_VLOG_name (typ, check_null_str (dev->type));
  322.  
  323.         fprintf (f, "\nmodule  %s (\n", typ);
  324.  
  325.         /* sort the identifiers of the nodes */
  326.         sort_nodes (dev, NO_EXTRACT_XY);
  327.         n = dev->nodes;
  328.         while (n)
  329.         {
  330.                 /* print the pin ID if it is connected to a net and the net is routable */
  331.                 if (All || (n->net && n->net->how_routed != Not_Routable))
  332.                 {
  333.                         char nam1[MAXIDLEN];
  334.                         if (printed)
  335.                                 fprintf (f, ",\n");
  336.                         printed = 1;
  337.                         sprintf (nam1, "%s", check_null_str (n->identifier));
  338.                         fprintf (f, "  %s", make_VLOG_name (nam, nam1));
  339.                 }
  340.                 n = n->sktnext; /* traverse to next pin on socket */
  341.         };
  342.         fprintf (f, " );\n\n");
  343.         /* list any declaration directives */
  344.         while (g_list)
  345.         {
  346.                 if (g_list->g_type == IS_DECLARATION_DIRECTIVE)
  347.                 {
  348.                         if (!g_list->expr || ISNULLSTR (g_list->expr->left.s))
  349.                                 fprintf (f, "/* synthesis %s */\n", g_list->name);
  350.                         else
  351.                                 fprintf (
  352.                                     f,
  353.                                     "/* synthesis %s = %s*/\n",
  354.                                     g_list->name,
  355.                                     check_null_str (g_list->expr->left.s));
  356.                 }
  357.                 g_list = g_list->next;
  358.         }
  359.  
  360.         n = dev->nodes;
  361.  
  362.         while (n)
  363.         {
  364.                 if (dev->is_template || (n->net && n->net->how_routed != Not_Routable))
  365.                 {
  366.                         fprintf (
  367.                             f,
  368.                             " %8s %s ",
  369.                             decode_pin_VLOG[(int) n->pindir],
  370.                             make_VLOG_name (nam, check_null_str (n->identifier)));
  371.                         decode_VLOG_bus (f, n->vhdltype);
  372.                         fprintf (f, ";\n");
  373.                 }
  374.                 n = n->sktnext; /* traverse to next pin on socket */
  375.         };
  376.         fprintf (f, "endmodule\n\n");
  377. }
  378.  
  379. /* ********************************************************************** */
  380. /* Printout an instance of a component */
  381. /* ********************************************************************** */
  382. void print_VLOG_instance (FILE *f, socket_t *dev, int All)
  383. {
  384.         node_t *n;
  385.         int need_term = 0;
  386.         char nam[MAXIDLEN], id[MAXIDLEN];
  387.         generic_info_t *g_list = dev->generics;
  388.         make_VLOG_name (nam, check_null_str (dev->type));
  389.         make_VLOG_name (id, check_null_str (dev->identifier));
  390.  
  391.         fprintf (f, "\n\n/* Component instance */\n");
  392.         fprintf (f, "%s %s ", nam, id);
  393.  
  394.         while (g_list)
  395.         {
  396.                 if (g_list->g_type == IS_INSTANCE_DIRECTIVE)
  397.                 {
  398.                         if (!g_list->expr || ISNULLSTR (g_list->expr->left.s))
  399.                                 fprintf (f, "/* synthesis %s */\n", g_list->name);
  400.                         else
  401.                                 fprintf (
  402.                                     f,
  403.                                     "/* synthesis %s = %s*/\n",
  404.                                     g_list->name,
  405.                                     check_null_str (g_list->expr->left.s));
  406.                 }
  407.                 g_list = g_list->next;
  408.         }
  409.  
  410.         fprintf (f, "   (\n");
  411.  
  412.         sort_nodes (dev, NO_EXTRACT_XY);
  413.         n = dev->nodes;
  414.  
  415.         while (n)
  416.         {
  417.                 char nam1[MAXIDLEN], nam2[MAXIDLEN];
  418.                 /* is there need to add a buffer signal prefix */
  419.  
  420.                 if (n->net && n->net->how_routed != Not_Routable)
  421.                 {
  422.                         if (need_term)
  423.                                 fprintf (f, ",\n");
  424.                         else
  425.                                 fprintf (f, "\n");
  426.                         need_term = 1;
  427.  
  428.                         if (n->net_assigned && n->in_use && !ISNULLSTR (n->identifier))
  429.                         {
  430.                                 fprintf (
  431.                                     f,
  432.                                     "   .%s(%s",
  433.                                     make_VLOG_name (nam1, check_null_str (n->identifier)),
  434.                                     make_VLOG_name (
  435.                                         nam2, check_null_str (n->net->name))); /* was
  436.                                                                                   identifier */
  437.                                 decode_VLOG_bus (f, n->vhdltype);
  438.                                 fprintf (f, ")");
  439.                         }
  440.                         else
  441.                         {
  442.                                 /* No assigned net : pin exists  */
  443.                                 fprintf (
  444.                                     f,
  445.                                     "   .%s()",
  446.                                     make_VLOG_name (nam1, check_null_str (n->identifier)));
  447.                         }
  448.                 }
  449.                 else
  450.                 {
  451.                         if (n->net && n->net->how_routed != Not_Routable)
  452.                         {
  453.                                 /* If we are printing comments then dont need a comma next time
  454.                                  */
  455.                                 if (need_term)
  456.                                         fprintf (f, ",\n");
  457.                                 else
  458.                                         fprintf (f, "\n");
  459.                                 need_term = 1;
  460.                                 fprintf (
  461.                                     f,
  462.                                     "   .pin_%s()",
  463.                                     make_VLOG_name (nam1, check_null_str (n->identifier)));
  464.                         }
  465.                 }
  466.                 n = n->sktnext; /* traverse to next pin on socket */
  467.         };
  468.         fprintf (f, "\n   );\n\n");
  469. }
  470.  
  471. /* ********************************************************************** */
  472.  
  473. void print_VLOG_sigs (FILE *f)
  474. {
  475.         net_t *net = named_list;
  476.         int width = 0;
  477.         char nam[MAXIDLEN], *sig_prefix;
  478.         while (net)
  479.         {
  480.                 if (net->needs_buff_sig)
  481.                         sig_prefix = BUFPREFIX;
  482.                 else
  483.                         sig_prefix = "";
  484.  
  485.                 if ((net->how_routed != Not_Routable) &&
  486.                     ((net->bundle_member) || ((net->inside_partition) && net->has_external)))
  487.                 { /* May 21 2001 only print nets that connect to 'external' tagged modules */
  488.                         /* add to this those in a bundled connection */
  489.                         width += fprintf (
  490.                             f, " wire %s%s;", sig_prefix, make_VLOG_name (nam, net->name));
  491.                         if (strcmp (nam, net->name) != 0) /* names changed by printout */
  492.                                 width += fprintf (f, "/* \"%s\" */", net->name);
  493.                 }
  494.                 else
  495.                 {
  496.                         if (level & 1)
  497.                         {
  498.                                 fprintf (
  499.                                     f,
  500.                                     "  /* wire %s%s; ",
  501.                                     sig_prefix,
  502.                                     make_VLOG_name (nam, net->name));
  503.                                 fprintf (f, " */");
  504.                         }
  505.                 }
  506.                 if (level & 1)
  507.                 {
  508.                         fprintf (
  509.                             f,
  510.                             " /* partition : %s %s %s %s %s*/\n",
  511.                             net->inside_partition ? "used in," : "unused in,",
  512.                             net->leaves_partition ? "leaves," : "buried,",
  513.                             net->needs_buff_sig ? ", buffered," : "",
  514.                             net->has_external ? "external skt" : "internal skt",
  515.                             net->bundle_member ? "bundle member" : " not bundled");
  516.                 }
  517.  
  518.                 if ((level & 1) || (width > MAXWIDTH))
  519.                 {
  520.                         width = 0;
  521.                         fprintf (f, "\n  ");
  522.                 }
  523.  
  524.                 net = net->next;
  525.         }
  526. }
  527. /* ********************************************************************** */
  528.  
  529. void print_VLOG_assignments (FILE *f)
  530. {
  531.         net_t *net = named_list;
  532.         socket_t *socket = socket_head;
  533.         fprintf (f, "/* Bundle signals */\n\n");
  534.  
  535.         while (socket)
  536.         {
  537.                 node_t *nodes = socket->nodes;
  538.                 if (socket->highest_bundle &&
  539.                     (socket->bundle_width > MINBUNDLE)) /* will not do assigns on small bundles
  540.                                                          */
  541.                         while (nodes)
  542.                         {
  543.                                 /*      if (strcmp("X6",socket->identifier)==0)              */
  544.                                 /*        {                                                  */
  545.                                 /*        printf("-- X6 index = %d\n",nodes->bundle_index);  */
  546.                                 /*        }                                                  */
  547.                                 if (nodes->bundle_index >= 0)
  548.                                 {
  549.                                         char nam[MAXIDLEN];
  550.                                         net_t *net = nodes->net;
  551.                                         make_VLOG_name (nam, net->name);
  552.                                         fprintf (
  553.                                             f,
  554.                                             " assign %s[%d] = %s;\n",
  555.                                             socket->identifier,
  556.                                             nodes->bundle_index,
  557.                                             nam);
  558.                                 }
  559.                                 nodes = nodes->sktnext;
  560.                         }
  561.                 /*    else
  562.                       fprintf(f,"-- %s;\n",
  563.                                net->name);
  564.                 */
  565.  
  566.                 socket = socket->next;
  567.         }
  568.         fprintf (f, "/* end bundle signals */ \n\n");
  569.  
  570. #if defined USE_PREV
  571.         fprintf (f, "/* Bundle signals */\n\n");
  572.  
  573.         while (net)
  574.         {
  575.                 if (net->bundle_parent)
  576.                 {
  577.                         char nam[MAXIDLEN];
  578.                         make_VLOG_name (nam, net->name);
  579.                         fprintf (
  580.                             f,
  581.                             " assign %s[%d] = %s;\n",
  582.                             net->bundle_parent->identifier,
  583.                             net->bundle_index,
  584.                             nam);
  585.                 }
  586.                 /*    else
  587.                       fprintf(f,"-- %s;\n",
  588.                                net->name);
  589.                 */
  590.  
  591.                 net = net->next;
  592.         }
  593.         fprintf (f, "/* end bundle signals */ \n\n");
  594. #endif
  595.  
  596.         net = named_list;
  597.         fprintf (f, "/* Buffered signals */\n\n");
  598.         while (net)
  599.         {
  600.                 if (net->inside_partition && net->needs_buff_sig)
  601.                 {
  602.                         char nam[MAXIDLEN];
  603.                         make_VLOG_name (nam, net->name);
  604.  
  605.                         fprintf (f, " assign " BUFPREFIX "%s = %s;\n", nam, nam);
  606.                 }
  607.                 net = net->next;
  608.         }
  609.  
  610.         fprintf (f, "/* end Buffered signals */ \n\n");
  611. }
  612.  
  613. /* ********************************************************************** */
  614.  
  615. void print_VLOG_entity (FILE *f, char *entityname)
  616. {
  617.         net_t *net;
  618.         int need_term = 0;
  619.         int width = 0;
  620.         socket_t *skt;
  621.         char nam[MAXIDLEN];
  622.  
  623.         fprintf (f, "\nmodule %s ", entityname);
  624.  
  625.         fprintf (f, "(\n  ");
  626.  
  627.         skt = socket_head;
  628.         /* bundles of pins are replaced by signals named the same as a socket which
  629.            they are bundled through , unless the bundles are too small in which case they
  630.            are replaced by separate wires */
  631.         while (skt)
  632.         {
  633.                 if (skt->highest_bundle)
  634.                 {
  635.                         if (skt->bundle_width > MINBUNDLE)
  636.                         {
  637.                                 if (need_term)
  638.                                 {
  639.                                         width += fprintf (f, ", ");
  640.                                         need_term = 0;
  641.                                 }
  642.                                 if (width > MAXWIDTH)
  643.                                 {
  644.                                         width = 0;
  645.                                         fprintf (f, "\n  ");
  646.                                 }
  647.                                 width += fprintf (f, "%s", skt->identifier);
  648.                                 need_term = 1;
  649.                         }
  650.                         else
  651.                         /* if the 'bundle' has less than MINBUNDLE pins, */
  652.                         /* list out all of the nets in turn as pins      */
  653.                         {
  654.                                 node_t *node;
  655.                                 node = skt->nodes;
  656.                                 while (node)
  657.                                 {
  658.                                         net = node->net;
  659.                                         /*
  660.                                             printf("node %s\n",node->identifier);
  661.                                         */
  662.                                         if (net && (net->how_routed != Not_Routable) &&
  663.                                             net->bundle_member)
  664.                                         {
  665.                                                 if (need_term)
  666.                                                 {
  667.                                                         width += fprintf (f, ", ");
  668.                                                         need_term = 0;
  669.                                                 }
  670.                                                 if (width > 60)
  671.                                                 {
  672.                                                         width = 0;
  673.                                                         fprintf (f, "\n  ");
  674.                                                 }
  675.                                                 width += fprintf (f, "%s", net->identifier);
  676.                                                 need_term = 1;
  677.                                         }
  678.                                         node = node->sktnext;
  679.                                 }
  680.                         }
  681.                 }
  682.  
  683.                 skt = skt->next;
  684.         }
  685.  
  686.         net = named_list;
  687.  
  688.         while (net)
  689.         {
  690.                 /* print out only unbundled nets as ports of the pcb */
  691.                 if (net->leaves_partition && !net->bundle_member)
  692.                 {
  693.                         if (need_term)
  694.                         {
  695.                                 width += fprintf (f, ", ");
  696.                         }
  697.                         if (width > MAXWIDTH)
  698.                         {
  699.                                 width = 0;
  700.                                 fprintf (f, "\n  ");
  701.                         }
  702.                         width += fprintf (f, " %s", make_VLOG_name (nam, net->name));
  703.                         /*        width+= decode_VLOG_bus(f,net->vhdltype); Not used in verilog
  704.                          */
  705.                         if (strcmp (nam, net->name) != 0) /* names changed by printout */
  706.                                 width += fprintf (f, " /* \"%s\" */", net->name);
  707.  
  708.                         need_term = 1;
  709.                 }
  710.                 net = net->next;
  711.         }
  712.         /* terminate port list */
  713.         fprintf (f, ");\n");
  714.  
  715.         fprintf (f, "/* synthesis syn_partition = \"board\" */ \n\n");
  716.  
  717.         need_term = 0;
  718.         skt = socket_head;
  719.  
  720.         /* now write out the verilog types of ll of the ports*/
  721.  
  722.         while (skt)
  723.         {
  724.                 if (skt->highest_bundle)
  725.                 {
  726.                         /* big bundles are listed as a single item */
  727.                         if (skt->bundle_width > MINBUNDLE)
  728.                         {
  729.                                 fprintf (
  730.                                     f,
  731.                                     "  inout [%d:%d] %s; // row(%d:%d) col(%d:%d) \n",
  732.                                     skt->highest_bundle,
  733.                                     skt->lowest_bundle,
  734.                                     skt->identifier,
  735.                                     skt->min_pin_row,
  736.                                     skt->max_pin_row,
  737.                                     skt->min_pin_col,
  738.                                     skt->max_pin_col);
  739.                         }
  740.                         else
  741.                         /* small bundles are enumerated as induvidual wires */
  742.                         {
  743.                                 node_t *node;
  744.                                 node = skt->nodes;
  745.                                 while (node)
  746.                                 {
  747.                                         net = node->net;
  748.                                         /*
  749.                                             printf("node %s\n",node->identifier);
  750.                                         */
  751.                                         if (net && net->bundle_member)
  752.                                         {
  753.                                                 fprintf (
  754.                                                     f, "  %s ", decode_pin_VLOG[net->ext_dir]);
  755.                                                 decode_VLOG_bus (f, net->vhdltype);
  756.                                                 fprintf (
  757.                                                     f,
  758.                                                     " %s;\n",
  759.                                                     make_VLOG_name (nam, net->name));
  760.                                         }
  761.                                         node = node->sktnext;
  762.                                 }
  763.                         }
  764.                 }
  765.  
  766.                 skt = skt->next;
  767.         }
  768.  
  769.         net = named_list;
  770.  
  771.         while (net)
  772.         {
  773.                 char nam[MAXIDLEN];
  774.                 if (net->leaves_partition && !net->bundle_member)
  775.                 {
  776.                         fprintf (f, "  %s ", decode_pin_VLOG[net->ext_dir]);
  777.                         decode_VLOG_bus (f, net->vhdltype);
  778.                         fprintf (f, " %s;\n", make_VLOG_name (nam, net->identifier));
  779.                 }
  780.                 net = net->next;
  781.         }
  782.         fprintf (f, "\n");
  783. }
  784.  
  785. /* ********************************************************************** */
  786. /* generate default VLOG Libraries */
  787. /* ********************************************************************** */
  788. void print_VLOG_libs (FILE *f)
  789. {
  790.         fprintf (f, "/* Default text */\n\n");
  791. }
  792.  
  793. /* **********************************************************************
  794.  * clear verilog 'type seen' flags (providing a single declaration for all
  795.  * instances of a given type
  796.  * **********************************************************************
  797.  * Using this as a means to avoid duplicate components: only print those
  798.  * not seen before */
  799.  
  800. void clr_type_seen (void)
  801. {
  802.         socket_t *skt;
  803.         skt = template_head;
  804.         while (skt)
  805.         {
  806.                 skt->socket_type_seen = 0;
  807.                 skt = skt->next;
  808.         }
  809. }
  810. /* **********************************************************************
  811.  * set verilog 'type seen' flags  for all instances of a given type
  812.  * ********************************************************************** */
  813. void set_type_seen (char *type)
  814. {
  815.         socket_t *skt;
  816.         skt = socket_head;
  817.         while (skt)
  818.         {
  819.                 if (strcmp (type, skt->type) == 0)
  820.                         skt->socket_type_seen = 1;
  821.                 skt = skt->next;
  822.         }
  823. }
  824.  
  825. /* ********************************************************************** */
  826. /* declare all used modules (once !!)  */
  827. /* ********************************************************************** */
  828. /* to do: fix up a generic giving an alternative verilog line for the
  829.    FPGA declaration case eg 'include something.v
  830.  
  831. Need to
  832.    bundle a socket then del external it for port bundling
  833.  
  834. */
  835.  
  836. void print_VLOG_declarations (FILE *f, char *entityname)
  837. {
  838.         socket_t *skt;
  839.         skt = socket_head;
  840.         clr_type_seen ();
  841.  
  842.         skt = socket_head;
  843.         /* list out templates for those sockets selected, and which have not been
  844.            converted into a bundle */
  845.         while (skt)
  846.         {
  847.                 if (skt->is_external && skt->highest_bundle == 0)
  848.                 {
  849.                         /* suppress printout of duplicate components .... */
  850.                         if (skt->template_socket)
  851.                         {
  852.                                 if (skt->template_socket->socket_type_seen == 0)
  853.                                 {
  854.                                         if (!skt->is_FPGA)
  855.                                         { /* only printout component decls for non-FPGA:
  856.                                          Certify has its own private store of these
  857.                                          declarations
  858.                                          and it is fiddly to match these exactly. */
  859.                                                 fprintf (
  860.                                                     f, "\n// defined by component template\n");
  861.                                                 print_VLOG_component (
  862.                                                     f, skt->template_socket, 1);
  863.                                         }
  864.                                         else
  865.                                         {
  866.                                                 generic_info_t *info = get_generic_ref (
  867.                                                     &skt->generics, "fpga_file");
  868.                                                 fprintf (
  869.                                                     f,
  870.                                                     "\n/* socket '%s' is an FPGA: component "
  871.                                                     "declaration skipped */\n",
  872.                                                     skt->identifier);
  873.                                                 if (info && info->g_type == IS_ATTRIBUTE)
  874.                                                 {
  875.                                                         fprintf (
  876.                                                             f,
  877.                                                             "/* replacement for declaration "
  878.                                                             "*/\n%s\n",
  879.                                                             info->expr->left.s
  880.                                                                 ? info->expr->left.s
  881.                                                                 : "");
  882.                                                 }
  883.                                         }
  884.                                         skt->template_socket->socket_type_seen = 1;
  885.                                 }
  886.                         }
  887.                         else
  888.                         {
  889.                                 /* no components, use socket/entity as its own component */
  890.                                 if (!skt->is_FPGA)
  891.                                 {
  892.                                         print_VLOG_component (f, skt, 1);
  893.                                 }
  894.                                 else
  895.                                 {
  896.                                         generic_info_t *info =
  897.                                             get_generic_ref (&skt->generics, "fpga_file");
  898.                                         fprintf (
  899.                                             f,
  900.                                             "\n/* socket '%s' is an FPGA: socket declaration "
  901.                                             "skipped */\n",
  902.                                             skt->identifier);
  903.                                         if (info && info->g_type == IS_ATTRIBUTE)
  904.                                         {
  905.                                                 fprintf (
  906.                                                     f,
  907.                                                     "/* replacement for declaration */\n%s\n",
  908.                                                     info->expr->left.s ? info->expr->left.s
  909.                                                                        : "");
  910.                                         }
  911.                                 }
  912.                         }
  913.                 }
  914.                 skt = skt->next;
  915.         }
  916. }
  917.  
  918. /* ********************************************************************** */
  919. /* generate a VLOG architecture  */
  920. /* ********************************************************************** */
  921.  
  922. void print_VLOG_architecture (FILE *f, char *entityname)
  923. {
  924.         socket_t *skt;
  925.         print_VLOG_entity (f, entityname);
  926.  
  927.         print_VLOG_sigs (f);
  928.  
  929.         skt = socket_head;
  930.         while (skt)
  931.         {
  932.                 if (skt->is_external && skt->highest_bundle == 0)
  933.                         print_VLOG_instance (f, skt, 0);
  934.                 skt = skt->next;
  935.         }
  936.         print_VLOG_assignments (f);
  937.         fprintf (f, "endmodule\n\n");
  938. }
  939.  
  940. /* ********************************************************************** */
  941. /* generate a VLOG file */
  942. /* ********************************************************************** */
  943.  
  944. void produce_VLOG (FILE *f, char *entityname, char *template)
  945. {
  946.         char linebuff[256];
  947.         int done_architecture = 0, done_declarations = 0;
  948.         if (!template || !template[0])
  949.         { /* check null pointer or empty string */
  950.                 fprintf (f, "// vertical verilog\n");
  951.                 print_VLOG_header (f, "WRITE VLOG");
  952.                 print_VLOG_declarations (f, entityname);
  953.                 print_VLOG_architecture (f, entityname);
  954.                 fprintf (f, "\n// vertical end;\n");
  955.         }
  956.         else
  957.         { /* there is a template file */
  958.                 FILE *tp;
  959.                 tp = fopen (template, "r");
  960.                 if (tp)
  961.                 {
  962.                         fprintf (f, "// vertical verilog\n");
  963.                         print_VLOG_header (f, "WRITE VLOG");
  964.                         fprintf (f, "/* Using template  '%s' */\n", template);
  965.                         while (!feof (tp))
  966.                         {
  967.                                 if (fgets (linebuff, 256, tp))
  968.                                 {
  969.                                         if (strstr (linebuff, "$DECL$"))
  970.                                         {
  971.                                                 print_VLOG_declarations (f, entityname);
  972.                                                 done_declarations++;
  973.                                         }
  974.  
  975.                                         else if (strstr (linebuff, "$ARCH$"))
  976.                                         {
  977.                                                 print_VLOG_architecture (f, entityname);
  978.                                                 done_architecture++;
  979.                                         }
  980.                                         else
  981.                                                 fprintf (f, "%s", linebuff); /* it already has
  982.                                                                                 a '\n' on the
  983.                                                                                 end */
  984.                                 }
  985.                         }
  986.                         fprintf (f, "\n// vertical end;\n");
  987.                         fclose (tp);
  988.                         if (done_declarations != 1)
  989.                                 Log (
  990.                                     LOG_ERROR,
  991.                                     "-- Error: %d  $DECL$ tags counted (need    1) in "
  992.                                     "template '%s'\n",
  993.                                     template);
  994.                         if (done_architecture != 1)
  995.                                 Log (
  996.                                     LOG_ERROR,
  997.                                     "-- Error: %d  $ARCH$ tags counted (need    1) in "
  998.                                     "template '%s'\n",
  999.                                     template);
  1000.                 }
  1001.                 else
  1002.                         Log (
  1003.                             LOG_ERROR,
  1004.                             "-- Error: Cannot open VLOG  template '%s'\n",
  1005.                             template);
  1006.         }
  1007. }
  1008.