Subversion Repositories Vertical

Rev

Rev 2 | 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.  
  192. #include <stdio.h>
  193. #include <string.h>
  194. #include <stdlib.h>
  195. #include <ctype.h>
  196. #include <time.h>
  197. #include <regex.h>
  198.  
  199. #include "vertcl_main.h"
  200. #include "expression.h"
  201. #include "generic.h"
  202. #include "database.h"
  203. #include "printout.h"
  204. #include "print_vhdl.h"
  205. #include "sorting.h"
  206. #include "cmdparse.h"
  207. #include "cmdlog.h"
  208.  
  209.  
  210. /* ********************************************************************** */
  211.  
  212. /* Decoding pin direction in VLOG */
  213. static char * decode_pin_VLOG[]=
  214. {
  215.   "inout", /* was -NONE- */
  216.   "inout", /* was in */
  217.   "out",
  218.   "out", /* buffer is a sort of Output pin */
  219.   "inout",
  220.   "inout",  /* config is a sort of input pin */
  221.   "inout"}; /* power is a sort of input pin */
  222.  
  223. /* ********************************************************************** */
  224. /* VHDL output of the entities                                            */
  225. /* ********************************************************************** */
  226. static char illegal[]="-+:|/.\\$ ";
  227. static char replace[]="NPCxxxxS_";
  228. char * make_VLOG_name(char * buffer,char * str)
  229. {
  230.   int i,l,j;
  231.  
  232.   l=strlen(str);
  233.   if (isdigit(str[0]))
  234.     {
  235.     l += 1;
  236.     sprintf(buffer,"\%s",str);   /* might as well use the verilog quotation method in this case */
  237.     }
  238.   else
  239.     strcpy(buffer,str);
  240.  
  241.  
  242. /* spot illegal strings in the net name */
  243.   for(i=0;i<l;i++){
  244.     for(j=0;j<sizeof(illegal);j++)
  245.       if (buffer[i]==illegal[j])
  246.         buffer[i]=replace[j];
  247.     }
  248.  
  249.  
  250.   i=l-1;
  251.   /* convert pin indices back from Altera form if we are looking at FIT files */
  252.   if(l){
  253.     /* name ends in underscore, this forces mapping name_nn_ --> name(nn) */
  254.     if(buffer[i] =='_'){
  255.       buffer[i--]=']';
  256.       while(i>=0 && buffer[i] != '_')
  257.         i--;
  258.       if(i>=0)
  259.         buffer[i] = '[';
  260.       }
  261.   }
  262.   return buffer;
  263. }
  264.  
  265. /* ********************************************************************** */
  266. /* decodes the 'vector' part of a bus , if known                           */
  267. int decode_VLOG_bus(FILE * f,vhdl_t * vhdl) {
  268.   if(!vhdl)
  269.      vhdl=default_vhdl_datatype;
  270.  
  271.   if(vhdl->is_vector) {
  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.   while(list) {
  302.     if (list->g_type ==   IS_DECLARATION_DIRECTIVE)
  303.       set_generic_value(&(skt->generics), list) ;
  304.     if (list->g_type ==   IS_INSTANCE_DIRECTIVE)
  305.       set_generic_value(&(skt->generics), list) ;
  306.     list = list->next;
  307.     }
  308.   }
  309.  
  310.  
  311.  
  312.  
  313. /* ********************************************************************** */
  314. /* print out a VLOG component declaration */
  315.  
  316. void print_VLOG_component(FILE * f,socket_t * dev, int All)
  317. {
  318.   node_t * n;
  319.   char printed = 0;
  320.     char nam[MAXIDLEN],typ[MAXIDLEN];
  321.   generic_info_t * g_list= dev->generics;
  322.   make_VLOG_name(typ,check_null_str(dev->type));
  323.  
  324.   fprintf(f,"\nmodule  %s (\n",typ);
  325.  
  326.   /* sort the identifiers of the nodes */
  327.   sort_nodes(dev,NO_EXTRACT_XY);
  328.   n=dev->nodes;
  329.   while(n)
  330.   {
  331.     /* print the pin ID if it is connected to a net and the net is routable */
  332.     if(All || (n->net && n->net->how_routed != Not_Routable )){
  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",
  339.                 make_VLOG_name(nam,nam1));
  340.       }
  341.     n=n->sktnext; /* traverse to next pin on socket */
  342.   };
  343.   fprintf(f," );\n\n");
  344. /* list any declaration directives */
  345.   while(g_list) {
  346.     if (g_list->g_type ==   IS_DECLARATION_DIRECTIVE) {
  347.        if (!g_list->expr || ISNULLSTR(g_list->expr->left.s))
  348.           fprintf(f,"/* synthesis %s */\n",
  349.                   g_list->name);
  350.        else
  351.           fprintf(f,"/* synthesis %s = %s*/\n",
  352.                   g_list->name,
  353.                   check_null_str(g_list->expr->left.s));
  354.        }
  355.     g_list = g_list->next;
  356.     }
  357.  
  358.   n=dev->nodes;
  359.  
  360.   while(n)
  361.   {
  362.     if(dev->is_template || (n->net  && n->net->how_routed != Not_Routable  )){
  363.  
  364.       fprintf(f," %8s %s ",
  365.                 decode_pin_VLOG[(int)n->pindir],
  366.                 make_VLOG_name(nam,check_null_str(n->identifier)));
  367.       decode_VLOG_bus(f,n->vhdltype);
  368.       fprintf(f,";\n");
  369.       }
  370.     n=n->sktnext; /* traverse to next pin on socket */
  371.   };
  372.   fprintf(f,"endmodule\n\n");
  373.  
  374. }
  375.  
  376. /* ********************************************************************** */
  377. /* Printout an instance of a component */
  378. /* ********************************************************************** */
  379. void print_VLOG_instance(FILE * f,socket_t * dev, int All)
  380. {
  381.   node_t * n;
  382.   int need_term = 0;
  383.   char nam[MAXIDLEN],id[MAXIDLEN];
  384.   generic_info_t * g_list= dev->generics;
  385.   make_VLOG_name(nam,check_null_str(dev->type));
  386.   make_VLOG_name(id ,check_null_str(dev->identifier));
  387.  
  388.   fprintf(f,"\n\n/* Component instance */\n");
  389.   fprintf(f,"%s %s ",nam,id);
  390.  
  391.   while(g_list) {
  392.     if (g_list->g_type ==   IS_INSTANCE_DIRECTIVE) {
  393.        if (!g_list->expr || ISNULLSTR(g_list->expr->left.s))
  394.           fprintf(f,"/* synthesis %s */\n",
  395.                   g_list->name);
  396.        else
  397.           fprintf(f,"/* synthesis %s = %s*/\n",
  398.                   g_list->name,
  399.                   check_null_str(g_list->expr->left.s));
  400.        }
  401.     g_list = g_list->next;
  402.     }
  403.  
  404.   fprintf(f,"   (\n");
  405.  
  406.   sort_nodes(dev,NO_EXTRACT_XY);
  407.   n=dev->nodes;
  408.  
  409.  
  410.   while(n)
  411.   {
  412.     char nam1[MAXIDLEN] , nam2[MAXIDLEN];
  413.       /* is there need to add a buffer signal prefix */
  414.  
  415.       if(n->net && n->net->how_routed != Not_Routable  ){
  416.  
  417.         if(need_term)
  418.           fprintf(f,",\n");
  419.         else
  420.           fprintf(f,"\n");
  421.         need_term = 1;  
  422.  
  423.         if(n->net_assigned && n->in_use && !ISNULLSTR(n->identifier) )  {
  424.           fprintf(f,"   .%s(%s",
  425.                  make_VLOG_name(nam1,check_null_str(n->identifier)),
  426.                  make_VLOG_name(nam2,check_null_str(n->net->name))); /* was identifier */
  427.           decode_VLOG_bus(f,n->vhdltype);
  428.           fprintf(f,")");
  429.            }
  430.         else {
  431.         /* No assigned net : pin exists  */
  432.            fprintf(f,"   .%s()",
  433.                  make_VLOG_name(nam1,check_null_str(n->identifier)));
  434.           }
  435.         }
  436.     else {
  437.       if (n->net && n->net->how_routed !=Not_Routable) {
  438.     /* If we are printing comments then dont need a comma next time */
  439.         if(need_term)
  440.           fprintf(f,",\n");
  441.         else
  442.           fprintf(f,"\n");
  443.         need_term = 1;  
  444.         fprintf(f,"   .pin_%s()",
  445.             make_VLOG_name(nam1,check_null_str(n->identifier)));
  446.         }
  447.       }
  448.     n=n->sktnext; /* traverse to next pin on socket */
  449.   };
  450.   fprintf(f,"\n   );\n\n");
  451. }
  452.  
  453. /* ********************************************************************** */
  454.  
  455. void print_VLOG_sigs(FILE * f)
  456. {
  457.   net_t * net = named_list;
  458.   int width = 0;
  459.   char  nam[MAXIDLEN], * sig_prefix;
  460.   while(net){
  461.    if(net->needs_buff_sig)
  462.      sig_prefix = BUFPREFIX;
  463.    else
  464.      sig_prefix = "";
  465.  
  466.  
  467.    if((net->how_routed != Not_Routable) &&
  468.      ((net->bundle_member) || ((net->inside_partition) && net->has_external)) ) { /* May 21 2001 only print nets that connect to 'external' tagged modules */
  469.  /* add to this those in a bundled connection */
  470.       width+= fprintf(f," wire %s%s;",
  471.                  sig_prefix,
  472.                  make_VLOG_name(nam,net->name));
  473.       if (strcmp(nam,net->name)!=0) /* names changed by printout */
  474.          width+= fprintf(f,"/* \"%s\" */",net->name);
  475.       }
  476.     else {
  477.       if(level & 1)
  478.         {
  479.         fprintf(f,"  /* wire %s%s; ",
  480.                  sig_prefix,
  481.                  make_VLOG_name(nam,net->name));
  482.         fprintf(f," */");
  483.         }
  484.       }  
  485.     if (level & 1)
  486.       {  
  487.       fprintf(f," /* partition : %s %s %s %s %s*/\n",
  488.             net->inside_partition?"used in,":"unused in,",
  489.             net->leaves_partition?"leaves,":"buried,",
  490.             net->needs_buff_sig?", buffered,":"",
  491.             net->has_external?"external skt":"internal skt",
  492.             net->bundle_member?"bundle member":" not bundled");
  493.       }
  494.  
  495.     if((level &1) || (width>MAXWIDTH))
  496.       {
  497.       width = 0;
  498.       fprintf(f,"\n  ");
  499.       }
  500.  
  501.  
  502.  
  503.     net=net->next;
  504.   }
  505. }
  506. /* ********************************************************************** */
  507.  
  508. void print_VLOG_assignments(FILE * f)
  509. {
  510.   net_t * net = named_list;
  511.   socket_t * socket = socket_head;
  512.   fprintf(f,"/* Bundle signals */\n\n");
  513.  
  514.   while(socket)
  515.     {
  516.     node_t * nodes = socket->nodes;
  517.     if (socket->highest_bundle  && (socket->bundle_width > MINBUNDLE)) /* will not do assigns on small bundles */
  518.     while(nodes)
  519.       {
  520. /*      if (strcmp("X6",socket->identifier)==0)              */  
  521. /*        {                                                  */
  522. /*        printf("-- X6 index = %d\n",nodes->bundle_index);  */
  523. /*        }                                                  */
  524.       if (nodes->bundle_index >= 0)
  525.         {
  526.         char  nam[MAXIDLEN];
  527.         net_t * net = nodes->net;
  528.         make_VLOG_name(nam,net->name);
  529.         fprintf(f," assign %s[%d] = %s;\n",
  530.                socket->identifier,nodes->bundle_index,nam);
  531.         }
  532.       nodes = nodes->sktnext;
  533.       }
  534. /*    else
  535.       fprintf(f,"-- %s;\n",
  536.                net->name);
  537. */
  538.  
  539.     socket = socket->next;
  540.     }
  541.   fprintf(f,"/* end bundle signals */ \n\n");
  542.  
  543.  
  544. #if defined USE_PREV
  545.   fprintf(f,"/* Bundle signals */\n\n");
  546.  
  547.   while(net)
  548.     {
  549.     if (net->bundle_parent)
  550.       {
  551.       char  nam[MAXIDLEN];
  552.       make_VLOG_name(nam,net->name);
  553.       fprintf(f," assign %s[%d] = %s;\n",
  554.                net->bundle_parent->identifier,net->bundle_index,nam);
  555.  
  556.       }
  557. /*    else
  558.       fprintf(f,"-- %s;\n",
  559.                net->name);
  560. */
  561.  
  562.     net=net->next;
  563.     }
  564.   fprintf(f,"/* end bundle signals */ \n\n");
  565. #endif
  566.  
  567.   net = named_list;
  568.   fprintf(f,"/* Buffered signals */\n\n");
  569.   while(net)
  570.     {
  571.     if(net->inside_partition && net->needs_buff_sig)
  572.       {
  573.       char  nam[MAXIDLEN];
  574.       make_VLOG_name(nam,net->name);
  575.  
  576.       fprintf(f," assign "BUFPREFIX"%s = %s;\n",
  577.                nam,nam);
  578.       }
  579.     net=net->next;
  580.     }
  581.  
  582.   fprintf(f,"/* end Buffered signals */ \n\n");
  583.   }
  584.  
  585. /* ********************************************************************** */
  586.  
  587. void print_VLOG_entity(FILE * f,char * entityname)
  588. {
  589.   net_t * net;
  590.   int need_term = 0;
  591.   int width     = 0;
  592.   socket_t * skt;
  593.   char nam[MAXIDLEN];
  594.  
  595.   fprintf(f,"\nmodule %s ",entityname);
  596.  
  597.  
  598.   fprintf(f,"(\n  ");
  599.  
  600.  
  601.   skt = socket_head;
  602. /* bundles of pins are replaced by signals named the same as a socket which
  603.    they are bundled through , unless the bundles are too small in which case they
  604.    are replaced by separate wires */
  605.   while(skt)
  606.     {
  607.     if(skt->highest_bundle)
  608.       {
  609.       if (skt->bundle_width > MINBUNDLE)
  610.         {
  611.         if(need_term)
  612.           {
  613.           width+= fprintf(f,", ");
  614.           need_term = 0;
  615.           }
  616.         if(width>MAXWIDTH)
  617.           {
  618.           width = 0;
  619.           fprintf(f,"\n  ");
  620.           }
  621.         width+= fprintf(f,"%s",skt->identifier);
  622.         need_term  = 1;
  623.         }
  624.       else
  625. /* if the 'bundle' has less than MINBUNDLE pins, */
  626. /* list out all of the nets in turn as pins      */
  627.         {
  628.         node_t * node;
  629.         node = skt-> nodes;
  630.         while (node)
  631.          {
  632.          net = node->net;
  633. /*
  634.     printf("node %s\n",node->identifier);
  635. */
  636.          if(net && (net->how_routed != Not_Routable) && net->bundle_member)
  637.            {
  638.            if(need_term)
  639.              {
  640.              width+= fprintf(f,", ");
  641.              need_term = 0;
  642.              }
  643.            if(width>60)
  644.              {
  645.              width = 0;
  646.              fprintf(f,"\n  ");
  647.              }
  648.            width+= fprintf(f,"%s",net->identifier);
  649.            need_term = 1;
  650.            }
  651.          node = node->sktnext;
  652.          }
  653.  
  654.         }
  655.       }
  656.    
  657.     skt = skt->next;
  658.     }
  659.  
  660.  
  661.   net = named_list;
  662.  
  663.   while(net){
  664.     /* print out only unbundled nets as ports of the pcb */
  665.     if(net->leaves_partition && !net->bundle_member)
  666.       {
  667.       if(need_term)
  668.         {
  669.         width+= fprintf(f,", ");
  670.         }
  671.        if(width>MAXWIDTH)
  672.         {
  673.         width = 0;
  674.         fprintf(f,"\n  ");
  675.         }
  676.         width+= fprintf(f," %s",
  677.                make_VLOG_name(nam,net->name));
  678. /*        width+= decode_VLOG_bus(f,net->vhdltype); Not used in verilog */
  679.       if (strcmp(nam,net->name)!=0) /* names changed by printout */
  680.         width+=fprintf(f," /* \"%s\" */",net->name);
  681.          
  682.       need_term = 1;
  683.       }
  684.     net=net->next;
  685.  
  686.     }
  687. /* terminate port list */
  688.   fprintf(f,");\n");  
  689.  
  690.   fprintf(f,"/* synthesis syn_partition = \"board\" */ \n\n");
  691.  
  692.   need_term = 0;
  693.   skt = socket_head;
  694.  
  695.  
  696. /* now write out the verilog types of ll of the ports*/
  697.  
  698.   while(skt)
  699.     {
  700.     if(skt->highest_bundle)
  701.       {
  702. /* big bundles are listed as a single item */
  703.       if (skt->bundle_width > MINBUNDLE)
  704.         {
  705.         fprintf(f,"  inout [%d:%d] %s; // row(%d:%d) col(%d:%d) \n",skt->highest_bundle,skt->lowest_bundle,skt->identifier,
  706.               skt->min_pin_row, skt->max_pin_row,
  707.               skt->min_pin_col,  skt->max_pin_col);
  708.         }
  709.       else
  710. /* small bundles are enumerated as induvidual wires */
  711.         {
  712.         node_t * node;
  713.         node = skt-> nodes;
  714.         while (node)
  715.           {
  716.           net = node->net;
  717. /*
  718.     printf("node %s\n",node->identifier);
  719. */
  720.           if(net && net->bundle_member)
  721.             {
  722.             fprintf(f,"  %s ",
  723.               decode_pin_VLOG[net->ext_dir]);
  724.               decode_VLOG_bus(f,net->vhdltype);
  725.               fprintf(f," %s;\n",
  726.                make_VLOG_name(nam,net->name));
  727.             }
  728.          node = node->sktnext;
  729.          }
  730.         }
  731.       }
  732.      
  733.     skt = skt->next;
  734.     }
  735.  
  736.   net = named_list;
  737.  
  738.   while(net){
  739.     char nam[MAXIDLEN];
  740.     if(net->leaves_partition && !net->bundle_member){
  741.       fprintf(f,"  %s ",
  742.                decode_pin_VLOG[net->ext_dir]);
  743.       decode_VLOG_bus(f,net->vhdltype);
  744.       fprintf(f," %s;\n",
  745.                make_VLOG_name(nam,net->identifier));
  746.       }
  747.     net=net->next;
  748.  
  749.     }
  750.   fprintf(f,"\n");
  751.  
  752.   }
  753.  
  754.  
  755. /* ********************************************************************** */
  756. /* generate default VLOG Libraries */
  757. /* ********************************************************************** */
  758. void print_VLOG_libs(FILE * f)
  759. {
  760.   fprintf(f,"/* Default text */\n\n");
  761. }
  762.  
  763. /* **********************************************************************
  764.  * clear verilog 'type seen' flags (providing a single declaration for all
  765.  * instances of a given type
  766.  * **********************************************************************
  767.  * Using this as a means to avoid duplicate components: only print those
  768.  * not seen before */
  769.  
  770. void clr_type_seen(void) {
  771.   socket_t * skt;
  772.   skt = template_head;
  773.   while(skt){
  774.     skt->socket_type_seen = 0;
  775.     skt = skt->next;
  776.     }
  777.  }
  778. /* **********************************************************************
  779.  * set verilog 'type seen' flags  for all instances of a given type
  780.  * ********************************************************************** */
  781. void set_type_seen(char * type) {
  782.   socket_t * skt;
  783.   skt = socket_head;
  784.   while(skt){
  785.     if(strcmp(type,skt->type)==0)
  786.        skt->socket_type_seen = 1;
  787.     skt = skt->next;
  788.     }
  789.  }
  790.  
  791. /* ********************************************************************** */
  792. /* declare all used modules (once !!)  */
  793. /* ********************************************************************** */
  794. /* to do: fix up a generic giving an alternative verilog line for the
  795.    FPGA declaration case eg 'include something.v
  796.  
  797. Need to
  798.    bundle a socket then del external it for port bundling
  799.  
  800. */
  801.  
  802. void print_VLOG_declarations(FILE * f,char * entityname) {
  803.   socket_t * skt;
  804.   skt = socket_head;
  805.   clr_type_seen();
  806.  
  807.   skt = socket_head;
  808.   /* list out templates for those sockets selected, and which have not been
  809.      converted into a bundle */
  810.     while(skt){
  811.     if(skt->is_external && skt->highest_bundle==0 ) {
  812.   /* suppress printout of duplicate components .... */
  813.       if(skt->template_socket)
  814.         {
  815.         if( skt->template_socket->socket_type_seen == 0)
  816.           {
  817.           if (!skt->is_FPGA)
  818.             { /* only printout component decls for non-FPGA: Certify
  819.              has its own private store of these declarations
  820.              and it is fiddly to match these exactly. */
  821.             fprintf(f,"\n// defined by component template\n");
  822.             print_VLOG_component(f,skt->template_socket,1);
  823.             }
  824.           else
  825.             {
  826.             generic_info_t * info = get_generic_ref(&skt->generics,"fpga_file");
  827.             fprintf(f,"\n/* socket '%s' is an FPGA: component declaration skipped */\n",skt->identifier);
  828.             if(info && info->g_type == IS_ATTRIBUTE)
  829.               {
  830.               fprintf(f,"/* replacement for declaration */\n%s\n",
  831.               info->expr->left.s?info->expr->left.s:"");
  832.               }
  833.             }
  834.           skt->template_socket->socket_type_seen = 1;
  835.           }
  836.         }
  837.       else
  838.         {
  839.         /* no components, use socket/entity as its own component */
  840.         if (!skt->is_FPGA)
  841.           {
  842.           print_VLOG_component(f,skt,1);
  843.           }
  844.         else
  845.           {
  846.           generic_info_t * info = get_generic_ref(&skt->generics,"fpga_file");
  847.           fprintf(f,"\n/* socket '%s' is an FPGA: socket declaration skipped */\n",skt->identifier);
  848.           if(info && info->g_type == IS_ATTRIBUTE)
  849.             {
  850.             fprintf(f,"/* replacement for declaration */\n%s\n",
  851.             info->expr->left.s?info->expr->left.s:"");
  852.             }
  853.           }
  854.         }
  855.       }
  856.     skt = skt->next;
  857.     }
  858.  
  859.   }
  860.  
  861. /* ********************************************************************** */
  862. /* generate a VLOG architecture  */
  863. /* ********************************************************************** */
  864.  
  865.  
  866. void print_VLOG_architecture(FILE * f,char * entityname) {
  867.  
  868.   socket_t * skt;
  869.   print_VLOG_entity(f,entityname);
  870.  
  871.   print_VLOG_sigs(f);
  872.  
  873.   skt = socket_head;
  874.   while(skt){
  875.     if(skt->is_external && skt->highest_bundle == 0)
  876.        print_VLOG_instance(f,skt,0);
  877.     skt = skt->next;
  878.   }
  879.   print_VLOG_assignments(f);
  880.   fprintf(f,"endmodule\n\n");
  881.   }
  882.  
  883. /* ********************************************************************** */
  884. /* generate a VLOG file */
  885. /* ********************************************************************** */
  886.  
  887. void produce_VLOG(FILE * f,char * entityname,char *template) {
  888.   char linebuff[256];
  889.   int done_architecture=0,done_declarations=0;
  890.   if(!template || !template[0]) { /* check null pointer or empty string */
  891.     fprintf(f,"// vertical verilog\n");
  892.     print_VLOG_header(f,"WRITE VLOG");
  893.     print_VLOG_declarations(f,entityname);
  894.     print_VLOG_architecture(f,entityname);
  895.     fprintf(f,"\n// vertical end;\n");
  896.     }
  897.   else { /* there is a template file */
  898.     FILE * tp;
  899.     tp=fopen(template,"r");
  900.     if(tp) {
  901.    
  902.       fprintf(f,"// vertical verilog\n");
  903.       print_VLOG_header(f,"WRITE VLOG");
  904.       fprintf(f,"/* Using template  '%s' */\n",template);
  905.       while(!feof(tp)){
  906.         if(fgets(linebuff,256,tp)) {
  907.           if(strstr(linebuff,"$DECL$")) {
  908.             print_VLOG_declarations(f,entityname);
  909.             done_declarations++;
  910.             }
  911.  
  912.           else if (strstr(linebuff,"$ARCH$")){
  913.             print_VLOG_architecture(f,entityname);
  914.             done_architecture++;
  915.             }
  916.           else
  917.             fprintf(f,"%s",linebuff); /* it already has a '\n' on the end */
  918.           }
  919.         }
  920.       fprintf(f,"\n// vertical end;\n");
  921.       fclose(tp);
  922.       if(done_declarations!=1)
  923.         Log(LOG_ERROR,"-- Error: %d  $DECL$ tags counted (need  1) in template '%s'\n",template);
  924.       if(done_architecture!=1)
  925.         Log(LOG_ERROR,"-- Error: %d  $ARCH$ tags counted (need  1) in template '%s'\n",template);
  926.        
  927.       }
  928.     else
  929.       Log(LOG_ERROR,"-- Error: Cannot open VLOG  template '%s'\n",template);
  930.      
  931.     }
  932.   }
  933.        
  934.  
  935.  
  936.  
  937.