1 /*
2 * This file is part of the Alliance CAD System
3 * Copyright (C) Laboratoire LIP6 - D�partement ASIM
4 * Universite Pierre et Marie Curie
5 *
6 * Home page : http://www-asim.lip6.fr/alliance/
7 * E-mail : mailto:alliance-users@asim.lip6.fr
8 *
9 * This library is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Library General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * Alliance VLSI CAD System is distributed in the hope that it will be
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with the GNU C Library; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24 /*
25 * Purpose : verilog driver, mainly used to enable simulating with Cadence Verilog.
26 * Version : 002
27 * Date : Jul 1995
28 * Author : Aldo Mozzi <aldo.mozzi@libero.it>
29 * Modified by Mourad Aberbour in Sept. 1997
30 */
31
32 #ident "$Id: drive_vlog.c,v 1.3 2012/05/14 14:20:26 alliance Exp $"
33
34 #include <mut.h>
35 #include <mlo.h>
36 #include <stdlib.h>
37 #include <ctype.h>
38 #include <time.h>
39 #include <string.h>
40
41 extern char *mvl_vhdlname(); /*see ../mbkvhdl/mbkvhdl/mvl_drive.h*/
42
43 static char name_buffer[255];
44 static char vec_name_buffer[255];
45
46 /******************************************************************
47 * function vlg_name: gets a name and returns a legal verilog name *
48 * in name_buffer. Characteres not allowed in a valid verilog name *
49 * are replaced by "_"<ascii code in hex>"_". *
50 * If the name is indexed the indexing syntax is translated: *
51 * <name><space><number> --> <name>[<number>] *
52 ******************************************************************/
vlg_name(name)53 char *vlg_name (name)
54 char *name;
55 {
56 char *scan_new;
57 int i, indexed;
58 static char hextable[] = "0123456789ABCDEF";
59 #ifdef mark_in_out
60 printf ("entering vlg_name %s\n", name);
61 #endif
62 scan_new = name_buffer;
63 i = 0;
64 indexed = 0;
65 while (*name)
66 {
67 if (i != 0 && *name == ' ')
68 {
69 *scan_new++ = '[';
70 indexed = 1;
71 name++;
72 }
73 else
74 {
75 if (isalpha(*name) || *name == '_' || (((i != 0) && (isdigit(*name))) || *name == '$'))
76 {
77 *scan_new = *name++;
78 /* modif mourad : le 03/12/97
79 Le driver verilog pour les netlists alliance doit garder les noms de models et des coneecteurs
80 en minuscule pour une compatibilite avec les cellules ScLib et PadLib exportees vers Cadence.
81 Les noms de signaux et d'instances peuvent rester tel quel.
82
83 if (islower(*scan_new)) *scan_new = toupper(*scan_new);
84 ----*/
85 if (isupper(*scan_new)) *scan_new = tolower(*scan_new);
86 scan_new++;
87 }
88 else
89 {
90 *scan_new++ = '_';
91 *scan_new++ = hextable[(*name >> 4) & 0x0f];
92 *scan_new++ = hextable[*name++ & 0x0f];
93 *scan_new++ = '_';
94 }
95 }
96 ++i;
97 }
98 if (indexed != 0) *scan_new++ = ']';
99 *scan_new = '\0';
100
101 #ifdef mark_in_out
102 printf ("exiting vlg_name %s\n", name_buffer);
103 #endif
104
105 return (name_buffer);
106 }
107
108
109 /***************************************************************************
110 * function vlg_busname: gets a pointer to a list of connectors and returns *
111 * the next connector name in *name (that points to vec_buffer), the left *
112 * and right indices of the vector (-1 if signal is a scalar) and the *
113 * pointer to the next vector as the return value. Performs vectorization *
114 * of locon names, that are always scalar. *
115 ***************************************************************************/
vlg_busname(pt_list,left,right,name)116 locon_list *vlg_busname(pt_list,left,right,name)
117 locon_list *pt_list;
118 int *left, *right;
119 char **name;
120 {
121 char *blank_space;
122 locon_list *ptcon;
123 char END = 0;
124
125 #ifdef mark_in_out
126 printf("entering vlg_busname %s\n", pt_list->NAME);
127 #endif
128
129 ptcon = pt_list;
130 /* Extract the name and number of an element */
131 *left = *right = -1;
132 strcpy(vec_name_buffer, ptcon->NAME);
133 blank_space = strchr(vec_name_buffer, ' ');
134 if (blank_space != NULL)
135 {
136 *right = atoi(blank_space);
137 *left = *right;
138 *blank_space = '\0';
139
140 while(END != 1)
141 {
142 if(ptcon->NEXT != NULL)
143 {
144 blank_space = strchr(ptcon->NEXT->NAME, ' ');
145 if(blank_space != NULL)
146 {
147 *blank_space = '\0';
148 if(!strcmp(vec_name_buffer, ptcon->NEXT->NAME))
149 {
150 *right = atoi(blank_space + 1);
151 ptcon = ptcon->NEXT;
152 }
153 else END = 1;
154 *blank_space = ' ';
155 }
156 else END = 1;
157 }
158 else END = 1;
159 }
160 }
161 *name = vec_name_buffer;
162
163 #ifdef mark_in_out
164 printf("exiting vlg_busname %s\n", *name);
165 #endif
166
167 return(ptcon->NEXT);
168 }
169
170
171 /*******************************************************************************
172 * function vlogsavelofig *
173 *******************************************************************************/
174
vlogsavelofig(ptfig)175 void vlogsavelofig(ptfig)
176 lofig_list *ptfig;
177 {
178 loins_list *ptins = NULL;
179 locon_list *ptcon = NULL;
180 locon_list *ptscan = NULL;
181 losig_list *ptsig = NULL;
182 FILE *ptfile;
183 time_t clock;
184 int flag, left, right, i, first;
185 char *name;
186 char *sig_name;
187 char direc_flag;
188 chain_list *sig_list = NULL;
189
190 #ifdef mark_in_out
191 printf("entering vlogsavelofig\n");
192 #endif
193
194 if ((ptfile = mbkfopen(ptfig->NAME, OUT_LO, WRITE_TEXT)) == NULL)
195 {
196 (void)fprintf(stderr, "*** mbk error ***\n");
197 (void)fprintf(stderr, "cannot open file %s.%s\n", ptfig->NAME, OUT_LO);
198 EXIT(1);
199 }
200
201 time (&clock);
202 (void) fprintf (ptfile,"// Verilog structural description generated from `%s`\n", ptfig->NAME);
203 (void) fprintf (ptfile,"// Date : %s\n\n", ctime(&clock));
204
205 /*********************
206 * Module declaration *
207 *********************/
208 (void) fprintf (ptfile,"// Module Declaration.\n\n");
209 (void) fprintf (ptfile,"module %s (\n", vlg_name(ptfig->NAME));
210
211 if (ptfig->LOCON != NULL) {
212 ptfig->LOCON = (struct locon *) reverse ((chain_list *)ptfig->LOCON);
213 /*list inputs without indices first*/
214 ptcon = ptfig->LOCON;
215 flag = 0;
216 while (ptcon != NULL)
217 {
218 if (ptcon->DIRECTION == 'I')
219 {
220 ptcon = vlg_busname(ptcon,&left,&right,&name);
221 /*
222 printf("list input %s\n", name);
223 */
224 if (flag == 4)
225 {
226 (void)fprintf(ptfile, ",\n");
227 flag = 0;
228 }
229 if (flag != 0)
230 (void)fprintf(ptfile, ", ");
231 (void)fprintf(ptfile, "%s", vlg_name(name));
232 ++flag;
233 }
234 else ptcon = ptcon->NEXT;
235 }
236 /*then list I/Os*/
237 ptcon = ptfig->LOCON;
238 while (ptcon != NULL)
239 {
240 direc_flag = ptcon->DIRECTION;
241 if ((direc_flag != 'I') && (direc_flag != 'O') && (direc_flag != 'B'))
242 {
243 ptcon = vlg_busname(ptcon,&left,&right,&name);
244 /*
245 printf("list input-output %s %c\n", name, direc_flag);
246 */
247 if (flag == 4)
248 {
249 (void)fprintf(ptfile, ",\n");
250 flag = 0;
251 }
252 if (flag != 0)
253 (void)fprintf(ptfile, ", ");
254 (void)fprintf(ptfile, "%s", vlg_name(name));
255 ++flag;
256 }
257 else ptcon = ptcon->NEXT;
258 }
259 /*then list outputs*/
260 ptcon = ptfig->LOCON;
261 while (ptcon != NULL)
262 {
263 direc_flag = ptcon->DIRECTION;
264 if ((direc_flag == 'O') || (direc_flag == 'B'))
265 {
266 ptcon = vlg_busname(ptcon,&left,&right,&name);
267 /*
268 printf("list output %s\n", name);
269 */
270 if (flag == 4)
271 {
272 (void)fprintf(ptfile, ",\n");
273 flag = 0;
274 }
275 if (flag != 0)
276 (void)fprintf(ptfile, ", ");
277 (void)fprintf(ptfile, "%s", vlg_name(name));
278 ++flag;
279 }
280 else ptcon = ptcon->NEXT;
281 }
282 (void) fprintf(ptfile, ");\n\n\n");
283
284 (void) fprintf (ptfile,"// Declaration of external signals.\n\n");
285 /*now list inputs and outputs with indices; bidirs are both listed as
286 inputs and outputs*/
287 ptcon = ptfig->LOCON;
288 while (ptcon != NULL)
289 {
290 direc_flag = ptcon->DIRECTION;
291 ptcon = vlg_busname(ptcon, &left, &right, &name);
292 if ((direc_flag != 'O') && (direc_flag != 'B'))
293 {
294 if (left != -1)
295 (void)fprintf(ptfile, "input [%d:%d] %s;\n", left, right, vlg_name(name));
296 else
297 (void)fprintf(ptfile, "input %s;\n", vlg_name(name));
298 }
299 if (direc_flag != 'I')
300 {
301 if (left != -1)
302 (void)fprintf(ptfile, "output [%d:%d] %s;\n", left, right, vlg_name(name));
303 else
304 (void)fprintf(ptfile, "output %s;\n", vlg_name(name));
305 }
306 }
307 }
308 (void) fprintf(ptfile, "\n\n");
309
310 ptfig->LOCON = (struct locon *) reverse ((chain_list *)ptfig->LOCON);
311
312 /***********************************************************
313 * End of module declarations, now declare internal signals *
314 ***********************************************************/
315
316 (void) fprintf(ptfile, "// Declaration of internal signals.\n\n");
317 ptsig = ptfig->LOSIG;
318 while(ptsig != NULL)
319 {
320 if (ptsig->TYPE == 'I')
321 {
322 (void) fprintf (ptfile, "wire %s;\n", vlg_name(getsigname(ptsig)));
323 }
324 ptsig = ptsig->NEXT;
325 }
326
327 /*********************************************************
328 * End of signal declarations, now comes the real netlist *
329 *********************************************************/
330
331 (void) fprintf(ptfile, "\n\n// Declaration of instances.\n\n");
332 ptfig->LOINS = (struct loins *) reverse ((chain_list *)ptfig->LOINS);
333 for (ptins = ptfig->LOINS; ptins; ptins = ptins->NEXT)
334 {
335 /* name the module name and the instance name */
336 (void) fprintf (ptfile, "%s ", vlg_name(ptins->FIGNAME));
337 (void) fprintf (ptfile, "i_%s (\n ", vlg_name(ptins->INSNAME));
338 ptcon = ptins->LOCON;
339 while(ptcon != NULL)
340 {
341 vlg_busname(ptcon, &left, &right, &name);
342 (void) fprintf (ptfile, ".%s(",vlg_name(name));
343 if(left != -1)
344 {
345 /* The connected signals are bused */
346 for(i = abs(left - right); i >= 0; i--)
347 {
348 ptsig = ptcon->SIG;
349 if (ptsig->TYPE == 'I')
350 {
351 /* The signal is internal */
352 sig_name = namealloc(mvl_vhdlname(getsigname(ptsig)));
353 sig_list = addchain(sig_list,(char *)sig_name);
354 }
355 else
356 {
357 /* The signal is external */
358 for (ptscan = ptfig->LOCON ; ptscan ; ptscan = ptscan->NEXT)
359 {
360 if (ptscan->SIG == ptsig)
361 break;
362 }
363 if (ptscan == NULL)
364 {
365 (void) printf("\n*** mbk error *** no external connector \n");
366 (void) printf(" driving verilog file %s\n", ptfig->NAME);
367 }
368 else
369 {
370 sig_name = namealloc(vlg_name(ptscan->NAME));
371 sig_list = addchain(sig_list,(char *)sig_name);
372 }
373 }
374 if(i > 0)
375 ptcon = ptcon->NEXT;
376 }
377 first = 1;
378 while(sig_list != NULL)
379 {
380 if(first!=1)
381 {
382 (void)fprintf(ptfile,"& %s",(char *)(sig_list->DATA));
383 }
384 else
385 {
386 (void)fprintf(ptfile,"%s",(char *)(sig_list->DATA));
387 first = 0;
388 }
389 sig_list = sig_list->NEXT;
390 }
391 }
392 else
393 {
394 /* The connected signals is simple */
395 ptsig = ptcon->SIG;
396 if (ptsig->TYPE == 'I')
397 {
398 (void) fprintf(ptfile, "%s", vlg_name (getsigname(ptsig)));
399 }
400 else
401 {
402 for (ptscan = ptfig->LOCON ; ptscan ; ptscan = ptscan->NEXT)
403 {
404 if (ptscan->SIG == ptsig) break;
405 }
406 if (ptscan == NULL)
407 {
408 (void) printf("\n*** mbk error *** no external connector \n");
409 (void) printf(" driving verilog file %s\n", ptfig->NAME);
410 }
411 else
412 {
413 (void) fprintf(ptfile, "%s", vlg_name(ptscan->NAME));
414 }
415 }
416 }
417 if (ptcon->NEXT != NULL)
418 (void) fprintf (ptfile, "),");
419 ptcon = ptcon->NEXT;
420 }
421 (void) fprintf(ptfile, "));\n");
422 }
423 ptfig->LOINS = (struct loins *) reverse ((chain_list *)ptfig->LOINS);
424 (void) fprintf(ptfile, "endmodule\n");
425 (void) fclose (ptfile);
426 }
427