2
* Electric(tm) VLSI Design System
5
* This is the main file for the VHDL front-end compiler for generating
6
* input files for the ALS Design System and QUISC (Silicon Compiler)
7
* Written by: Andrew R. Kostiuk, Queen's University
8
* Modified by: Steven M. Rubin, Static Free Software
10
* Copyright (c) 2000 Static Free Software.
12
* Electric(tm) is free software; you can redistribute it and/or modify
13
* it under the terms of the GNU General Public License as published by
14
* the Free Software Foundation; either version 2 of the License, or
15
* (at your option) any later version.
17
* Electric(tm) is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* You should have received a copy of the GNU General Public License
23
* along with Electric(tm); see the file COPYING. If not, write to
24
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
25
* Boston, Mass 02111-1307, USA.
27
* Static Free Software
29
* Portola Valley, California 94028
30
* info@staticfreesoft.com
37
#include "efunction.h"
45
#define MAXINPUTS 30 /* maximum inputs to logic gate */
46
#define IGNORE4PORTTRANSISTORS 1
48
/* special codes during VHDL generation */
49
#define BLOCKNORMAL 0 /* ordinary block */
50
#define BLOCKMOSTRAN 1 /* a MOS transistor */
51
#define BLOCKBUFFER 2 /* a buffer */
52
#define BLOCKPOSLOGIC 3 /* an and, or, xor */
53
#define BLOCKINVERTER 4 /* an inverter */
54
#define BLOCKNAND 5 /* a nand */
55
#define BLOCKNOR 6 /* a nor */
56
#define BLOCKXNOR 7 /* an xnor */
57
#define BLOCKFLOPDS 8 /* a settable D flip-flop */
58
#define BLOCKFLOPDR 9 /* a resettable D flip-flop */
59
#define BLOCKFLOPTS 10 /* a settable T flip-flop */
60
#define BLOCKFLOPTR 11 /* a resettable T flip-flop */
61
#define BLOCKFLOP 12 /* a general flip-flop */
63
/* the VHDL compiler tool table */
64
static KEYWORD vhdloutputopt[] =
66
{"netlisp", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
67
{"als", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
68
{"quisc", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
69
{"silos", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
70
{"rsim", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
73
static COMCOMP vhdloutputp = {vhdloutputopt, NOTOPLIST, NONEXTLIST, NOPARAMS,
74
NOBACKUP, INPUTOPT, " \t", M_("VHDL compiler output format"), 0};
75
static COMCOMP vhdllibraryp = {NOKEYWORD, topoflibs, nextlibs, NOPARAMS,
76
NOBACKUP, INPUTOPT, " \t", M_("Behavioral library to use in VHDL compilation"), 0};
77
static KEYWORD vhdlnopt[] =
79
{"vhdl-on-disk", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
80
{"netlist-on-disk", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
81
{"external", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
82
{"warn", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
85
static COMCOMP vhdlnp = {vhdlnopt, NOTOPLIST, NONEXTLIST, NOPARAMS,
86
NOBACKUP, INPUTOPT, " \t", M_("Negating action"), 0};
87
static KEYWORD vhdlsetopt[] =
89
{"output-format", 1,{&vhdloutputp,NOKEY,NOKEY,NOKEY,NOKEY}},
90
{"library", 1,{&vhdllibraryp,NOKEY,NOKEY,NOKEY,NOKEY}},
91
{"external", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
92
{"warn", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
93
{"vhdl-on-disk", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
94
{"netlist-on-disk", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
95
{"not", 1,{&vhdlnp,NOKEY,NOKEY,NOKEY,NOKEY}},
96
{"make-vhdl", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
97
{"compile-now", 0,{NOKEY,NOKEY,NOKEY,NOKEY,NOKEY}},
100
COMCOMP vhdl_comp = {vhdlsetopt, NOTOPLIST, NONEXTLIST, NOPARAMS, NOBACKUP,
101
0, " \t", M_("VHDL compiler action"), 0};
103
char vhdl_delimiterstr[] = "&'()*+,-./:;<=>|";
104
char vhdl_doubledelimiterstr[] = "=>..**:=/=>=<=<>";
106
static VKEYWORD vhdl_keywords[] =
109
{"after", KEY_AFTER},
110
{"alias", KEY_ALIAS},
116
{"architectural", KEY_ARCHITECTURAL},
118
{"architecture", KEY_ARCHITECTURE},
120
{"array", KEY_ARRAY},
121
{"assertion", KEY_ASSERTION},
122
{"attribute", KEY_ATTRIBUTE},
123
{"begin", KEY_BEGIN},
124
{"behavioral", KEY_BEHAVIORAL},
127
{"component", KEY_COMPONENT},
128
{"connect", KEY_CONNECT},
129
{"constant", KEY_CONSTANT},
130
{"convert", KEY_CONVERT},
132
{"downto", KEY_DOWNTO},
134
{"elsif", KEY_ELSIF},
136
{"entity", KEY_ENTITY},
139
{"function", KEY_FUNCTION},
140
{"generate", KEY_GENERATE},
141
{"generic", KEY_GENERIC},
144
{"inout", KEY_INOUT},
146
{"library", KEY_LIBRARY},
147
{"linkage", KEY_LINKAGE},
163
{"others", KEY_OTHERS},
165
{"package", KEY_PACKAGE},
167
{"range", KEY_RANGE},
168
{"record", KEY_RECORD},
170
{"report", KEY_REPORT},
171
{"resolve", KEY_RESOLVE},
172
{"return", KEY_RETURN},
173
{"severity", KEY_SEVERITY},
174
{"signal", KEY_SIGNAL},
175
{"standard", KEY_STANDARD},
176
{"static", KEY_STATIC},
177
{"subtype", KEY_SUBTYPE},
181
{"units", KEY_UNITS},
183
{"variable", KEY_VARIABLE},
185
{"while", KEY_WHILE},
190
static IDENTTABLE *vhdl_identtable = 0;
191
static TOKENLIST *vhdl_tliststart;
192
static TOKENLIST *vhdl_tlistend;
193
INTBIG vhdl_externentities; /* enternal entities flag */
194
INTBIG vhdl_warnflag; /* warning flag, TRUE warn */
195
static INTBIG vhdl_vhdlondiskkey; /* variable key for "VHDL_vhdl_on_disk" */
196
static INTBIG vhdl_netlistondiskkey; /* variable key for "VHDL_netlist_on_disk" */
197
INTBIG vhdl_target; /* Current simulator */
198
static LIBRARY *vhdl_lib; /* behavioral library */
199
static FILE *vhdl_fp; /* current file */
200
static VARIABLE *vhdl_var; /* current variable */
201
static INTBIG vhdl_linecount; /* current line number */
202
static NODEPROTO *vhdl_facet; /* current output facet */
203
extern INTBIG vhdl_errorcount;
204
extern SYMBOLLIST *vhdl_gsymbols;
206
static void *vhdl_componentarray = 0;
207
static void *vhdl_stringarray;
208
UNRESLIST *vhdl_unresolved_list = 0;
210
/* prototypes for local routines */
211
static void vhdl_addportlist(NODEINST*, NODEPROTO*, INTBIG);
212
static void vhdl_addrealports(NODEINST *ni, INTBIG special);
213
static void vhdl_addstring(char*, NODEPROTO*);
214
static void vhdl_addtheseports(NODEINST*, NODEPROTO*, INTBIG, char*);
215
static BOOLEAN vhdl_compile(NODEPROTO*);
216
static void vhdl_convertfacet(NODEPROTO*, BOOLEAN);
217
static INTBIG vhdl_endinput(void);
218
static INTBIG vhdl_endoutput(void);
219
static void vhdl_freescannermemory(void);
220
static BOOLEAN vhdl_generatevhdl(NODEPROTO *np);
221
static UINTBIG vhdl_getfacetdate(NODEPROTO *np);
222
static INTBIG vhdl_getnextline(char*);
223
static INTBIG vhdl_identfirsthash(char*);
224
static INTBIG vhdl_identsecondhash(char*, INTBIG);
225
static VKEYWORD *vhdl_iskeyword(char*, INTBIG);
226
static void vhdl_makechartoken(char, INTBIG, INTBIG);
227
static void vhdl_makedecimaltoken(char*, INTBIG, INTBIG, INTBIG);
228
static void vhdl_makeidenttoken(char*, INTBIG, INTBIG, INTBIG);
229
static void vhdl_makekeytoken(VKEYWORD*, INTBIG, INTBIG);
230
static BOOLEAN vhdl_morerecentcontents(NODEPROTO*, UINTBIG);
231
static void vhdl_makestrtoken(char*, INTBIG, INTBIG, INTBIG);
232
static void vhdl_maketoken(INTBIG, INTBIG, INTBIG);
233
static void vhdl_optionsdlog(void);
234
static char *vhdl_primname(NODEINST*, INTBIG*);
235
static void vhdl_scanner(void);
236
static INTBIG vhdl_startinput(NODEPROTO*, INTBIG, BOOLEAN, char**, UINTBIG*);
237
static INTBIG vhdl_startoutput(NODEPROTO*, INTBIG, BOOLEAN, char**);
238
static char vhdl_toupper(char);
240
void vhdl_init(INTBIG *argc, char *argv[], TOOL *thistool)
242
/* only initialize during pass 1 */
243
if (thistool == NOTOOL || thistool == 0) return;
245
vhdl_tool = thistool;
246
vhdl_target = TARGET_QUISC;
247
vhdl_externentities = TRUE;
248
vhdl_warnflag = FALSE;
249
vhdl_lib = NOLIBRARY;
250
vhdl_vhdlondiskkey = makekey("VHDL_vhdl_on_disk");
251
vhdl_netlistondiskkey = makekey("VHDL_netlist_on_disk");
252
DiaDeclareHook("vhdlopt", &vhdl_comp, vhdl_optionsdlog);
258
if (vhdl_componentarray != 0) killstringarray(vhdl_componentarray);
259
vhdl_freescannermemory();
260
if (vhdl_identtable != 0) efree((char *)vhdl_identtable);
261
vhdl_freeparsermemory();
263
vhdl_freeunresolvedlist(&vhdl_unresolved_list);
267
void vhdl_set(INTBIG count, char *par[])
271
REGISTER NODEPROTO *np;
273
if (count == 0) return;
274
l = strlen(pp = par[0]);
276
if (namesamen(pp, "make-vhdl", l) == 0)
280
np = getnodeproto(par[1]);
281
if (np == NONODEPROTO)
283
ttyputerr(_("No facet named %s"), par[1]);
286
if (np->primindex != 0)
288
ttyputerr(M_("Can only convert facets to VHDL, not primitives"));
294
if (np == NONODEPROTO)
296
ttyputerr(_("No current facet"));
300
begintraversehierarchy();
301
vhdl_convertfacet(np, TRUE);
306
if (namesamen(pp, "compile-now", l) == 0)
309
if (np == NONODEPROTO)
311
ttyputerr(_("Must be editing a cell"));
315
(void)vhdl_compile(np);
319
if (namesamen(pp, "library", l) == 0)
323
ttyputusage("telltool vhdl-compiler library LIBRARY");
326
vhdl_lib = getlibrary(par[1]);
327
if (vhdl_lib == NOLIBRARY)
329
ttyputerr(_("Cannot find library %s"), par[1]);
332
ttyputverbose(M_("Library %s will be used for behavioral descriptions"), par[1]);
336
if (namesamen(pp, "vhdl-on-disk", l) == 0)
338
setvalkey((INTBIG)vhdl_tool, VTOOL, vhdl_vhdlondiskkey, 1, VINTEGER);
339
ttyputverbose(M_("VHDL will be kept in separate disk files"));
343
if (namesamen(pp, "netlist-on-disk", l) == 0)
345
setvalkey((INTBIG)vhdl_tool, VTOOL, vhdl_netlistondiskkey, 1, VINTEGER);
346
ttyputverbose(M_("Netlists will be kept in separate disk files"));
350
if (namesamen(pp, "warn", l) == 0)
352
vhdl_warnflag = TRUE;
353
ttyputverbose(M_("VHDL compiler will display warnings"));
357
if (namesamen(pp, "external", l) == 0)
359
vhdl_externentities = TRUE;
360
ttyputverbose(M_("VHDL compiler will allow external references"));
364
if (namesamen(pp, "not", l) == 0)
368
ttyputusage("telltool vhdl-compiler not OPTION");
371
l = strlen(pp = par[1]);
372
if (namesamen(pp, "warn", l) == 0)
374
vhdl_warnflag = FALSE;
375
ttyputverbose(M_("VHDL compiler will not display warnings"));
378
if (namesamen(pp, "external", l) == 0)
380
vhdl_externentities = FALSE;
381
ttyputverbose(M_("VHDL compiler will not allow external references"));
384
if (namesamen(pp, "vhdl-on-disk", l) == 0)
386
setvalkey((INTBIG)vhdl_tool, VTOOL, vhdl_vhdlondiskkey, 0, VINTEGER);
387
ttyputverbose(M_("VHDL will be kept in facets"));
390
if (namesamen(pp, "netlist-on-disk", l) == 0)
392
setvalkey((INTBIG)vhdl_tool, VTOOL, vhdl_netlistondiskkey, 0, VINTEGER);
393
ttyputverbose(M_("Netlists will be kept in facets"));
396
ttyputbadusage("telltool vhdl-compiler not");
400
if (namesamen(pp, "output-format", l) == 0)
404
ttyputusage("telltool vhdl-compiler output-format FORMAT");
407
l = strlen(pp = par[1]);
408
if (namesamen(pp, "netlisp", l) == 0)
410
vhdl_target = TARGET_NETLISP;
411
ttyputverbose(M_("VHDL compiles to net lisp"));
414
if (namesamen(pp, "als", l) == 0 && l >= 1)
416
vhdl_target = TARGET_ALS;
417
ttyputverbose(M_("VHDL compiles to ALS simulation"));
420
if (namesamen(pp, "quisc", l) == 0 && l >= 3)
422
vhdl_target = TARGET_QUISC;
423
ttyputverbose(M_("VHDL compiles to QUISC place-and-route"));
426
if (namesamen(pp, "silos", l) == 0)
428
vhdl_target = TARGET_SILOS;
429
ttyputverbose(M_("VHDL compiles to SILOS simulation"));
432
if (namesamen(pp, "rsim", l) == 0)
434
vhdl_target = TARGET_RSIM;
435
ttyputverbose(M_("VHDL compiles to RSIM simulation"));
438
ttyputbadusage("telltool vhdl-compiler output-format");
442
ttyputbadusage("telltool vhdl-compiler");
445
void vhdl_slice(void)
447
REGISTER NODEPROTO *np;
450
if (np == NONODEPROTO)
452
ttyputerr(_("Must be editing a cell"));
453
toolturnoff(vhdl_tool, FALSE);
457
(void)vhdl_compile(np);
459
toolturnoff(vhdl_tool, FALSE);
460
ttyputmsg(_("VHDL compiler turned off"));
464
* make requests of the VHDL tool:
465
* "begin-vhdl-input" TAKES: facet, string for source RETURNS: nonzero on error
466
* "begin-netlist-input" TAKES: facet, filetype, string for source
467
* RETURNS: nonzero on error
468
* "want-netlist-input" TAKES: facet, filetype
469
* RETURNS: nonzero on error
470
* "get-line" TAKES: buffer address RETURNS: line number, zero on EOF
473
* "begin-vhdl-output" TAKES: facet, string for source RETURNS: output name (zero on error)
474
* "begin-netlist-output" TAKES: facet RETURNS: output name (zero on error)
475
* "put-line" TAKES: buffer address
478
INTBIG vhdl_request(char *command, va_list ap)
481
BOOLEAN vhdlondisk, netlistondisk;
482
UINTBIG netlistdate, vhdldate;
483
char *intended, *desired, buffer[MAXVHDLLINE];
484
REGISTER VARIABLE *var;
485
REGISTER INTBIG arg1, arg2, arg3;
486
REGISTER NODEPROTO *np, *orignp;
489
var = getvalkey((INTBIG)vhdl_tool, VTOOL, VINTEGER, vhdl_vhdlondiskkey);
491
if (var != NOVARIABLE && var->addr != 0) vhdlondisk = TRUE;
492
netlistondisk = FALSE;
493
var = getvalkey((INTBIG)vhdl_tool, VTOOL, VINTEGER, vhdl_netlistondiskkey);
494
if (var != NOVARIABLE && var->addr != 0) netlistondisk = TRUE;
496
if (namesame(command, "begin-vhdl-input") == 0)
498
/* get the arguments (1=facet, 2=source) */
499
arg1 = va_arg(ap, INTBIG);
500
arg2 = va_arg(ap, INTBIG);
502
return(vhdl_startinput((NODEPROTO *)arg1, io_filetypevhdl, vhdlondisk,
503
(char **)arg2, &vhdldate));
506
if (namesame(command, "begin-netlist-input") == 0)
508
/* get the arguments (1=facet, 2=filetype, 3=source) */
509
arg1 = va_arg(ap, INTBIG);
510
arg2 = va_arg(ap, INTBIG);
511
arg3 = va_arg(ap, INTBIG);
513
return(vhdl_startinput((NODEPROTO *)arg1, arg2, netlistondisk,
514
(char **)arg3, &netlistdate));
517
if (namesame(command, "get-line") == 0)
519
/* get the arguments (1=buffer) */
520
arg1 = va_arg(ap, INTBIG);
522
return(vhdl_getnextline((char *)arg1));
525
if (namesame(command, "end-input") == 0)
527
return(vhdl_endinput());
530
if (namesame(command, "want-netlist-input") == 0)
532
/* get the arguments (1=facet, 2=filetype) */
533
arg1 = va_arg(ap, INTBIG);
534
arg2 = va_arg(ap, INTBIG);
536
if (arg2 == sim_filetypequisc)
538
view = el_netlistquiscview; vhdl_target = TARGET_QUISC;
539
} else if (arg2 == sim_filetypeals)
541
view = el_netlistalsview; vhdl_target = TARGET_ALS;
542
} else if (arg2 == sim_filetypenetlisp)
544
view = el_netlistnetlispview; vhdl_target = TARGET_NETLISP;
545
} else if (arg2 == sim_filetypesilos)
547
view = el_netlistsilosview; vhdl_target = TARGET_SILOS;
548
} else if (arg2 == sim_filetypersim)
550
view = el_netlistrsimview; vhdl_target = TARGET_RSIM;
553
/* must have a valid netlist */
554
orignp = (NODEPROTO *)arg1;
555
i = vhdl_startinput(orignp, arg2, netlistondisk, &intended, &netlistdate);
559
/* got netlist: make sure it is more recent than any VHDL or layout */
560
if (orignp->cellview != view)
562
/* determine date of associated VHDL */
563
if (vhdl_startinput(orignp, io_filetypevhdl, vhdlondisk, &intended,
566
if (netlistdate < vhdldate) i = 1;
568
/* if original is not VHDL, ensure that VHDL comes from original */
569
if (orignp->cellview != el_vhdlview)
571
if (vhdl_getnextline(buffer) != 0)
573
desired = "-- VHDL automatically generated from facet ";
574
len = strlen(desired);
575
if (strncmp(buffer, desired, len) == 0)
577
if (strcmp(&buffer[len], describenodeproto(orignp)) != 0) i = 1;
584
/* if original is not VHDL, check all facets for recency */
585
if (orignp->cellview != el_vhdlview && i == 0)
587
/* check all in cell for recency */
588
for(np = orignp->cell->firstincell; np != NONODEPROTO; np = np->nextincell)
589
if (netlistdate < np->revisiondate)
596
if (vhdl_morerecentcontents(orignp, netlistdate)) i = 1;
604
/* no valid netlist: look for VHDL */
605
i = vhdl_startinput(orignp, io_filetypevhdl, vhdlondisk, &intended, &vhdldate);
607
/* if original is not VHDL, ensure that VHDL comes from original */
608
if (i == 0 && orignp->cellview != el_vhdlview)
610
if (vhdl_getnextline(buffer) != 0)
612
desired = "-- VHDL automatically generated from facet ";
613
len = strlen(desired);
614
if (strncmp(buffer, desired, len) == 0)
616
if (strcmp(&buffer[len], describenodeproto(orignp)) != 0) i = 1;
623
/* got VHDL: make sure it is more recent than any layout */
624
if (orignp->cellview != el_vhdlview)
626
/* check all in cell for recency */
627
for(np = orignp->cell->firstincell; np != NONODEPROTO; np = np->nextincell)
628
if (vhdldate < np->revisiondate)
635
if (vhdl_morerecentcontents(orignp, vhdldate)) i = 1;
641
/* no valid VHDL: convert facet */
642
np = (NODEPROTO *)arg1;
643
begintraversehierarchy();
644
vhdl_convertfacet(np, FALSE);
647
/* compile VHDL to netlist */
648
if (vhdl_compile(getcurfacet())) return(1);
653
if (namesame(command, "begin-vhdl-output") == 0)
655
/* get the arguments (1=facet, 2=source) */
656
arg1 = va_arg(ap, INTBIG);
657
arg2 = va_arg(ap, INTBIG);
659
return(vhdl_startoutput((NODEPROTO *)arg1, io_filetypevhdl, vhdlondisk,
663
if (namesame(command, "put-line") == 0)
665
/* get the arguments */
666
arg1 = va_arg(ap, INTBIG);
667
arg2 = va_arg(ap, INTBIG);
668
arg3 = va_arg(ap, INTBIG);
670
vhdl_print((char *)arg1, (char *)arg2, (char *)arg3);
674
if (namesame(command, "end-output") == 0)
676
return(vhdl_endoutput());
682
* routine returns false if all facets in the hierarchy below facet "np" are less recent
683
* than "dateoffile". Returns true if any more recent facet is found.
685
BOOLEAN vhdl_morerecentcontents(NODEPROTO *np, UINTBIG dateoffile)
687
REGISTER NODEINST *ni;
688
REGISTER NODEPROTO *subnp;
690
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
693
if (subnp->primindex != 0) continue;
695
/* ignore recursive references (showing icon in contents) */
696
if (subnp->cell == np->cell) continue;
697
if (subnp->cellview == el_iconview)
699
subnp = contentsview(subnp);
700
if (subnp == NONODEPROTO) continue;
702
if (dateoffile < subnp->revisiondate) return(TRUE);
703
if (vhdl_morerecentcontents(subnp, dateoffile)) return(TRUE);
708
/****************************** GENERALIZED VHDL/NET I/O ******************************/
711
* Routine to begin input of a file or facet of type "filetype". If "diskflag" is true,
712
* use a disk file whose name is the cell name of facet "np". If "diskflag" is false, use
713
* the facet with the appropriate view of "np". Returns the name of the input source in
714
* "intended" and its last modification date in "revisiondate". Returns nonzero on error.
716
INTBIG vhdl_startinput(NODEPROTO *np, INTBIG filetype, BOOLEAN diskflag, char **intended,
717
UINTBIG *revisiondate)
719
REGISTER NODEPROTO *onp;
723
if (np == NONODEPROTO || np->primindex != 0)
725
*intended = "NO CURRENT FACET";
729
if (filetype == io_filetypevhdl)
732
} else if (filetype == sim_filetypequisc)
734
view = el_netlistquiscview;
735
} else if (filetype == sim_filetypeals)
737
view = el_netlistalsview;
738
} else if (filetype == sim_filetypenetlisp)
740
view = el_netlistnetlispview;
741
} else if (filetype == sim_filetypesilos)
743
view = el_netlistsilosview;
744
} else if (filetype == sim_filetypersim)
746
view = el_netlistrsimview;
750
vhdl_var = NOVARIABLE;
753
/* attempt to open file */
755
(void)addstringtoinfstr("file ");
756
(void)addstringtoinfstr(np->cell->cellname);
757
*intended = returninfstr();
758
if ((vhdl_fp = xopen(np->cell->cellname, filetype, "", &filename)) == 0) return(1);
759
*revisiondate = filedate(filename);
762
/* find proper view of this cell */
763
if (np->cellview == view) onp = np; else
764
for(onp = np->cell->firstincell; onp != NONODEPROTO; onp = onp->nextincell)
765
if (onp->cellview == view) break;
766
if (onp == NONODEPROTO)
768
*intended = "CANNOT FIND FACET VIEW";
773
(void)addstringtoinfstr("facet ");
774
(void)addstringtoinfstr(describenodeproto(onp));
775
*intended = returninfstr();
776
vhdl_var = getvalkey((INTBIG)onp, VNODEPROTO, VSTRING|VISARRAY, el_facet_message_key);
777
if (vhdl_var == NOVARIABLE) return(1);
778
*revisiondate = onp->revisiondate;
784
INTBIG vhdl_endinput(void)
791
if (vhdl_var != NOVARIABLE) vhdl_var = NOVARIABLE;
796
* Routine to get the next line from the current input file/facet into the buffer
797
* at "addr". Returns the line number (1-based). Returns zero on EOF.
799
INTBIG vhdl_getnextline(char *addr)
806
ret = xfgets(addr, MAXVHDLLINE-1, vhdl_fp);
808
} else if (vhdl_var != NOVARIABLE)
810
if (vhdl_linecount >= getlength(vhdl_var)) return(0);
811
line = ((char **)vhdl_var->addr)[vhdl_linecount];
812
if (strlen(line) >= MAXVHDLLINE)
814
ttyputerr(_("Error: line %ld longer than limit of %d characters"),
815
vhdl_linecount+1, MAXVHDLLINE);
816
strncpy(addr, line, MAXVHDLLINE-1);
817
addr[MAXVHDLLINE] = 0;
820
(void)strcpy(addr, line);
824
return(vhdl_linecount);
828
* Routine to begin output of a file of type "filetype" (either VHDL or Netlist) that is either
829
* to disk ("diskflag" true) or to a facet ("diskflag" false). If it is to disk,
830
* the file name is the cell name of facet "np". If it is to a facet, that facet is the
831
* appropriate view of "np". Returns the intended destination in "indended".
832
* Returns 1 on error, -1 if aborted.
834
INTBIG vhdl_startoutput(NODEPROTO *np, INTBIG filetype, BOOLEAN diskflag, char **intended)
836
REGISTER char *prompt;
837
char *truefile, *ext;
840
if (filetype == io_filetypevhdl)
842
view = el_vhdlview; ext = "vhdl";
843
} else if (filetype == sim_filetypequisc)
845
view = el_netlistquiscview; ext = "sci";
846
} else if (filetype == sim_filetypeals)
848
view = el_netlistalsview; ext = "net";
849
} else if (filetype == sim_filetypenetlisp)
851
view = el_netlistnetlispview; ext = "net";
852
} else if (filetype == sim_filetypesilos)
854
view = el_netlistsilosview; ext = "sil";
855
} else if (filetype == sim_filetypersim)
857
view = el_netlistrsimview; ext = "net";
861
vhdl_facet = NONODEPROTO;
864
/* attempt to open output file */
866
(void)addstringtoinfstr("file ");
867
(void)addstringtoinfstr(np->cell->cellname);
868
(void)addstringtoinfstr(".");
869
(void)addstringtoinfstr(ext);
870
*intended = returninfstr();
871
if (namesame(ext, "vhdl") == 0) prompt = _("VHDL File"); else
872
prompt = _("Netlist File");
873
vhdl_fp = xcreate(&(*intended)[5], filetype, prompt, &truefile);
876
if (truefile == 0) return(-1);
881
/* make proper view of this cell */
883
(void)addstringtoinfstr("facet ");
884
(void)addstringtoinfstr(np->cell->cellname);
885
(void)addstringtoinfstr("{");
886
(void)addstringtoinfstr(view->sviewname);
887
(void)addstringtoinfstr("}");
888
*intended = returninfstr();
889
vhdl_facet = newnodeproto(&(*intended)[6], np->cell->lib);
890
if (vhdl_facet == NONODEPROTO) return(1);
891
vhdl_stringarray = newstringarray(vhdl_tool->cluster);
896
INTBIG vhdl_endoutput(void)
903
if (vhdl_facet != NONODEPROTO)
905
stringarraytotextfacet(vhdl_stringarray, vhdl_facet, FALSE);
906
killstringarray(vhdl_stringarray);
907
vhdl_facet = NONODEPROTO;
913
* Routine to write a formatted string to the current output file.
915
void vhdl_printoneline(char *fstring, ...)
920
var_start(ap, fstring);
921
evsnprintf(buff, 4000, fstring, ap);
923
if (vhdl_fp == 0) addtostringarray(vhdl_stringarray, buff); else
924
xprintf(vhdl_fp, "%s\n", buff);
928
* Routine to write a formatted string to the current output file.
930
void vhdl_print(char *fstring, ...)
933
char buff[4000], *sptr, save;
936
var_start(ap, fstring);
937
evsnprintf(buff, 4000, fstring, ap);
940
while (strlen(sptr) > 70)
942
for(i=70; i>0; i--) if (isspace(sptr[i])) break;
944
save = sptr[i]; sptr[i] = 0;
945
if (vhdl_fp == 0) addtostringarray(vhdl_stringarray, sptr); else
946
xprintf(vhdl_fp, "%s\n", sptr);
948
if (vhdl_target == TARGET_SILOS)
955
if (vhdl_fp == 0) addtostringarray(vhdl_stringarray, sptr); else
956
xprintf(vhdl_fp, "%s\n", sptr);
960
* Routine to determine the revision date of facet "np", including any subfacets.
962
UINTBIG vhdl_getfacetdate(NODEPROTO *np)
964
REGISTER UINTBIG mostrecent, subfacetdate;
965
REGISTER NODEINST *ni;
967
mostrecent = np->revisiondate;
968
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
970
if (ni->proto->primindex != 0) continue;
972
/* ignore recursive references (showing icon in contents) */
973
if (ni->proto->cell == np->cell) continue;
974
subfacetdate = vhdl_getfacetdate(ni->proto);
975
if (subfacetdate > mostrecent) mostrecent = subfacetdate;
980
/****************************** GENERATION ******************************/
983
* Routine to ensure that facet "np" and all subfacets have VHDL on them.
984
* If "force" is true, do conversion even if VHDL facet is newer. Otherwise
985
* convert only if necessary.
987
void vhdl_convertfacet(NODEPROTO *np, BOOLEAN force)
989
REGISTER NODEPROTO *npvhdl, *onp;
990
REGISTER LIBRARY *lib;
991
REGISTER INTBIG i, len;
992
REGISTER BOOLEAN backannotate;
994
REGISTER UINTBIG dateoflayout;
995
REGISTER VARIABLE *var;
997
char *intended, *filename, *desired, *firstline;
999
/* cannot make VHDL for facet with no ports */
1000
if (np->firstportproto == NOPORTPROTO)
1002
ttyputerr(_("Cannot convert facet %s to VHDL: it has no ports"), describenodeproto(np));
1007
var = getvalkey((INTBIG)vhdl_tool, VTOOL, VINTEGER, vhdl_vhdlondiskkey);
1008
if (var != NOVARIABLE && var->addr != 0) vhdlondisk = TRUE;
1012
/* determine most recent change to this or any subfacet */
1013
dateoflayout = vhdl_getfacetdate(np);
1015
/* if there is already VHDL that is newer, stop now */
1018
/* look for the disk file */
1019
f = xopen(np->cell->cellname, io_filetypevhdl, "", &filename);
1023
if (filedate(filename) >= dateoflayout) return;
1027
/* look for the facet */
1028
npvhdl = anyview(np, el_vhdlview);
1029
if (npvhdl != NONODEPROTO)
1031
/* examine the VHDL to see if it really came from this facet */
1032
var = getvalkey((INTBIG)npvhdl, VNODEPROTO, VSTRING|VISARRAY, el_facet_message_key);
1033
if (var != NOVARIABLE)
1035
firstline = ((char **)var->addr)[0];
1036
desired = "-- VHDL automatically generated from facet ";
1037
len = strlen(desired);
1038
if (strncmp(firstline, desired, len) == 0)
1040
if (strcmp(&desired[len], describenodeproto(np)) != 0)
1041
dateoflayout = npvhdl->revisiondate + 1;
1045
if (npvhdl->revisiondate >= dateoflayout) return;
1050
/* begin output of VHDL */
1051
i = vhdl_startoutput(np, io_filetypevhdl, vhdlondisk, &intended);
1054
if (i > 0) ttyputerr(_("Cannot write %s"), intended);
1057
ttyputmsg(_("Converting layout in facet %s, writing VHDL to %s"), describenodeproto(np),
1060
/* recursively generate the VHDL */
1061
for(lib = el_curlib; lib != NOLIBRARY; lib = lib->nextlibrary)
1062
for(onp = lib->firstnodeproto; onp != NONODEPROTO; onp = onp->nextnodeproto)
1064
backannotate = vhdl_generatevhdl(np);
1066
ttyputmsg(_("Back-annotation information has been added (library must be saved)"));
1072
BOOLEAN vhdl_generatevhdl(NODEPROTO *np)
1074
REGISTER NODEINST *ni;
1075
REGISTER NODEPROTO *onp, *cnp;
1076
REGISTER INTBIG first, i, j, instnum, linelen, thisend, gotinverters;
1077
REGISTER BOOLEAN backannotate;
1078
INTBIG componentcount;
1080
REGISTER NETWORK *net;
1081
REGISTER PORTPROTO *pp;
1082
REGISTER ARCINST *ai;
1083
REGISTER VARIABLE *var;
1084
char line[30], *pt, gotnand[MAXINPUTS+1], gotxnor[MAXINPUTS+1],
1085
gotnor[MAXINPUTS+1], **componentlist;
1087
/* make sure that all nodes have names on them */
1088
backannotate = FALSE;
1089
if (asktool(net_tool, "name-nodes", (INTBIG)np) != 0) backannotate = TRUE;
1090
if (asktool(net_tool, "name-nets", (INTBIG)np) != 0) backannotate = TRUE;
1092
/* indicate the source of this VHDL */
1094
(void)addstringtoinfstr("-- VHDL automatically generated from facet ");
1095
(void)addstringtoinfstr(describenodeproto(np));
1096
vhdl_printoneline(returninfstr());
1098
/* build the "entity" line */
1100
(void)addstringtoinfstr("entity ");
1101
vhdl_addstring(np->cell->cellname, NONODEPROTO);
1102
(void)addstringtoinfstr(" is port(");
1103
vhdl_addportlist(NONODEINST, np, 0);
1104
(void)addstringtoinfstr(");");
1105
vhdl_print(returninfstr());
1107
/* add the "end" line */
1109
(void)addstringtoinfstr(" end ");
1110
vhdl_addstring(np->cell->cellname, NONODEPROTO);
1111
(void)addstringtoinfstr(";");
1112
vhdl_print(returninfstr());
1114
/* now write the "architecture" line */
1116
(void)addstringtoinfstr("architecture ");
1117
vhdl_addstring(np->cell->cellname, NONODEPROTO);
1118
(void)addstringtoinfstr("_BODY of ");
1119
vhdl_addstring(np->cell->cellname, NONODEPROTO);
1120
(void)addstringtoinfstr(" is");
1121
vhdl_print(returninfstr());
1123
/* enumerate negated arcs */
1125
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1127
if ((ai->userbits&ISNEGATED) == 0) continue;
1128
ai->temp1 = instnum;
1132
/* write prototypes for each node */
1133
for(i=0; i<=MAXINPUTS; i++) gotnand[i] = gotnor[i] = gotxnor[i] = 0;
1134
if (vhdl_componentarray == 0)
1136
vhdl_componentarray = newstringarray(vhdl_tool->cluster);
1137
if (vhdl_componentarray == 0) return(backannotate);
1139
clearstrings(vhdl_componentarray);
1140
componentlist = getstringarray(vhdl_componentarray, &componentcount);
1143
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1145
if (ni->proto->primindex == 0)
1147
/* ignore recursive references (showing icon in contents) */
1148
if (ni->proto->cell == np->cell) continue;
1150
pt = vhdl_primname(ni, &special);
1151
if (pt[0] == 0) continue;
1153
/* see if the node has a name, number it if not */
1154
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, el_node_name_key);
1155
if (var == NOVARIABLE) ni->temp1 = instnum++;
1157
/* write only once per prototype */
1158
if (special == BLOCKINVERTER)
1163
if (special == BLOCKNAND)
1166
if (i <= MAXINPUTS) gotnand[i]++; else
1167
ttyputerr("Cannot handle %ld-input NAND, limit is %d", i, MAXINPUTS);
1170
if (special == BLOCKNOR)
1173
if (i <= MAXINPUTS) gotnor[i]++; else
1174
ttyputerr("Cannot handle %ld-input NOR, limit is %d", i, MAXINPUTS);
1177
if (special == BLOCKXNOR)
1180
if (i <= MAXINPUTS) gotxnor[i]++; else
1181
ttyputerr("Cannot handle %ld-input XNOR, limit is %d", i, MAXINPUTS);
1185
/* ignore component with no ports */
1186
if (ni->proto->firstportproto == NOPORTPROTO) continue;
1188
/* see if this component is already written to the header */
1189
for(i=0; i<componentcount; i++)
1190
if (namesame(pt, componentlist[i]) == 0) break;
1191
if (i < componentcount) continue;
1193
/* new component: add to the list */
1194
addtostringarray(vhdl_componentarray, pt);
1195
componentlist = getstringarray(vhdl_componentarray, &componentcount);
1198
(void)addstringtoinfstr(" component ");
1199
vhdl_addstring(pt, NONODEPROTO);
1200
(void)addstringtoinfstr(" port(");
1201
vhdl_addportlist(ni, ni->proto, special);
1202
(void)addstringtoinfstr(");");
1203
vhdl_print(returninfstr());
1204
vhdl_print(" end component;");
1207
/* write pseudo-prototype if there are any negated arcs */
1208
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1209
if ((ai->userbits&ISNEGATED) != 0 && ai->temp1 != 0)
1214
if (gotinverters != 0)
1216
vhdl_print(" component inverter port(a: in BIT; y: out BIT);");
1217
vhdl_print(" end component;");
1219
for(i=0; i<MAXINPUTS; i++)
1221
if (gotnand[i] != 0)
1224
(void)addstringtoinfstr(" component nand");
1225
(void)sprintf(line, "%ld", i);
1226
(void)addstringtoinfstr(line);
1227
(void)addstringtoinfstr(" port(");
1230
if (j > 1) (void)addstringtoinfstr(", ");
1231
(void)sprintf(line, "a%ld", j);
1232
(void)addstringtoinfstr(line);
1234
(void)addstringtoinfstr(": in BIT; y: out BIT);");
1235
vhdl_print(returninfstr());
1236
vhdl_print(" end component;");
1241
(void)addstringtoinfstr(" component nor");
1242
(void)sprintf(line, "%ld", i);
1243
(void)addstringtoinfstr(line);
1244
(void)addstringtoinfstr(" port(");
1247
if (j > 1) (void)addstringtoinfstr(", ");
1248
(void)sprintf(line, "a%ld", j);
1249
(void)addstringtoinfstr(line);
1251
(void)addstringtoinfstr(": in BIT; y: out BIT);");
1252
vhdl_print(returninfstr());
1253
vhdl_print(" end component;");
1255
if (gotxnor[i] != 0)
1258
(void)addstringtoinfstr(" component xnor");
1259
(void)sprintf(line, "%ld", i);
1260
(void)addstringtoinfstr(line);
1261
(void)addstringtoinfstr(" port(");
1264
if (j > 1) (void)addstringtoinfstr(", ");
1265
(void)sprintf(line, "a%ld", j);
1266
(void)addstringtoinfstr(line);
1268
(void)addstringtoinfstr(": in BIT; y: out BIT);");
1269
vhdl_print(returninfstr());
1270
vhdl_print(" end component;");
1274
/* write internal nodes */
1275
for(net = np->firstnetwork; net != NONETWORK; net = net->nextnetwork)
1277
for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
1279
pp->network->temp1 = 1;
1280
if (pp->network->signals > 1)
1282
for(i=0; i<pp->network->signals; i++)
1283
pp->network->networklist[i]->temp1 = 1;
1287
for(net = np->firstnetwork; net != NONETWORK; net = net->nextnetwork)
1289
if (net->portcount != 0 || net->buslinkcount != 0) continue;
1291
/* disallow if part of a bus export or already written */
1292
if (net->temp1 != 0) continue;
1293
for(i=0; i<net->signals; i++)
1295
if (net->signals <= 1)
1297
if (net->namecount > 0) pt = net->netname; else
1298
pt = describenetwork(net);
1302
if (net->networklist[i]->temp1 != 0) continue;
1303
pt = net->networklist[i]->netname;
1304
net->networklist[i]->temp1 = 1;
1305
pt = describenetwork(net->networklist[i]);
1310
(void)addstringtoinfstr(" signal ");
1314
(void)addstringtoinfstr(", ");
1318
if (linelen + strlen(pt) > 80)
1320
vhdl_print(returninfstr());
1322
(void)addstringtoinfstr(" ");
1325
vhdl_addstring(pt, np);
1326
linelen += strlen(pt);
1331
(void)addstringtoinfstr(": BIT;");
1332
vhdl_print(returninfstr());
1335
/* write pseudo-internal nodes for all negated arcs */
1337
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1339
if ((ai->userbits&ISNEGATED) == 0 || ai->temp1 == 0) continue;
1343
(void)addstringtoinfstr(" signal ");
1344
} else (void)addstringtoinfstr(", ");
1345
(void)sprintf(line, "PINV%ld", ai->temp1);
1346
(void)addstringtoinfstr(line);
1351
(void)addstringtoinfstr(": BIT;");
1352
vhdl_print(returninfstr());
1355
/* write the instances */
1356
vhdl_print("begin");
1357
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1359
/* ignore component with no ports */
1360
if (ni->proto->firstportproto == NOPORTPROTO) continue;
1362
if (ni->proto->primindex == 0)
1364
/* ignore recursive references (showing icon in contents) */
1365
if (ni->proto->cell == np->cell) continue;
1368
pt = vhdl_primname(ni, &special);
1369
if (pt[0] == 0) continue;
1372
(void)addstringtoinfstr(" ");
1373
var = getvalkey((INTBIG)ni, VNODEINST, VSTRING, el_node_name_key);
1374
if (var != NOVARIABLE) vhdl_addstring((char *)var->addr, NONODEPROTO); else
1376
ttyputerr("VHDL conversion warning: no name on node %s", describenodeinst(ni));
1377
(void)sprintf(line, "NODE%ld", (INTBIG)ni);
1378
(void)addstringtoinfstr(line);
1380
(void)addstringtoinfstr(": ");
1381
vhdl_addstring(pt, NONODEPROTO);
1383
(void)addstringtoinfstr(" port map(");
1384
vhdl_addrealports(ni, special);
1385
(void)addstringtoinfstr(");");
1386
vhdl_print(returninfstr());
1389
/* write pseudo-nodes for all negated arcs */
1390
for(ai = np->firstarcinst; ai != NOARCINST; ai = ai->nextarcinst)
1392
if ((ai->userbits&ISNEGATED) == 0 || ai->temp1 == 0) continue;
1394
(void)addstringtoinfstr(" PSEUDO_INVERT");
1395
(void)sprintf(line, "%ld", ai->temp1);
1396
(void)addstringtoinfstr(line);
1397
(void)addstringtoinfstr(": inverter port map(");
1398
if ((ai->userbits&REVERSEEND) == 0) thisend = 0; else thisend = 1;
1399
if ((ai->end[thisend].portarcinst->proto->userbits&STATEBITS) == OUTPORT)
1401
(void)sprintf(line, "PINV%ld", ai->temp1);
1402
(void)addstringtoinfstr(line);
1403
(void)addstringtoinfstr(", ");
1405
if (net->namecount > 0) vhdl_addstring(net->netname, np); else
1406
(void)addstringtoinfstr(describenetwork(net));
1410
if (net->namecount > 0) vhdl_addstring(net->netname, np); else
1411
(void)addstringtoinfstr(describenetwork(net));
1412
(void)addstringtoinfstr(", ");
1413
(void)sprintf(line, "PINV%ld", ai->temp1);
1414
(void)addstringtoinfstr(line);
1416
(void)addstringtoinfstr(");");
1417
vhdl_print(returninfstr());
1420
/* write the end of the body */
1422
(void)addstringtoinfstr("end ");
1423
vhdl_addstring(np->cell->cellname, NONODEPROTO);
1424
(void)addstringtoinfstr("_BODY;");
1425
vhdl_print(returninfstr());
1428
/* finally, generate VHDL for all subfacets */
1430
for(ni = np->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1432
if (ni->proto->primindex != 0) continue;
1434
/* ignore recursive references (showing icon in contents) */
1435
if (ni->proto->cell == np->cell) continue;
1436
if (ni->proto->temp1 != 0) continue;
1437
cnp = contentsview(ni->proto);
1438
if (cnp == NONODEPROTO) cnp = ni->proto;
1439
if (cnp->temp1 != 0) continue;
1441
/* ignore component with no ports */
1442
if (cnp->firstportproto == NOPORTPROTO) continue;
1444
/* if ALS, see if this facet is in the reference library */
1445
if (vhdl_lib != NOLIBRARY && vhdl_target == TARGET_ALS)
1447
for(onp = vhdl_lib->firstnodeproto; onp != NONODEPROTO; onp = onp->nextnodeproto)
1448
if (onp->cellview == el_netlistalsview &&
1449
namesame(onp->cell->cellname, cnp->cell->cellname) == 0) break;
1450
if (onp != NONODEPROTO) continue;
1453
downhierarchy(ni, 0);
1454
if (vhdl_generatevhdl(cnp)) backannotate = TRUE;
1457
return(backannotate);
1460
void vhdl_addrealports(NODEINST *ni, INTBIG special)
1462
REGISTER INTBIG first, pass, i;
1463
REGISTER PORTPROTO *pp, *opp, *cpp;
1464
REGISTER NODEPROTO *np, *cnp;
1465
REGISTER ARCINST *ai;
1466
REGISTER PORTARCINST *pi;
1467
REGISTER PORTEXPINST *pe;
1468
REGISTER NETWORK *net, *subnet;
1472
cnp = contentsview(np);
1473
if (cnp == NONODEPROTO) cnp = np;
1475
for(pass = 0; pass < 5; pass++)
1477
for(cpp = cnp->firstportproto; cpp != NOPORTPROTO; cpp = cpp->nextportproto)
1479
#ifdef IGNORE4PORTTRANSISTORS
1480
/* ignore the bias port of 4-port transistors */
1481
if (ni->proto == sch_transistor4prim)
1483
if (namesame(cpp->protoname, "b") == 0) continue;
1486
if (cnp == np) pp = cpp; else
1487
pp = equivalentport(cnp, cpp, np);
1490
/* must be an input port */
1491
if ((pp->userbits&STATEBITS) != INPORT) continue;
1495
/* must be an output port */
1496
if ((pp->userbits&STATEBITS) != OUTPORT) continue;
1500
/* must be an output port */
1501
if ((pp->userbits&STATEBITS) != PWRPORT) continue;
1505
/* must be an output port */
1506
if ((pp->userbits&STATEBITS) != GNDPORT) continue;
1510
/* any other port type */
1511
if ((pp->userbits&STATEBITS) == INPORT || (pp->userbits&STATEBITS) == OUTPORT ||
1512
(pp->userbits&STATEBITS) == PWRPORT || (pp->userbits&STATEBITS) == GNDPORT)
1516
if (special == BLOCKMOSTRAN)
1518
/* ignore electrically connected ports */
1519
for(opp = np->firstportproto; opp != pp; opp = opp->nextportproto)
1520
if (opp->network == pp->network) break;
1521
if (opp != pp) continue;
1523
if (special == BLOCKPOSLOGIC || special == BLOCKBUFFER || special == BLOCKINVERTER ||
1524
special == BLOCKNAND || special == BLOCKNOR || special == BLOCKXNOR)
1526
/* ignore ports not named "a" or "y" */
1527
if (strcmp(pp->protoname, "a") != 0 && strcmp(pp->protoname, "y") != 0)
1533
if (special == BLOCKFLOPTS || special == BLOCKFLOPDS)
1535
/* ignore ports not named "i1", "ck", "preset", or "q" */
1536
if (strcmp(pp->protoname, "i1") != 0 && strcmp(pp->protoname, "ck") != 0 &&
1537
strcmp(pp->protoname, "preset") != 0 && strcmp(pp->protoname, "q") != 0)
1543
if (special == BLOCKFLOPTR || special == BLOCKFLOPDR)
1545
/* ignore ports not named "i1", "ck", "clear", or "q" */
1546
if (strcmp(pp->protoname, "i1") != 0 && strcmp(pp->protoname, "ck") != 0 &&
1547
strcmp(pp->protoname, "clear") != 0 && strcmp(pp->protoname, "q") != 0)
1554
/* if multiple connections, get them all */
1555
if ((pp->userbits&PORTISOLATED) != 0)
1557
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1559
if (pi->proto != pp) continue;
1560
ai = pi->conarcinst;
1561
if (((ai->proto->userbits&AFUNCTION)>>AFUNCTIONSH) == APNONELEC) continue;
1562
if (first != 0) (void)addstringtoinfstr(", "); first = 1;
1563
if ((ai->userbits&ISNEGATED) != 0)
1565
if ((ai->end[0].portarcinst == pi && (ai->userbits&REVERSEEND) == 0) ||
1566
(ai->end[1].portarcinst == pi && (ai->userbits&REVERSEEND) != 0))
1568
(void)sprintf(line, "PINV%ld", ai->temp1);
1569
(void)addstringtoinfstr(line);
1574
if (net->namecount > 0) vhdl_addstring(net->netname, ni->parent); else
1575
(void)addstringtoinfstr(describenetwork(net));
1580
/* get connection */
1581
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1582
if (pi->proto->network == pp->network) break;
1583
if (pi != NOPORTARCINST)
1585
ai = pi->conarcinst;
1586
if (((ai->proto->userbits&AFUNCTION)>>AFUNCTIONSH) != APNONELEC)
1588
if (first != 0) (void)addstringtoinfstr(", "); first = 1;
1589
if ((ai->userbits&ISNEGATED) != 0 && ai->temp1 != 0)
1591
if ((ai->end[0].portarcinst == pi && (ai->userbits&REVERSEEND) == 0) ||
1592
(ai->end[1].portarcinst == pi && (ai->userbits&REVERSEEND) != 0))
1594
(void)sprintf(line, "PINV%ld", ai->temp1);
1595
(void)addstringtoinfstr(line);
1601
if (net->signals > 1)
1603
for(i=0; i<net->signals; i++)
1605
if (i != 0) (void)addstringtoinfstr(", ");
1606
subnet = net->networklist[i];
1607
if (subnet->namecount > 0) vhdl_addstring(subnet->netname, ni->parent); else
1608
(void)addstringtoinfstr(describenetwork(subnet));
1612
if (net->namecount > 0) vhdl_addstring(net->netname, ni->parent); else
1613
(void)addstringtoinfstr(describenetwork(net));
1619
/* see if this is an export */
1620
for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
1621
if (pe->proto->network == pp->network) break;
1622
if (pe != NOPORTEXPINST)
1624
if (first != 0) (void)addstringtoinfstr(", "); first = 1;
1625
vhdl_addstring(pe->exportproto->protoname, ni->parent);
1629
/* port is not connected or an export */
1630
if (first != 0) (void)addstringtoinfstr(", "); first = 1;
1631
(void)addstringtoinfstr("open");
1632
ttyputmsg(_("Warning: port %s of node %s is not connected"),
1633
cpp->protoname, describenodeinst(ni));
1639
* routine to return the VHDL name to use for node "ni". Returns a "special" value
1640
* that indicates the nature of the node.
1641
* BLOCKNORMAL: no special port arrangements necessary
1642
* BLOCKMOSTRAN: only output ports that are not electrically connected
1643
* BLOCKBUFFER: only include input port "a" and output port "y"
1644
* BLOCKPOSLOGIC: only include input port "a" and output port "y"
1645
* BLOCKINVERTER: only include input port "a" and output port "y"
1646
* BLOCKNAND: only include input port "a" and output port "y"
1647
* BLOCKNOR: only include input port "a" and output port "y"
1648
* BLOCKXNOR: only include input port "a" and output port "y"
1649
* BLOCKFLOPTS: only include input ports "i1", "ck", "preset" and output port "q"
1650
* BLOCKFLOPTR: only include input ports "i1", "ck", "clear" and output port "q"
1651
* BLOCKFLOPDS: only include input ports "i1", "ck", "preset" and output port "q"
1652
* BLOCKFLOPDR: only include input ports "i1", "ck", "clear" and output port "q"
1653
* BLOCKFLOP: include input ports "i1", "i2", "ck", "preset", "clear", and output ports "q" and "qb"
1655
char *vhdl_primname(NODEINST *ni, INTBIG *special)
1657
REGISTER INTBIG k, inport, isneg;
1658
static INTBIG tech_vhdl_names_key = 0;
1659
REGISTER char *str, *ptr;
1660
REGISTER VARIABLE *var;
1661
REGISTER PORTARCINST *pi;
1662
REGISTER PORTEXPINST *pe;
1663
REGISTER PORTPROTO *pp;
1664
REGISTER ARCINST *ai;
1668
if (tech_vhdl_names_key == 0) tech_vhdl_names_key = makekey("TECH_vhdl_names");
1670
/* facet instances are easy */
1671
*special = BLOCKNORMAL;
1672
if (ni->proto->primindex == 0) return(ni->proto->cell->cellname);
1674
/* get the primitive function */
1675
k = nodefunction(ni);
1679
case NPTRANMOS: case NPTRA4NMOS:
1680
var = getval((INTBIG)ni, VNODEINST, -1, "SIM_weak_node");
1681
if (var == NOVARIABLE) (void)strcpy(pt, "nMOStran"); else
1682
(void)strcpy(pt, "nMOStranWeak");
1683
*special = BLOCKMOSTRAN;
1685
case NPTRADMOS: case NPTRA4DMOS:
1686
(void)strcpy(pt, "DMOStran");
1687
*special = BLOCKMOSTRAN;
1689
case NPTRAPMOS: case NPTRA4PMOS:
1690
var = getval((INTBIG)ni, VNODEINST, -1, "SIM_weak_node");
1691
if (var == NOVARIABLE) (void)strcpy(pt, "PMOStran"); else
1692
(void)strcpy(pt, "pMOStranWeak");
1693
*special = BLOCKMOSTRAN;
1695
case NPTRANPN: case NPTRA4NPN:
1696
(void)strcpy(pt, "NPNtran");
1698
case NPTRAPNP: case NPTRA4PNP:
1699
(void)strcpy(pt, "PNPtran");
1701
case NPTRANJFET: case NPTRA4NJFET:
1702
(void)strcpy(pt, "NJFET");
1704
case NPTRAPJFET: case NPTRA4PJFET:
1705
(void)strcpy(pt, "PJFET");
1707
case NPTRADMES: case NPTRA4DMES:
1708
(void)strcpy(pt, "DMEStran");
1710
case NPTRAEMES: case NPTRA4EMES:
1711
(void)strcpy(pt, "EMEStran");
1715
switch (ni->userbits&FFTYPE)
1718
(void)strcpy(pt, "rsff");
1719
*special = BLOCKFLOP;
1722
(void)strcpy(pt, "jkff");
1723
*special = BLOCKFLOP;
1726
(void)strcpy(pt, "dsff");
1727
*special = BLOCKFLOPDS;
1728
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1730
if (namesame(pi->proto->protoname, "clear") == 0)
1732
(void)strcpy(pt, "drff");
1733
*special = BLOCKFLOPDR;
1739
(void)strcpy(pt, "tsff");
1740
*special = BLOCKFLOPTS;
1741
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1743
if (namesame(pi->proto->protoname, "clear") == 0)
1745
(void)strcpy(pt, "trff");
1746
*special = BLOCKFLOPTR;
1752
(void)strcpy(pt, "fflop");
1753
*special = BLOCKFLOP;
1759
var = getvalkey((INTBIG)el_curtech, VTECHNOLOGY, VSTRING|VISARRAY, tech_vhdl_names_key);
1760
if (var == NOVARIABLE) str = "buffer/inverter"; else
1761
str = ((char **)var->addr)[ni->proto->primindex-1];
1762
*special = BLOCKBUFFER;
1763
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1765
if (strcmp(pi->proto->protoname, "y") != 0) continue;
1766
ai = pi->conarcinst;
1767
if ((ai->userbits&ISNEGATED) == 0) continue;
1768
if (ai->end[0].portarcinst == pi && (ai->userbits&REVERSEEND) == 0) break;
1769
if (ai->end[1].portarcinst == pi && (ai->userbits&REVERSEEND) != 0) break;
1771
if (pi != NOPORTARCINST)
1773
for(ptr = str; *ptr != 0; ptr++) if (*ptr == '/') break;
1774
if (*ptr == '/') strcpy(pt, &ptr[1]); else
1776
*special = BLOCKINVERTER;
1781
for(ptr = pt; *ptr != 0; ptr++) if (*ptr == '/') break;
1782
if (*ptr == '/') *ptr = 0;
1786
var = getvalkey((INTBIG)el_curtech, VTECHNOLOGY, VSTRING|VISARRAY, tech_vhdl_names_key);
1787
if (var == NOVARIABLE) str = "and%ld/nand%ld"; else
1788
str = ((char **)var->addr)[ni->proto->primindex-1];
1790
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1792
if (strcmp(pi->proto->protoname, "a") == 0) inport++;
1793
if (strcmp(pi->proto->protoname, "y") != 0) continue;
1794
ai = pi->conarcinst;
1795
if ((ai->userbits&ISNEGATED) == 0) continue;
1796
if (ai->end[0].portarcinst == pi && (ai->userbits&REVERSEEND) == 0) isneg++;
1797
if (ai->end[1].portarcinst == pi && (ai->userbits&REVERSEEND) != 0) isneg++;
1801
for(ptr = str; *ptr != 0; ptr++) if (*ptr == '/') break;
1802
if (*ptr == '/') (void)sprintf(pt, &ptr[1], inport); else
1803
(void)sprintf(pt, str, inport);
1804
*special = BLOCKNAND;
1808
(void)sprintf(pt, str, inport);
1809
for(ptr = pt; *ptr != 0; ptr++) if (*ptr == '/') break;
1810
if (*ptr == '/') *ptr = 0;
1811
*special = BLOCKPOSLOGIC;
1815
var = getvalkey((INTBIG)el_curtech, VTECHNOLOGY, VSTRING|VISARRAY, tech_vhdl_names_key);
1816
if (var == NOVARIABLE) str = "or%ld/nor%ld"; else
1817
str = ((char **)var->addr)[ni->proto->primindex-1];
1819
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1821
if (strcmp(pi->proto->protoname, "a") == 0) inport++;
1822
if (strcmp(pi->proto->protoname, "y") != 0) continue;
1823
ai = pi->conarcinst;
1824
if ((ai->userbits&ISNEGATED) == 0) continue;
1825
if (ai->end[0].portarcinst == pi && (ai->userbits&REVERSEEND) == 0) isneg++;
1826
if (ai->end[1].portarcinst == pi && (ai->userbits&REVERSEEND) != 0) isneg++;
1830
for(ptr = str; *ptr != 0; ptr++) if (*ptr == '/') break;
1831
if (*ptr == '/') (void)sprintf(pt, &ptr[1], inport); else
1832
(void)sprintf(pt, str, inport);
1833
*special = BLOCKNOR;
1837
(void)sprintf(pt, str, inport);
1838
for(ptr = pt; *ptr != 0; ptr++) if (*ptr == '/') break;
1839
if (*ptr == '/') *ptr = 0;
1840
*special = BLOCKPOSLOGIC;
1844
var = getvalkey((INTBIG)el_curtech, VTECHNOLOGY, VSTRING|VISARRAY, tech_vhdl_names_key);
1845
if (var == NOVARIABLE) str = "xor%ld/xnor%ld"; else
1846
str = ((char **)var->addr)[ni->proto->primindex-1];
1848
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1850
if (strcmp(pi->proto->protoname, "a") == 0) inport++;
1851
if (strcmp(pi->proto->protoname, "y") != 0) continue;
1852
ai = pi->conarcinst;
1853
if ((ai->userbits&ISNEGATED) == 0) continue;
1854
if (ai->end[0].portarcinst == pi && (ai->userbits&REVERSEEND) == 0) isneg++;
1855
if (ai->end[1].portarcinst == pi && (ai->userbits&REVERSEEND) != 0) isneg++;
1859
for(ptr = str; *ptr != 0; ptr++) if (*ptr == '/') break;
1860
if (*ptr == '/') (void)sprintf(pt, &ptr[1], inport); else
1861
(void)sprintf(pt, str, inport);
1862
*special = BLOCKNOR;
1866
(void)sprintf(pt, str, inport);
1867
for(ptr = pt; *ptr != 0; ptr++) if (*ptr == '/') break;
1868
if (*ptr == '/') *ptr = 0;
1869
*special = BLOCKPOSLOGIC;
1873
var = getvalkey((INTBIG)el_curtech, VTECHNOLOGY, VSTRING|VISARRAY, tech_vhdl_names_key);
1874
if (var == NOVARIABLE) str = "mux%ld"; else
1875
str = ((char **)var->addr)[ni->proto->primindex-1];
1878
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
1879
if (strcmp(pi->proto->protoname, "a") == 0) inport++;
1880
(void)sprintf(pt, str, inport);
1883
strcpy(pt, "power");
1886
strcpy(pt, "ground");
1891
/* if the node has an export with power/ground, make it that */
1892
for(pe = ni->firstportexpinst; pe != NOPORTEXPINST; pe = pe->nextportexpinst)
1894
pp = pe->exportproto;
1895
if (portispower(pp))
1897
strcpy(pt, "power");
1900
if (portisground(pp))
1902
strcpy(pt, "ground");
1911
* Routine to add the string "orig" to the infinite string.
1912
* If "environment" is not NONODEPROTO, it is the facet in which this signal is
1913
* to reside, and if that facet has nodes with this name, the signal must be renamed.
1915
void vhdl_addstring(char *orig, NODEPROTO *environment)
1918
REGISTER INTBIG len, nonalnum;
1919
REGISTER NODEINST *ni;
1921
/* remove all nonVHDL characters while adding to current string */
1923
for(pt = orig; *pt != 0; pt++)
1924
if (isalnum(*pt)) (void)addtoinfstr(*pt); else
1926
(void)addtoinfstr('_');
1930
/* if there were nonalphanumeric characters, this cannot be a VHDL keyword */
1933
/* check for VHDL keyword clashes */
1935
if (vhdl_iskeyword(orig, len) != NOVKEYWORD)
1937
(void)addstringtoinfstr("NV");
1941
/* "bit" isn't a keyword, but the compiler can't handle it */
1942
if (namesame(orig, "bit") == 0)
1944
(void)addstringtoinfstr("NV");
1949
/* see if there is a name clash */
1950
if (environment != NONODEPROTO)
1952
for(ni = environment->firstnodeinst; ni != NONODEINST; ni = ni->nextnodeinst)
1954
if (ni->proto->primindex != 0) continue;
1955
if (namesame(orig, ni->proto->cell->cellname) == 0) break;
1957
if (ni != NONODEINST)
1959
(void)addstringtoinfstr("NV");
1966
* routine to add, to the infinite string, VHDL for the ports on instance "ni"
1967
* (which is of prototype "np"). If "ni" is NONODEINST, use only prototype information,
1968
* otherwise, treat each connection on an isolated port as a separate port.
1969
* If "special" is BLOCKMOSTRAN, only list ports that are not electrically connected.
1970
* If "special" is BLOCKPOSLOGIC, BLOCKBUFFER or BLOCKINVERTER, only include input
1971
* port "a" and output port "y".
1972
* If "special" is BLOCKFLOPTS or BLOCKFLOPDS, only include input ports "i1", "ck", "preset"
1973
* and output port "q".
1974
* If "special" is BLOCKFLOPTR or BLOCKFLOPDR, only include input ports "i1", "ck", "clear"
1975
* and output port "q".
1977
void vhdl_addportlist(NODEINST *ni, NODEPROTO *np, INTBIG special)
1979
REGISTER PORTPROTO *pp, *opp;
1980
REGISTER NODEPROTO *cnp;
1983
if (special == BLOCKFLOPTS || special == BLOCKFLOPDS)
1985
(void)addstringtoinfstr("i1, ck, preset: in BIT; q: out BIT");
1988
if (special == BLOCKFLOPTR || special == BLOCKFLOPDR)
1990
(void)addstringtoinfstr("i1, ck, clear: in BIT; q: out BIT");
1994
/* if this is an icon, use the contents */
1995
if (np->primindex == 0 && np->cellview == el_iconview)
1997
cnp = contentsview(np);
1998
if (cnp != NONODEPROTO)
2000
/* make sure that the ports correspond */
2001
for(pp = cnp->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
2002
(void)equivalentport(cnp, pp, np);
2003
for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
2004
(void)equivalentport(np, pp, cnp);
2009
/* flag important ports */
2010
for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
2013
if (special == BLOCKMOSTRAN)
2015
/* ignore ports that are electrically connected to previous ones */
2016
for(opp = np->firstportproto; opp != pp; opp = opp->nextportproto)
2017
if (opp->network == pp->network) break;
2018
if (opp != pp) { pp->temp1 = 1; continue; }
2020
if (special == BLOCKPOSLOGIC || special == BLOCKBUFFER || special == BLOCKINVERTER)
2022
/* ignore ports not named "a" or "y" */
2023
if (strcmp(pp->protoname, "a") != 0 && strcmp(pp->protoname, "y") != 0)
2031
(void)strcpy(before, "");
2032
vhdl_addtheseports(ni, np, INPORT, before);
2033
vhdl_addtheseports(ni, np, OUTPORT, before);
2034
vhdl_addtheseports(ni, np, PWRPORT, before);
2035
vhdl_addtheseports(ni, np, GNDPORT, before);
2036
vhdl_addtheseports(ni, np, 0, before);
2039
void vhdl_addtheseports(NODEINST *ni, NODEPROTO *np, INTBIG bits, char *before)
2041
REGISTER PORTPROTO *pp;
2042
REGISTER PORTARCINST *pi;
2043
REGISTER BOOLEAN didsome;
2044
REGISTER INTBIG i, count, inst;
2045
char instname[10], **strings;
2048
for(pp = np->firstportproto; pp != NOPORTPROTO; pp = pp->nextportproto)
2050
#ifdef IGNORE4PORTTRANSISTORS
2051
if (np == sch_transistor4prim)
2053
if (namesame(pp->protoname, "b") == 0) continue;
2056
if (pp->temp1 != 0) continue;
2059
if ((pp->userbits&STATEBITS) == INPORT || (pp->userbits&STATEBITS) == OUTPORT ||
2060
(pp->userbits&STATEBITS) == PWRPORT || (pp->userbits&STATEBITS) == GNDPORT)
2064
if ((INTBIG)((pp->userbits&STATEBITS)) != bits) continue;
2066
if (ni != NONODEINST && (pp->userbits&PORTISOLATED) != 0)
2069
for(pi = ni->firstportarcinst; pi != NOPORTARCINST; pi = pi->nextportarcinst)
2071
if (pi->proto != pp) continue;
2072
count = net_evalbusname(APBUS, pp->protoname, &strings, NOARCINST, np, 0);
2073
for(i=0; i<count; i++)
2075
(void)addstringtoinfstr(before);
2076
(void)strcpy(before, ", ");
2077
vhdl_addstring(strings[i], np);
2078
(void)sprintf(instname, "%ld", inst);
2079
(void)addstringtoinfstr(instname);
2086
count = net_evalbusname(APBUS, pp->protoname, &strings, NOARCINST, np, 0);
2087
for(i=0; i<count; i++)
2089
(void)addstringtoinfstr(before);
2090
(void)strcpy(before, ", ");
2091
vhdl_addstring(strings[i], np);
2100
(void)addstringtoinfstr(": in BIT");
2101
} else if (bits == OUTPORT || bits == PWRPORT || bits == GNDPORT)
2103
(void)addstringtoinfstr(": out BIT");
2106
(void)addstringtoinfstr(": inout BIT");
2108
(void)strcpy(before, "; ");
2112
/****************************** COMPILATION ******************************/
2115
* routine to compile the VHDL in "basefacet" (or wherever the related VHDL
2116
* view is). If "toplevel" is nonzero, this network is the final output, so
2117
* it MUST be recompiled if any subfacets have changed. Returns true
2120
BOOLEAN vhdl_compile(NODEPROTO *basefacet)
2122
char *intended, *fromintended;
2125
REGISTER VARIABLE *var;
2126
UINTBIG netlistdate, vhdldate;
2128
BOOLEAN vhdlondisk, netlistondisk;
2130
/* determine netlist type */
2131
switch (vhdl_target)
2133
case TARGET_ALS: filetype = sim_filetypeals; break;
2134
case TARGET_NETLISP: filetype = sim_filetypenetlisp; break;
2135
case TARGET_RSIM: filetype = sim_filetypersim; break;
2136
case TARGET_SILOS: filetype = sim_filetypesilos; break;
2137
case TARGET_QUISC: filetype = sim_filetypequisc; break;
2140
var = getvalkey((INTBIG)vhdl_tool, VTOOL, VINTEGER, vhdl_vhdlondiskkey);
2142
if (var != NOVARIABLE && var->addr != 0) vhdlondisk = TRUE;
2143
var = getvalkey((INTBIG)vhdl_tool, VTOOL, VINTEGER, vhdl_netlistondiskkey);
2144
netlistondisk = FALSE;
2145
if (var != NOVARIABLE && var->addr != 0) netlistondisk = TRUE;
2147
/* see if there is netlist associated with this facet */
2148
if (vhdl_startinput(basefacet, filetype, netlistondisk, &intended, &netlistdate) == 0)
2153
/* got netlist, don't need to read it, just wanted the date and existence */
2158
if (vhdl_startinput(basefacet, io_filetypevhdl, vhdlondisk, &intended, &vhdldate) != 0)
2160
/* issue error if this isn't an icon */
2161
if (basefacet->cellview != el_iconview)
2162
ttyputerr(_("Cannot find VHDL for %s"), basefacet->cell->cellname);
2166
/* if there is a newer netlist, stop now */
2167
if (!err && netlistdate >= vhdldate)
2173
/* build and clear vhdl_identtable */
2174
if (vhdl_identtable == 0)
2176
vhdl_identtable = (IDENTTABLE *)emalloc((INTBIG)IDENT_TABLE_SIZE *
2177
(INTBIG)(sizeof (IDENTTABLE)), vhdl_tool->cluster);
2178
if (vhdl_identtable == 0) return(TRUE);
2179
for (i = 0; i < IDENT_TABLE_SIZE; i++)
2180
vhdl_identtable[i].string = (char *)0;
2183
if (allocstring(&fromintended, intended, el_tempcluster)) return(TRUE);
2184
vhdl_errorcount = 0;
2186
(void)vhdl_endinput();
2187
err = vhdl_parser(vhdl_tliststart);
2188
if (!err) err = vhdl_semantic();
2191
ttyputmsg(_("ERRORS during compilation, no output produced"));
2192
efree(fromintended);
2196
/* prepare to create netlist */
2197
retval = vhdl_startoutput(basefacet, filetype, netlistondisk, &intended);
2200
if (retval > 0) ttyputerr(_("Cannot write %s"), intended);
2203
ttyputmsg(_("Compiling VHDL in %s, writing netlist to %s"), fromintended, intended);
2204
efree(fromintended);
2207
switch (vhdl_target)
2209
case TARGET_ALS: vhdl_genals(vhdl_lib, basefacet); break;
2210
case TARGET_NETLISP: vhdl_gennet(vhdl_target); break;
2211
case TARGET_RSIM: vhdl_gennet(vhdl_target); break;
2212
case TARGET_SILOS: vhdl_gensilos(); break;
2213
case TARGET_QUISC: vhdl_genquisc(); break;
2222
Module: vhdl_scanner
2223
------------------------------------------------------------------------
2225
Lexical scanner of input file creating token list.
2226
------------------------------------------------------------------------
2227
Calling Sequence: vhdl_scanner();
2228
------------------------------------------------------------------------
2230
void vhdl_scanner(void)
2232
char *c, buffer[MAXVHDLLINE], *end, tchar;
2233
INTBIG line_num, space;
2236
/* start by clearing previous scanner memory */
2237
vhdl_freescannermemory();
2244
line_num = vhdl_getnextline(buffer);
2245
if (line_num == 0) return;
2248
} else if (isspace(*c)) space = TRUE; else
2250
while (isspace(*c)) c++;
2251
if (*c == 0) continue;
2254
/* could be identifier (keyword) or bit string literal */
2255
if (*(c + 1) == '"')
2257
if ((tchar = vhdl_toupper(*c)) == 'B')
2260
} else if (tchar == '0')
2263
} else if (tchar == 'X')
2269
while (isalnum(*end) || *end == '_') end++;
2271
/* got alphanumeric from c to end - 1 */
2272
if ((key = vhdl_iskeyword(c, (INTBIG)(end - c))) != NOVKEYWORD)
2274
vhdl_makekeytoken(key, line_num, (INTBIG)space);
2277
vhdl_makeidenttoken(c, (INTBIG)(end - c), line_num, (INTBIG)space);
2280
} else if (isdigit(*c))
2282
/* could be decimal or based literal */
2284
while (isdigit(*end) || *end == '_') end++;
2286
/* got numeric from c to end - 1 */
2287
vhdl_makedecimaltoken(c, (INTBIG)(end - c), line_num, (INTBIG)space);
2294
/* got a start of a string */
2296
while (*end != '\n')
2300
if (*(end + 1) == '"') end++; else
2305
/* string from c + 1 to end - 1 */
2306
vhdl_makestrtoken(c + 1, (INTBIG)(end - c - 1), line_num, (INTBIG)space);
2307
if (*end == '"') end++;
2311
vhdl_maketoken((INTBIG)TOKEN_AMPERSAND, line_num, (INTBIG)space);
2315
/* character literal */
2316
if (isgraph(*(c + 1)) && *(c + 2) == '\'')
2318
vhdl_makechartoken(*(c + 1), line_num, (INTBIG)space);
2323
vhdl_maketoken((INTBIG)TOKEN_LEFTBRACKET, line_num, (INTBIG)space);
2327
vhdl_maketoken((INTBIG)TOKEN_RIGHTBRACKET, line_num, (INTBIG)space);
2331
/* could be STAR or DOUBLESTAR */
2332
if (*(c + 1) == '*')
2334
vhdl_maketoken((INTBIG)TOKEN_DOUBLESTAR, line_num, (INTBIG)space);
2338
vhdl_maketoken((INTBIG)TOKEN_STAR, line_num, (INTBIG)space);
2343
vhdl_maketoken((INTBIG)TOKEN_PLUS, line_num, (INTBIG)space);
2347
vhdl_maketoken((INTBIG)TOKEN_COMMA, line_num, (INTBIG)space);
2351
if (*(c + 1) == '-')
2353
/* got a comment, throw away rest of line */
2354
c = buffer + strlen(buffer);
2357
/* got a minus sign */
2358
vhdl_maketoken((INTBIG)TOKEN_MINUS, line_num, (INTBIG)space);
2363
/* could be PERIOD or DOUBLEDOT */
2364
if (*(c + 1) == '.')
2366
vhdl_maketoken((INTBIG)TOKEN_DOUBLEDOT, line_num, (INTBIG)space);
2370
vhdl_maketoken((INTBIG)TOKEN_PERIOD, line_num, (INTBIG)space);
2375
/* could be SLASH or NE */
2376
if (*(c + 1) == '=')
2378
vhdl_maketoken((INTBIG)TOKEN_NE, line_num, (INTBIG)space);
2382
vhdl_maketoken((INTBIG)TOKEN_SLASH, line_num, (INTBIG)space);
2387
/* could be COLON or VARASSIGN */
2388
if (*(c + 1) == '=')
2390
vhdl_maketoken((INTBIG)TOKEN_VARASSIGN, line_num, (INTBIG)space);
2394
vhdl_maketoken((INTBIG)TOKEN_COLON, line_num, (INTBIG)space);
2399
vhdl_maketoken((INTBIG)TOKEN_SEMICOLON, line_num, (INTBIG)space);
2403
/* could be LT or LE or BOX */
2407
vhdl_maketoken((INTBIG)TOKEN_LE, line_num, (INTBIG)space);
2411
vhdl_maketoken((INTBIG)TOKEN_BOX, line_num, (INTBIG)space);
2415
vhdl_maketoken((INTBIG)TOKEN_LT, line_num, (INTBIG)space);
2421
/* could be EQUAL or double delimiter ARROW */
2422
if (*(c + 1) == '>')
2424
vhdl_maketoken((INTBIG)TOKEN_ARROW, line_num, (INTBIG)space);
2428
vhdl_maketoken((INTBIG)TOKEN_EQ, line_num, (INTBIG)space);
2433
/* could be GT or GE */
2434
if (*(c + 1) == '=')
2436
vhdl_maketoken((INTBIG)TOKEN_GE, line_num, (INTBIG)space);
2440
vhdl_maketoken((INTBIG)TOKEN_GT, line_num, (INTBIG)space);
2445
vhdl_maketoken((INTBIG)TOKEN_VERTICALBAR, line_num, (INTBIG)space);
2449
/* AJ vhdl_makestrtoken(TOKEN_UNKNOWN, c, 1, line_num, space); */
2450
vhdl_maketoken((INTBIG)TOKEN_UNKNOWN, line_num, (INTBIG)space);
2459
Module: vhdl_makekeytoken
2460
------------------------------------------------------------------------
2462
Add a token to the token list which has a key reference.
2463
------------------------------------------------------------------------
2464
Calling Sequence: vhdl_makekeytoken(key, line_num, space);
2466
Name Type Description
2467
---- ---- -----------
2468
key *VKEYWORD Pointer to keyword in table.
2469
line_num INTBIG Line number of occurence.
2470
space INTBIG Previous space flag.
2471
------------------------------------------------------------------------
2473
void vhdl_makekeytoken(VKEYWORD *key, INTBIG line_num, INTBIG space)
2475
TOKENLIST *newtoken;
2477
newtoken = (TOKENLIST *)emalloc((INTBIG)sizeof(TOKENLIST), vhdl_tool->cluster);
2478
newtoken->token = TOKEN_KEYWORD;
2479
newtoken->pointer = (char *)key;
2480
newtoken->line_num = line_num;
2481
newtoken->space = TRUE;
2482
newtoken->next = NOTOKENLIST;
2483
newtoken->last = vhdl_tlistend;
2484
if (vhdl_tlistend == NOTOKENLIST)
2486
vhdl_tliststart = vhdl_tlistend = newtoken;
2489
vhdl_tlistend->space = space;
2490
vhdl_tlistend->next = newtoken;
2491
vhdl_tlistend = newtoken;
2496
Module: vhdl_makeidenttoken
2497
------------------------------------------------------------------------
2499
Add a identity token to the token list which has a string reference.
2500
------------------------------------------------------------------------
2501
Calling Sequence: vhdl_makeidenttoken(str, length, line_num, space);
2503
Name Type Description
2504
---- ---- -----------
2505
str *char Pointer to start of string (not 0 term).
2506
length INTBIG Length of string.
2507
line_num INTBIG Line number of occurence.
2508
space INTBIG Previous space flag.
2509
------------------------------------------------------------------------
2511
void vhdl_makeidenttoken(char *str, INTBIG length, INTBIG line_num, INTBIG space)
2513
TOKENLIST *newtoken;
2517
newtoken = (TOKENLIST *)emalloc((INTBIG)sizeof(TOKENLIST), vhdl_tool->cluster);
2518
newtoken->token = TOKEN_IDENTIFIER;
2519
newstring = (char *)emalloc((INTBIG)length + 1, vhdl_tool->cluster);
2520
strncpy(newstring, str, length);
2521
newstring[length] = 0;
2523
/* check if ident exits in the global name space */
2524
if ((ikey = vhdl_findidentkey(newstring)) == (IDENTTABLE *)0)
2526
ikey = vhdl_makeidentkey(newstring);
2527
if (ikey == 0) return;
2528
} else efree(newstring);
2529
newtoken->pointer = (char *)ikey;
2530
newtoken->line_num = line_num;
2531
newtoken->space = TRUE;
2532
newtoken->next = NOTOKENLIST;
2533
newtoken->last = vhdl_tlistend;
2534
if (vhdl_tlistend == NOTOKENLIST)
2536
vhdl_tliststart = vhdl_tlistend = newtoken;
2539
vhdl_tlistend->space = space;
2540
vhdl_tlistend->next = newtoken;
2541
vhdl_tlistend = newtoken;
2546
Module: vhdl_makestrtoken
2547
------------------------------------------------------------------------
2549
Add a string token to the token list. Note that two adjacent double
2550
quotes should be mergered into one.
2551
------------------------------------------------------------------------
2552
Calling Sequence: vhdl_makestrtoken(string, length, line_num, space);
2554
Name Type Description
2555
---- ---- -----------
2556
string *char Pointer to start of string (not 0 term).
2557
length INTBIG Length of string.
2558
line_num INTBIG Line number of occurence.
2559
space INTBIG Previous space flag.
2560
------------------------------------------------------------------------
2562
void vhdl_makestrtoken(char *string, INTBIG length, INTBIG line_num, INTBIG space)
2564
TOKENLIST *newtoken;
2565
char *newstring, *str, *str2;
2567
newtoken = (TOKENLIST *)emalloc((INTBIG)sizeof(TOKENLIST), vhdl_tool->cluster);
2568
newtoken->token = TOKEN_STRING;
2569
newstring = (char *)emalloc((INTBIG)length + 1, vhdl_tool->cluster);
2570
strncpy(newstring, string, length);
2571
newstring[length] = 0;
2573
/* merge two adjacent double quotes */
2579
if (*(str + 1) == '"')
2584
*str2 = *(str2 + 1);
2586
} while (*str2 != 0);
2591
newtoken->pointer = newstring;
2592
newtoken->line_num = line_num;
2593
newtoken->space = TRUE;
2594
newtoken->next = NOTOKENLIST;
2595
newtoken->last = vhdl_tlistend;
2596
if (vhdl_tlistend == NOTOKENLIST)
2598
vhdl_tliststart = vhdl_tlistend = newtoken;
2601
vhdl_tlistend->space = space;
2602
vhdl_tlistend->next = newtoken;
2603
vhdl_tlistend = newtoken;
2608
Module: vhdl_makedecimaltoken
2609
------------------------------------------------------------------------
2611
Add a numeric token to the token list which has a string reference.
2612
------------------------------------------------------------------------
2613
Calling Sequence: vhdl_makedecimaltoken(string, length, line_num, space);
2615
Name Type Description
2616
---- ---- -----------
2617
string *char Pointer to start of string (not 0 term).
2618
length INTBIG Length of string.
2619
line_num INTBIG Line number of occurence.
2620
space INTBIG Previous space flag.
2621
------------------------------------------------------------------------
2623
void vhdl_makedecimaltoken(char *string, INTBIG length, INTBIG line_num,
2626
TOKENLIST *newtoken;
2629
newtoken = (TOKENLIST *)emalloc((INTBIG)sizeof(TOKENLIST), vhdl_tool->cluster);
2630
newtoken->token = TOKEN_DECIMAL;
2631
newstring = (char *)emalloc((INTBIG)length + 1, vhdl_tool->cluster);
2632
strncpy(newstring, string, length);
2633
newstring[length] = 0;
2634
newtoken->pointer = newstring;
2635
newtoken->line_num = line_num;
2636
newtoken->space = TRUE;
2637
newtoken->next = NOTOKENLIST;
2638
newtoken->last = vhdl_tlistend;
2639
if (vhdl_tlistend == NOTOKENLIST)
2641
vhdl_tliststart = vhdl_tlistend = newtoken;
2644
vhdl_tlistend->space = space;
2645
vhdl_tlistend->next = newtoken;
2646
vhdl_tlistend = newtoken;
2651
Module: vhdl_maketoken
2652
------------------------------------------------------------------------
2654
Add a token to the token list which has no string reference.
2655
------------------------------------------------------------------------
2656
Calling Sequence: vhdl_maketoken(token, line_num, space);
2658
Name Type Description
2659
---- ---- -----------
2660
token INTBIG Token number.
2661
line_num INTBIG Line number of occurence.
2662
space INTBIG Previous space flag.
2663
------------------------------------------------------------------------
2665
void vhdl_maketoken(INTBIG token, INTBIG line_num, INTBIG space)
2667
TOKENLIST *newtoken;
2669
newtoken = (TOKENLIST *)emalloc((INTBIG)sizeof(TOKENLIST), vhdl_tool->cluster);
2670
newtoken->token = token;
2671
newtoken->pointer = (char *)0;
2672
newtoken->line_num = line_num;
2673
newtoken->space = TRUE;
2674
newtoken->next = NOTOKENLIST;
2675
newtoken->last = vhdl_tlistend;
2676
if (vhdl_tlistend == NOTOKENLIST)
2678
vhdl_tliststart = vhdl_tlistend = newtoken;
2681
vhdl_tlistend->space = space;
2682
vhdl_tlistend->next = newtoken;
2683
vhdl_tlistend = newtoken;
2688
Module: vhdl_makechartoken
2689
------------------------------------------------------------------------
2691
Make a character literal token.
2692
------------------------------------------------------------------------
2693
Calling Sequence: vhdl_makechartoken(c, line_num, space);
2695
Name Type Description
2696
---- ---- -----------
2697
c char Character literal.
2698
line_num INTBIG Number of source line.
2699
space INTBIG Previous space flag.
2700
------------------------------------------------------------------------
2702
void vhdl_makechartoken(char c, INTBIG line_num, INTBIG space)
2704
TOKENLIST *newtoken;
2706
newtoken = (TOKENLIST *)emalloc((INTBIG)sizeof(TOKENLIST), vhdl_tool->cluster);
2707
newtoken->token = TOKEN_CHAR;
2708
newtoken->pointer = (char *)((INTBIG)c);
2709
newtoken->line_num = line_num;
2710
newtoken->space = TRUE;
2711
newtoken->next = NOTOKENLIST;
2712
newtoken->last = vhdl_tlistend;
2713
if (vhdl_tlistend == NOTOKENLIST)
2715
vhdl_tliststart = vhdl_tlistend = newtoken;
2718
vhdl_tlistend->space = space;
2719
vhdl_tlistend->next = newtoken;
2720
vhdl_tlistend = newtoken;
2724
void vhdl_freescannermemory(void)
2726
TOKENLIST *tok, *nexttok;
2729
/* free parsed tokens */
2730
for(tok = vhdl_tliststart; tok != NOTOKENLIST; tok = nexttok)
2732
nexttok = tok->next;
2733
if (tok->token == TOKEN_STRING || tok->token == TOKEN_DECIMAL)
2734
efree(tok->pointer);
2737
vhdl_tliststart = vhdl_tlistend = NOTOKENLIST;
2739
/* clear identifier table */
2740
if (vhdl_identtable != 0)
2742
for (i = 0; i < IDENT_TABLE_SIZE; i++)
2743
if (vhdl_identtable[i].string != 0)
2745
efree(vhdl_identtable[i].string);
2746
vhdl_identtable[i].string = 0;
2752
Module: vhdl_iskeyword
2753
------------------------------------------------------------------------
2755
If the passed string is a keyword, return its address in the
2756
keyword table, else return NOVKEYWORD.
2757
------------------------------------------------------------------------
2758
Calling Sequence: key = vhdl_iskeyword(string, length);
2760
Name Type Description
2761
---- ---- -----------
2762
string *char Pointer to start of string (not 0 term).
2763
length INTBIG Length of string.
2764
key *VKEYWORD Pointer to entry in keywords table if
2765
keyword, else NOVKEYWORD.
2766
------------------------------------------------------------------------
2768
VKEYWORD *vhdl_iskeyword(char *string, INTBIG length)
2770
INTBIG aindex, num, check, base;
2771
char tstring[MAXVHDLLINE];
2773
if (length >= MAXVHDLLINE) return(NOVKEYWORD);
2774
for (aindex = 0; aindex < length; aindex++)
2775
tstring[aindex] = string[aindex];
2776
tstring[length] = 0;
2778
num = sizeof(vhdl_keywords) / sizeof(VKEYWORD);
2782
check = namesame(tstring, vhdl_keywords[base + aindex].name);
2783
if (check == 0) return(&vhdl_keywords[base + aindex]);
2799
Module: vhdl_findidentkey
2800
------------------------------------------------------------------------
2802
Search for the passed string in the global name space. Return
2803
a pointer to the ident table entry if found or 0 if not
2805
------------------------------------------------------------------------
2806
Calling Sequence: ikey = vhdl_findidentkey(string);
2808
Name Type Description
2809
---- ---- -----------
2810
string *char Pointer to string of name.
2811
ikey *IDENTTABLE Pointer to entry in table if found,
2813
------------------------------------------------------------------------
2815
IDENTTABLE *vhdl_findidentkey(char *string)
2820
attempt = vhdl_identfirsthash(string);
2823
ident = vhdl_identtable[attempt].string;
2824
if (ident == 0) break;
2825
if (namesame(string, ident) == 0) return(&(vhdl_identtable[attempt]));
2826
attempt = vhdl_identsecondhash(string, attempt);
2828
return((IDENTTABLE *)0);
2832
Module: vhdl_makeidentkey
2833
------------------------------------------------------------------------
2835
Make an entry for the passed string in the global name space.
2836
Return a pointer to the ident table entry created.
2837
Returns zero on error.
2838
------------------------------------------------------------------------
2839
Calling Sequence: ikey = vhdl_makeidentkey(string);
2841
Name Type Description
2842
---- ---- -----------
2843
string *char Pointer to string of name.
2844
ikey *IDENTTABLE Pointer to entry in table created.
2845
------------------------------------------------------------------------
2847
IDENTTABLE *vhdl_makeidentkey(char *string)
2849
INTBIG attempt, count;
2852
attempt = vhdl_identfirsthash(string);
2853
while (vhdl_identtable[attempt].string)
2855
if (++count >= MAX_HASH_TRYS)
2857
ttyputmsg(_("ERROR hashing identifier - tried %ld times"), count);
2860
attempt = vhdl_identsecondhash(string, attempt);
2862
vhdl_identtable[attempt].string = string;
2863
return(&vhdl_identtable[attempt]);
2867
Module: vhdl_identfirsthash
2868
------------------------------------------------------------------------
2870
Return the hash value for the passed string. The first hash
2873
value = ((firstchar << 7) + (lastchar << 4) + length) mod
2876
Note: lowercase letters are converted to uppercase.
2877
------------------------------------------------------------------------
2878
Calling Sequence: value = vhdl_identfirsthash(string);
2880
Name Type Description
2881
---- ---- -----------
2882
string *char Pointer to string to hash.
2883
value INTBIG Returned hash value.
2884
------------------------------------------------------------------------
2886
INTBIG vhdl_identfirsthash(char *string)
2888
REGISTER INTBIG length, value;
2890
length = (INTBIG)strlen(string);
2891
value = (vhdl_toupper(*string) & 0xFF) << 7;
2892
value += (vhdl_toupper(string[length - 1]) & 0xFF) << 4;
2893
value = (value + length) % IDENT_TABLE_SIZE;
2898
Module: vhdl_identsecondhash
2899
------------------------------------------------------------------------
2901
Return the hash value for the passed string. The second hash
2904
value = (previous_hash + ((summation of characters) << 4) +
2905
(length of string)) mod IDENT_TABLE_SIZE;
2906
------------------------------------------------------------------------
2907
Calling Sequence: value = vhdl_identsecondhash(string, first_hash);
2909
Name Type Description
2910
---- ---- -----------
2911
string *char Pointer to string to hash.
2912
previous_hash INTBIG Value of previous hash.
2913
value INTBIG Returned hash value.
2914
------------------------------------------------------------------------
2916
INTBIG vhdl_identsecondhash(char *string, INTBIG previous_hash)
2918
INTBIG length, value;
2922
for (sptr = string; *sptr; sptr++)
2923
value += (vhdl_toupper(*sptr) & 0xFF);
2925
length = strlen(string);
2926
value = (previous_hash + value + length) % IDENT_TABLE_SIZE;
2931
Module: vhdl_toupper
2932
------------------------------------------------------------------------
2934
Convert a character to uppercase if it is a lowercase letter only.
2935
------------------------------------------------------------------------
2936
Calling Sequence: c = vhdl_toupper(c);
2938
Name Type Description
2939
---- ---- -----------
2940
c char Character to be converted.
2941
------------------------------------------------------------------------
2943
char vhdl_toupper(char c)
2951
Module: vhdl_findtopinterface
2952
------------------------------------------------------------------------
2954
Find the top interface in the database. The top interface is defined
2955
as the interface is called by no other architectural bodies.
2956
------------------------------------------------------------------------
2957
Calling Sequence: top_interface = vhdl_findtopinterface(units);
2959
Name Type Description
2960
---- ---- -----------
2961
units *DBUNITS Pointer to database design units.
2962
top_interface *DBINTERFACE Pointer to top interface.
2963
------------------------------------------------------------------------
2965
DBINTERFACE *vhdl_findtopinterface(DBUNITS *units)
2967
DBINTERFACE *interfacef;
2969
DBCOMPONENTS *compo;
2972
/* clear flags of all interfaces in database */
2973
for (interfacef = units->interfaces; interfacef != NULL; interfacef = interfacef->next)
2974
interfacef->flags &= ~TOP_ENTITY_FLAG;
2976
/* go through the list of bodies and flag any interfaces */
2977
for (body = units->bodies; body != NULL; body = body->next)
2979
/* go through component list */
2980
if (body->declare == 0) continue;
2981
for (compo = body->declare->components; compo != NULL; compo = compo->next)
2983
symbol = vhdl_searchsymbol(compo->name, vhdl_gsymbols);
2984
if (symbol != NULL && symbol->pointer != NULL)
2986
((DBINTERFACE *)(symbol->pointer))->flags |= TOP_ENTITY_FLAG;
2991
/* find interface with the flag bit not set */
2992
for (interfacef = units->interfaces; interfacef != NULL; interfacef = interfacef->next)
2994
if (!(interfacef->flags & TOP_ENTITY_FLAG)) break;
2999
void vhdl_freeunresolvedlist(UNRESLIST **lstart)
3003
while (*lstart != 0)
3006
*lstart = (*lstart)->next;
3007
efree((char *)unres);
3012
Module: vhdl_unresolved
3013
------------------------------------------------------------------------
3015
Maintain a list of unresolved interfaces for later reporting.
3016
------------------------------------------------------------------------
3017
Calling Sequence: vhdl_unresolved(iname, lstart);
3019
Name Type Description
3020
---- ---- -----------
3021
iname *IDENTTABLE Pointer to global name space.
3022
lstart **UNRESLIST Address of start of list pointer;
3023
------------------------------------------------------------------------
3025
void vhdl_unresolved(IDENTTABLE *iname, UNRESLIST **lstart)
3029
for (ulist = *lstart; ulist != NULL; ulist = ulist->next)
3031
if (ulist->interfacef == iname) break;
3033
if (ulist) ulist->numref++; else
3035
ulist = (UNRESLIST *)emalloc((INTBIG)sizeof(UNRESLIST), vhdl_tool->cluster);
3036
ulist->interfacef = iname;
3038
ulist->next = *lstart;
3043
/****************************** VHDL OPTIONS DIALOG ******************************/
3046
static DIALOGITEM vhdl_optionsdialogitems[] =
3048
/* 1 */ {0, {336,244,360,308}, BUTTON, N_("OK")},
3049
/* 2 */ {0, {300,244,324,308}, BUTTON, N_("Cancel")},
3050
/* 3 */ {0, {308,4,324,166}, CHECK, N_("VHDL stored in facet")},
3051
/* 4 */ {0, {332,4,348,179}, CHECK, N_("Netlist stored in facet")},
3052
/* 5 */ {0, {28,8,224,319}, SCROLL, ""},
3053
/* 6 */ {0, {236,4,252,203}, MESSAGE, N_("VHDL for primitive:")},
3054
/* 7 */ {0, {260,4,276,203}, MESSAGE, N_("VHDL for negated primitive:")},
3055
/* 8 */ {0, {236,208,252,319}, EDITTEXT, ""},
3056
/* 9 */ {0, {260,208,276,319}, EDITTEXT, ""},
3057
/* 10 */ {0, {8,8,24,183}, MESSAGE, N_("Schematics primitives:")},
3058
/* 11 */ {0, {292,8,293,319}, DIVIDELINE, ""}
3060
static DIALOG vhdl_optionsdialog = {{50,75,419,403}, N_("VHDL Options"), 0, 11, vhdl_optionsdialogitems};
3062
/* special items for the "VHDL Options" dialog: */
3063
#define DVHO_VHDLINFACET 3 /* VHDL stored in facet (check) */
3064
#define DVHO_NETINFACET 4 /* Netlist stored in facet (check) */
3065
#define DVHO_PRIMLIST 5 /* List of schematics prims (scroll) */
3066
#define DVHO_UNNEGATEDNAME 8 /* Unnegated name (edit text) */
3067
#define DVHO_NEGATEDNAME 9 /* Negated name (edit text) */
3069
void vhdl_optionsdlog(void)
3072
REGISTER char **varnames, *pt, *opt;
3073
REGISTER VARIABLE *var;
3074
REGISTER TECHNOLOGY *tech;
3075
REGISTER NODEPROTO *np, **nplist;
3076
REGISTER INTBIG i, len, technameschanged;
3077
BOOLEAN vhdlondisk, netlistondisk, ondisk;
3079
if (DiaInitDialog(&vhdl_optionsdialog)) return;
3080
var = getval((INTBIG)vhdl_tool, VTOOL, VINTEGER, "VHDL_vhdl_on_disk");
3082
if (var != NOVARIABLE && var->addr != 0) vhdlondisk = TRUE;
3083
var = getval((INTBIG)vhdl_tool, VTOOL, VINTEGER, "VHDL_netlist_on_disk");
3084
netlistondisk = FALSE;
3085
if (var != NOVARIABLE && var->addr != 0) netlistondisk = TRUE;
3087
/* setup for generated names in the technology */
3089
DiaInitTextDialog(DVHO_PRIMLIST, DiaNullDlogList, DiaNullDlogItem, DiaNullDlogDone, 0,
3090
SCSELMOUSE|SCREPORT);
3091
var = getval((INTBIG)tech, VTECHNOLOGY, VSTRING|VISARRAY, "TECH_vhdl_names");
3092
if (var == NOVARIABLE)
3094
for(len=0, np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto, len++) ;
3095
varnames = (char **)emalloc(len * (sizeof (char *)), el_tempcluster);
3096
for(i=0, np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto, i++)
3098
varnames[i] = (char *)emalloc(1, el_tempcluster);
3103
len = getlength(var);
3104
varnames = (char **)emalloc(len * (sizeof (char *)), el_tempcluster);
3105
for(i=0; i<len; i++)
3107
pt = ((char **)var->addr)[i];
3108
varnames[i] = (char *)emalloc(strlen(pt)+1, el_tempcluster);
3109
strcpy(varnames[i], pt);
3112
nplist = (NODEPROTO **)emalloc(i * (sizeof (NODEPROTO *)), el_tempcluster);
3113
for(i=0, np = tech->firstnodeproto; np != NONODEPROTO; np = np->nextnodeproto, i++)
3115
for(i=0; i<len; i++)
3118
(void)addstringtoinfstr(nplist[i]->primname);
3119
if (*varnames[i] != 0)
3121
(void)addstringtoinfstr(" (");
3122
(void)addstringtoinfstr(varnames[i]);
3123
(void)addstringtoinfstr(")");
3125
DiaStuffLine(DVHO_PRIMLIST, returninfstr());
3127
DiaSelectLine(DVHO_PRIMLIST, 0);
3129
if (!vhdlondisk) DiaSetControl(DVHO_VHDLINFACET, 1);
3130
if (!netlistondisk) DiaSetControl(DVHO_NETINFACET, 1);
3132
/* loop until done */
3133
technameschanged = 0;
3136
itemHit = DiaNextHit();
3137
if (itemHit == OK || itemHit == CANCEL) break;
3138
if (itemHit == DVHO_VHDLINFACET || itemHit == DVHO_NETINFACET)
3140
DiaSetControl(itemHit, 1 - DiaGetControl(itemHit));
3143
if (itemHit == DVHO_PRIMLIST)
3145
DiaSetText(DVHO_UNNEGATEDNAME, "");
3146
DiaSetText(DVHO_NEGATEDNAME, "");
3147
i = DiaGetCurLine(DVHO_PRIMLIST);
3149
for(opt = pt; *opt != 0; opt++) if (*opt == '/') break;
3153
DiaSetText(DVHO_UNNEGATEDNAME, pt);
3154
DiaSetText(DVHO_NEGATEDNAME, &opt[1]);
3158
DiaSetText(DVHO_UNNEGATEDNAME, pt);
3159
DiaSetText(DVHO_NEGATEDNAME, pt);
3163
if (itemHit == DVHO_UNNEGATEDNAME || itemHit == DVHO_NEGATEDNAME)
3165
i = DiaGetCurLine(DVHO_PRIMLIST);
3167
(void)addstringtoinfstr(DiaGetText(DVHO_UNNEGATEDNAME));
3168
(void)addtoinfstr('/');
3169
(void)addstringtoinfstr(DiaGetText(DVHO_NEGATEDNAME));
3170
pt = returninfstr();
3171
if (strcmp(varnames[i], pt) == 0) continue;
3174
(void)reallocstring(&varnames[i], pt, el_tempcluster);
3177
(void)addstringtoinfstr(nplist[i]->primname);
3178
if (*varnames[i] != 0)
3180
(void)addstringtoinfstr(" (");
3181
(void)addstringtoinfstr(varnames[i]);
3182
(void)addstringtoinfstr(")");
3184
DiaSetScrollLine(DVHO_PRIMLIST, i, returninfstr());
3189
if (itemHit != CANCEL)
3191
if (DiaGetControl(DVHO_VHDLINFACET) != 0) ondisk = FALSE; else ondisk = TRUE;
3192
if (ondisk != vhdlondisk)
3193
setval((INTBIG)vhdl_tool, VTOOL, "VHDL_vhdl_on_disk", ondisk, VINTEGER);
3194
if (DiaGetControl(DVHO_NETINFACET) != 0) ondisk = FALSE; else ondisk = TRUE;
3195
if (ondisk != netlistondisk)
3196
setval((INTBIG)vhdl_tool, VTOOL, "VHDL_netlist_on_disk", ondisk, VINTEGER);
3197
if (technameschanged != 0)
3198
setval((INTBIG)tech, VTECHNOLOGY, "TECH_vhdl_names", (INTBIG)varnames,
3199
VSTRING|VISARRAY|(len<<VLENGTHSH));
3202
for(i=0; i<len; i++) efree(varnames[i]);
3203
efree((char *)varnames);
3204
efree((char *)nplist);
3207
#endif /* VHDLTOOL - at top */