gnetlist

mk_verilog_syms.c

Go to the documentation of this file.
00001 /*  mk_verilog_syms.c: 
00002  *
00003  *  Create a set of n-input gate symbols for the geda verilog netlister.
00004  *
00005  *  symbols created:  and[2-9], nand[2-9], nor[2-9], or[2-9], nor[2-9],
00006  *  xor[2-9], xnor[2-9].
00007  *
00008  * Copyright (C) 1999-2010 Mike Jarabek
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00023  * MA 02111-1301 USA.
00024  *
00025  */
00026 
00027 #ifdef HAVE_CONFIG_H
00028 #include "config.h"
00029 #endif
00030 
00031 #include <stdio.h>
00032 #include <math.h>
00033 
00034 #ifdef HAVE_LIBDMALLOC
00035 #include <dmalloc.h>
00036 #endif
00037 
00038 /* local defines */
00039 
00040 /* gEDA colour, these should probably come from somewhere else */
00041 #define BLACK       0
00042 #define WHITE       1
00043 #define RED     2
00044 #define GREEN       3
00045 #define BLUE        4
00046 #define YELLOW      5
00047 #define CYAN        6
00048 #define GREY        7
00049 
00050 /* external prototypes */
00051 int GetStringDisplayLength(char *str,int font_size);  /* char_width.c */
00052 
00053 
00054 
00055 /* local prototypes */
00056 int MakeSymbol(FILE *fp, unsigned int pins, int inputBubbles, 
00057            int outputBubbles,
00058            int (*body)(FILE *, int, int, unsigned int, unsigned int));
00059 
00060 int AndBody(FILE *fp, int x, int y, unsigned int pins, unsigned int colour);
00061 int OrBody(FILE *fp, int x, int y, unsigned int pins, unsigned int colour);
00062 int XorBody(FILE *fp, int x, int y, unsigned int pins, unsigned int colour);
00063 int Pin(FILE *fp, int x1, int y1, int x2, int y2, int bubble);
00064 int PinAttribute(FILE *fp, int x, int y, unsigned int n, char *value); 
00065 int WidenBody(FILE *fp, int x, int y, unsigned int pins, unsigned int colour);
00066 
00067 /* globals */
00068 unsigned int PinSpacing = 200;
00069 unsigned int PinLength  = 300;
00070 
00071 struct Table
00072 {
00073   char         *name;     /* base name of part */
00074   unsigned int suffix;    /* suffix for part, 1 for normal, 2 for deMorgan.. */
00075   int (*body)(FILE *, int, int, unsigned int, unsigned int);  /* body style */
00076   int          inputBubbles;  /* where to draw bubbles */
00077   int          outputBubbles;
00078 };
00079 
00080 
00081 struct Table generate[] = {
00082   {"and",  1, AndBody, 0, 0},
00083   {"and",  2, OrBody,  1, 1},
00084   {"nand", 1, AndBody, 0, 1},
00085   {"nand", 2, OrBody,  1, 0},
00086   {"or",   1, OrBody,  0, 0},
00087   {"or",   2, AndBody, 1, 1},
00088   {"nor",  1, OrBody,  0, 1},
00089   {"nor",  2, AndBody, 1, 0},
00090   {"xor",  1, XorBody, 0, 0},
00091   {"xnor", 1, XorBody, 0, 1}
00092 };
00093 
00094 unsigned int nGenerate = sizeof(generate)/sizeof(struct Table);
00095 
00096 int
00097 main(int argc, char **argv)
00098 {
00099   int i,j;
00100   int rc;
00101   char name[127];
00102 
00103   FILE *fp;
00104 
00105   printf("Making verilog symbols\n");
00106 
00107   for(i=0; i<nGenerate; i++) /* loop over table entries */
00108     for(j=2; j<10; j++)      /* loop over number of pins */
00109       {
00110     /* build file name */
00111     sprintf(name, "sym/%s%u-%u.sym",
00112         generate[i].name, j, generate[i].suffix);
00113     printf("Working on:%s\n",name);
00114     fp = fopen(name, "wb");
00115     if(fp == NULL)
00116       {
00117         fprintf(stderr,"Error: Unable to create file `%s' in %s()\n",
00118             name, __func__);
00119         return 1;
00120       }
00121 
00122     rc = MakeSymbol(fp, j, 
00123             generate[i].inputBubbles, generate[i].outputBubbles,
00124             generate[i].body);
00125     if(rc)
00126       {
00127         fprintf(stderr,"Error: Symbol creation failed in %s()\n",
00128             __func__);
00129         return 1;
00130       }
00131 
00132     /* and finally add the device attribute */
00133     fprintf(fp,"T 400 100 5 8 0 0 0 0\ndevice=%s\n",generate[i].name);
00134     /* and the positional pin directive */
00135     fprintf(fp,"T 400 200 5 8 0 0 0 0\nVERILOG_PORTS=POSITIONAL");
00136     fclose(fp);
00137       }
00138 
00139   return 0;
00140 }
00141 
00142 /* output a complete symbol having the desired body
00143  * and requested number of pins.  Draw bubbles on the input and/or
00144  * output pins.
00145  */
00146 int
00147 MakeSymbol(FILE *fp, unsigned int pins, int inputBubbles, int outputBubbles,
00148        int (*body)(FILE *, int, int, unsigned int, unsigned int))
00149 {
00150   unsigned int i;
00151   int rc;
00152 
00153   int bodyx, bodyy;       /* origin of body */
00154   int outputx, outputy;   /* origin of output pin */
00155   int firstx, firsty;     /* first end of first input pin */
00156   int totalHeight;
00157 
00158   int pinx, piny;
00159 
00160   int bodyWidth  = 700;
00161   int bodyHeight = 600;
00162   unsigned int pinCount = 1;
00163 
00164   char pinName[20];       /* temp for pinnname */
00165 
00166   if(fp == NULL)
00167     {
00168       fprintf(stderr, "Error: NULL file pointer passed to %s()\n",
00169           __func__);
00170       return 1;
00171     }
00172 
00173   if(body == NULL)
00174     {
00175       fprintf(stderr, "Error: NULL body drawing function pointer passed "
00176           "to %s()\n",
00177           __func__);
00178       return 1;
00179     }
00180 
00181   /* do special pin spacing for 2 pins */
00182   if(pins == 2)
00183     PinSpacing = 400;
00184   else
00185     PinSpacing = 200;
00186 
00187 
00188   /* first, compute locations needed */
00189   totalHeight = bodyHeight;
00190   if(pins >= 3) /* do we need to add to the height ? */
00191     totalHeight += (pins-3) * PinSpacing;
00192 
00193   
00194   bodyx = PinLength;
00195   bodyy = totalHeight/2;
00196 
00197   outputx = bodyx+bodyWidth;
00198   outputy = bodyy;
00199 
00200   firstx  = PinLength;
00201   firsty  = 100;
00202 
00203   /* draw the body */
00204   rc = (*body)(fp, bodyx, bodyy, pins, GREEN);
00205   if(rc)
00206     {
00207       fprintf(stderr, "Error: Body function failed in %s()\n",
00208           __func__);
00209       return 1;
00210     }
00211 
00212   /* draw the pins and attach appropriate attributes */
00213   rc = Pin(fp, outputx, outputy, outputx+PinLength, outputy, outputBubbles);
00214   if(rc)
00215     {
00216       fprintf(stderr, "Error: Pin drawing function failed in %s() "
00217           "for output pin\n",
00218           __func__);
00219       return 1;
00220     }
00221   /* attach pin attribute */
00222   rc = PinAttribute(fp, outputx, outputy, pinCount++, "OUT"); 
00223   if(rc)
00224     {
00225       fprintf(stderr, "Error: Pin Attribute function failed for output pin "
00226           "in %s()\n",__func__);
00227       return 1;
00228     }
00229 
00230   /* do input pins */
00231   for(i=0; i<pins; i++)
00232     {
00233       /* calculate the position of the pin */
00234       pinx = firstx;
00235       piny = firsty+i*PinSpacing;
00236       /* output a pin */
00237       rc = Pin(fp, pinx, piny, pinx-PinLength, piny, inputBubbles);
00238       if(rc)
00239     {
00240       fprintf(stderr,"Error: Pin drawing function failed for pin %u "
00241           "in %s()\n",
00242           i, __func__);
00243       return 1;
00244     }
00245       /* output the attributes */
00246       sprintf(pinName,"IN%u",i);
00247       rc = PinAttribute(fp, pinx, piny, pinCount++, pinName);
00248       if(rc)
00249     {
00250       fprintf(stderr,"Error: Pin Attributes function failed for pin %u "
00251           "in %s()\n", i, __func__);
00252       return 1;
00253     }
00254 
00255     }
00256 
00257 
00258   /* drop on a template uref attribute */
00259   fprintf(fp,"T %d %d 5 10 1 1 0 2\nrefdes=U?\n",
00260       bodyx+100,
00261       bodyy-400);
00262 
00263 
00264   return 0;
00265 }
00266 
00267 
00268 
00269 
00270 /* produce an and shaped body at the given offset.
00271  * The origin is along the horizontal midline of the shape.
00272  */
00273 int 
00274 AndBody(FILE *fp, int x, int y, unsigned int pins, unsigned int colour)
00275 {
00276 
00277   if(fp == NULL)
00278     {
00279       fprintf(stderr, "Error: NULL file pointer passed to %s()\n",
00280           __func__);
00281       return 1;
00282     }
00283 
00284   /* top and bottom lines */
00285   fprintf(fp, "L %d %d %d %d %u\n",
00286       x, y+300, x+400, y+300, colour); 
00287   fprintf(fp, "L %d %d %d %d %u\n",
00288       x, y-300, x+400, y-300, colour);
00289  
00290   /* left line */
00291   fprintf(fp, "L %d %d %d %d %u\n",
00292       x, y-300, x, y+300, colour);
00293 
00294   /* arc at right */
00295   fprintf(fp, "A %d %d %d %d %d %u\n",
00296       x+400, y, 300, -90, 180, colour);
00297 
00298   return WidenBody(fp, x, y, pins, colour);
00299 }
00300 
00301 /* produce a or shaped body at the given offset.
00302  * The origin is along the horizontal midline of the shape.
00303  */
00304 int OrBody(FILE *fp, int x, int y, unsigned int pins, unsigned int colour)
00305 {
00306   if(fp == NULL)
00307     {
00308       fprintf(stderr, "Error: NULL file pointer passed to %s()\n",
00309           __func__);
00310       return 1;
00311     }
00312 
00313   /* top and bottom lines */
00314   fprintf(fp, "L %d %d %d %d %u\n",
00315       x, y+300, x+300, y+300, colour);
00316   fprintf(fp, "L %d %d %d %d %u\n",
00317       x, y-300, x+300, y-300, colour);
00318 
00319   /* left arc */
00320   fprintf(fp, "A %d %d %d %d %d %u\n",
00321       x-260, y, 400, -48, 97, colour); 
00322 
00323   /* right top and bottom arcs */
00324   fprintf(fp, "A %d %d %d %d %d %u\n",
00325       x+300, y+100, 400, 270, 76, colour); 
00326   fprintf(fp, "A %d %d %d %d %d %u\n",
00327       x+300, y-100, 400, 90, -76, colour);
00328  
00329   return WidenBody(fp, x, y, pins, colour);
00330 }
00331 
00332 /* produce a xor shaped body at the given offset.
00333  * The origin is along the horizontal midline of the shape.
00334  */
00335 int XorBody(FILE *fp, int x, int y, unsigned int pins, unsigned int colour)
00336 {
00337   if(fp == NULL)
00338     {
00339       fprintf(stderr, "Error: NULL file pointer passed to %s()\n",
00340           __func__);
00341       return 1;
00342     }
00343 
00344   /* top and bottom lines */
00345   fprintf(fp, "L %d %d %d %d %u\n",
00346       x+100, y+300, x+300, y+300, colour);
00347   fprintf(fp, "L %d %d %d %d %u\n",
00348       x+100, y-300, x+300, y-300, colour);
00349 
00350   /* left arc 1 */
00351   fprintf(fp, "A %d %d %d %d %d %u\n",
00352       x-260, y, 400, -48, 97, colour);  
00353  /* left arc 2 */
00354   fprintf(fp, "A %d %d %d %d %d %u\n",
00355       x-160, y, 400, -48, 97, colour); 
00356   
00357 
00358   /* right top and bottom arcs */
00359   fprintf(fp, "A %d %d %d %d %d %u\n",
00360       x+300, y+100, 400, 270, 76, colour); 
00361   fprintf(fp, "A %d %d %d %d %d %u\n",
00362       x+300, y-100, 400, 90, -76, colour); 
00363 
00364   return WidenBody(fp, x, y, pins, colour);
00365 }
00366 
00367 
00368 /* output two line segments that will serve to `widen' the
00369  * body of one of the above gates
00370  */
00371 int 
00372 WidenBody(FILE *fp, int x, int y, unsigned int pins, unsigned int colour)
00373 {
00374   unsigned int distanceNeeded;
00375 
00376   if(fp == NULL)
00377     {
00378       fprintf(stderr, "Error: NULL file pointer passed to %s()\n",
00379           __func__);
00380       return 1;
00381     }
00382 
00383   /* only need to do work if the number of pins > 2 */
00384   if(pins <= 3)
00385     return 0;
00386 
00387 
00388   /* Compute the amount needed to add to both top and bottom */
00389   distanceNeeded = (pins-3) * PinSpacing/2;
00390 
00391   /* output the line segments */
00392   /* for the top */
00393   fprintf(fp, "L %d %d %d %d %u\n",
00394       x, y+300, x, y+300+distanceNeeded, colour);
00395   /* for the bottom */
00396   fprintf(fp, "L %d %d %d %d %u\n",
00397       x, y-300, x, y-300-distanceNeeded, colour);
00398 
00399   return 0;
00400 }
00401 
00402 
00403 /* Draw a pin, optionally with a bubble
00404  */
00405 int 
00406 Pin(FILE *fp, int x1, int y1, int x2, int y2, int bubble) 
00407 {
00408   int bx, by;              /* bubble x and y locations */
00409   int px1, py1, px2, py2;  /* pin x and y locations */
00410   int dx, dy;
00411   int br = 50;             /* bubble radius */
00412 
00413   double x,y;              /* unit vector in direction of line */
00414   double denom;
00415 
00416   if(fp == NULL)
00417     {
00418       fprintf(stderr, "Error: NULL file pointer passed to %s()\n",
00419           __func__);
00420       return 1;
00421     }
00422 
00423   /* figure where pin ends are */
00424   if(bubble) /* is there a bubble? */
00425     { /* yes there is a bubble */
00426 
00427       /* compute a unit vector */
00428       dx = x2-x1;
00429       dy = y2-y1;
00430       denom = sqrt( dx*dx + dy*dy);
00431       if(denom < 1e-6)
00432     {
00433       fprintf(stderr, "Error: Length of pin too small in %s()\n",
00434           __func__);
00435       return 1;
00436     }
00437       
00438       x = dx / denom;
00439       y = dy / denom;
00440 
00441       /* figure center of bubble */
00442       bx = x1 + x * br;
00443       by = y1 + y * br;
00444 
00445       /* figure location of first line end */
00446       px1 = x1 + x * 2 * br;
00447       py1 = y1 + y * 2 * br;
00448       
00449       px2 = x2;
00450       py2 = y2;
00451       
00452 
00453       /* draw the bubble */
00454       fprintf(fp, "V %d %d %d %d\n",
00455           (int) bx, (int) by, br, CYAN);
00456 
00457     }
00458   else
00459     { /* no bubble, nothing special to do */
00460 
00461       px1 = x1; py1 = y1;
00462       px2 = x2; py2 = y2;
00463 
00464     }
00465 
00466   /* draw the pin */
00467   fprintf(fp, "P %d %d %d %d %d\n",
00468       px1, py1, px2, py2, WHITE);
00469 
00470   return 0;
00471 }
00472 
00473 int 
00474 PinAttribute(FILE *fp, int x, int y, unsigned int n, char *value) 
00475 {
00476   if(fp == NULL)
00477     {
00478       fprintf(stderr, "Error: NULL file pointer passed to %s()\n",
00479           __func__);
00480       return 1;
00481     }
00482   
00483   if(value == NULL)
00484     {
00485       fprintf(stderr, "Error: NULL value pointer passed to %s()\n",
00486           __func__);
00487       return 1;
00488     }
00489 
00490   fprintf(fp, "{\n");
00491   fprintf(fp, "T %d %d %u %u 0 0 0 0\n",x, y, YELLOW, 8);
00492   fprintf(fp, "pin%u=%s\n",n, value);
00493   fprintf(fp, "}\n");
00494   
00495   return 0;
00496 }
 All Data Structures Files Functions Variables Defines